Fix VFS crash

This commit is contained in:
Yann MAGNIN 2020-01-10 17:21:44 +01:00
parent 6eea55d645
commit c941207cc6
21 changed files with 316 additions and 147 deletions

View File

@ -9,7 +9,10 @@
#include <kernel/devices/device.h>
// Internal VFS macros
#define VFS_MOUNT_ROOT (-1)
#define VFS_MOUNT_ROOT (-1)
#define VFS_DENTRY_RESOLVE_FLAG_FULL_PATH (0)
#define VFS_DENTRY_RESOLVE_FLAG_PATHNAME (1)
// Constructor / destructor

View File

@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
#include <kernel/fs/file.h>
#include <kernel/fs/filesystem.h>
#include <kernel/context.h>
#include <kernel/types.h>
@ -39,6 +40,7 @@ typedef struct process_s
} status;
FILE file;
} opfile[PROCESS_NB_OPEN_FILE];
struct dentry *working_dir;
// Signals management.
//sighandler_t signal[NSIG];

View File

@ -17,7 +17,7 @@ extern pid_t waitpid(pid_t pid, int *wstatus, int options);
// File syscall
#define O_DIRECT 0
extern int open(const char *pathname, int flags); // <-- TODO: va_arg
extern int open(const char *pathname, int flags, ...);
extern ssize_t write(int fd, const void *buf, size_t count);
extern ssize_t read(int fd, void *buf, size_t count);
extern int close(int fd);

View File

@ -85,22 +85,6 @@ static void section_execute(void *bsection, void *esection)
}
}
void vfs_test(struct dentry *node, int level)
{
if (node == NULL)
return;
// space !
for (int i = 0 ; i < level ; i++)
tty_write(NULL, " ", 1);
// Name
tty_write(NULL, node->name, strlen(node->name));
tty_write(NULL, "\n", 1);
vfs_test(vfs_dentry_find_first_child(node), level + 1);
vfs_test(vfs_dentry_find_next_sibling(node), level);
}
/* start() - Kernel entry point */
__attribute__((section(".pretext")))
@ -158,6 +142,7 @@ int start(void)
// Creat initial file tree
vfs_mount(NULL, NULL, "gladfs", VFS_MOUNT_ROOT, NULL);
vfs_mkdir("/dev", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
vfs_mkdir("/home", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
vfs_mkdir("/mnt", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
vfs_mkdir("/mnt/smemfs", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
vfs_mount(NULL, "/mnt/smemfs", "smemfs", /*MS_RDONLY*/0, NULL);
@ -166,12 +151,8 @@ int start(void)
vfs_mknod("/dev/tty", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH,
dev_make_major(TTY_DEV_MAJOR));
// VFS test
tty_open(0, 0);
extern struct dentry *vfs_root_node;
vfs_test(vfs_root_node, 0);
tty_write(NULL, "FINIT !\n", 8);
DBG_WAIT;
extern void kernel_test(void);
kernel_test();
// Create first process: Vhex.
pid_t vhex_pid = process_create("Vhex");
@ -181,7 +162,9 @@ int start(void)
vhex_process->context.ssr = atomic_start();
// Load programe.
vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process);
extern void kernel_test(void);
vhex_process->context.spc = (uint32_t)&kernel_test;
//vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process);
if (vhex_process->context.spc == 0x00000000)
{
// Display message.

View File

@ -2,6 +2,7 @@
#include <kernel/memory.h>
#include <kernel/util.h>
/* vfs_dentry_alloc() - Allocate new "empty" dentry */
struct dentry *vfs_dentry_alloc(const char *name, mode_t mode)
{
struct dentry *node;
@ -13,9 +14,16 @@ struct dentry *vfs_dentry_alloc(const char *name, mode_t mode)
// Initialize dentry
memset(node->name, 0x00, VFS_DENTRY_NAME_LENGHT);
strncpy(node->name, name, VFS_DENTRY_NAME_LENGHT);
node->inode = NULL;
// Set the name if possible
if (name != NULL)
strncpy(node->name, name, VFS_DENTRY_NAME_LENGHT);
// Set the mode
node->mode = mode;
// Set default value
node->inode = NULL;
node->parent = NULL;
node->child = NULL;
node->next = NULL;

View File

@ -3,6 +3,15 @@
#include <kernel/util.h>
#include <kernel/fs/stat.h>
//
// vfs_dentry_find_first_child()
// Find the fist file of a file
// @note:
// To avoid useless memory used, the VFS cache
// is generated only if the user want to access to a file
// unregister to the cahe.
// TODO: explain correctly x)
//
struct dentry *vfs_dentry_find_first_child(struct dentry *dentry)
{
// Check file type
@ -43,7 +52,7 @@ struct dentry *vfs_dentry_find_first_child(struct dentry *dentry)
}
// Try to create new dentry
struct dentry *new_dentry = pm_alloc(sizeof(struct dentry));
struct dentry *new_dentry = vfs_dentry_alloc(NULL, 0);
if (new_dentry == NULL)
return (NULL);
@ -64,11 +73,7 @@ struct dentry *vfs_dentry_find_first_child(struct dentry *dentry)
// Common init
new_dentry->inode = inode;
new_dentry->parent = dentry;
new_dentry->child = NULL;
new_dentry->next = dentry->child;
new_dentry->mnt.inode = NULL;
new_dentry->mnt.file_op = NULL;
new_dentry->mnt.inode_op = NULL;
// Update VFS cache en return
dentry->child = new_dentry;

View File

@ -25,7 +25,7 @@ struct dentry *vfs_dentry_find_next_sibling(struct dentry *dentry)
return (NULL);
// Try to create new dentry
struct dentry *new_dentry = pm_alloc(sizeof(struct dentry));
struct dentry *new_dentry = vfs_dentry_alloc(NULL, 0);
if (new_dentry == NULL)
return (NULL);
@ -34,15 +34,11 @@ struct dentry *vfs_dentry_find_next_sibling(struct dentry *dentry)
new_dentry->mode = dentry->dentry_op.inode_op->get_mode(inode);
new_dentry->inode = inode;
new_dentry->parent = dentry;
new_dentry->child = NULL;
new_dentry->next = dentry->next;
new_dentry->dentry_op.file_op = dentry->dentry_op.file_op;
new_dentry->dentry_op.inode_op = dentry->dentry_op.inode_op;
new_dentry->mnt.inode = NULL;
new_dentry->mnt.file_op = NULL;
new_dentry->mnt.inode_op = NULL;
// Update VFS cache en return
new_dentry->next = dentry->next;
dentry->next = new_dentry;
return (new_dentry);

View File

@ -1,6 +1,8 @@
#include <kernel/fs/vfs.h>
#include <kernel/memory.h>
/* vfs_dentry_free() - Free'd allocated dentry */
/* @note: *WARNING* no verification will be done, so do not use this primitive */
void vfs_dentry_free(struct dentry *dentry)
{
// Check error

View File

@ -1,20 +1,43 @@
#include <kernel/fs/vfs.h>
#include <kernel/fs/stat.h>
#include <kernel/process.h>
#include <kernel/util.h>
//TODO add '.' handling.
static int get_name(int *name_lenght, const char *path, char *name)
{
// Get file name
*name_lenght = 0;
while (*name_lenght < 24 &&
path[*name_lenght] != '/' &&
path[*name_lenght] != '\0')
{
name[*name_lenght] = path[*name_lenght];
*name_lenght = *name_lenght + 1;
}
// Check error
if (path[*name_lenght] != '/' && path[*name_lenght] != '\0')
return (-1);
// Add null char
name[*name_lenght] = '\0';
return (0);
}
//TODO add '..' handling.
//TODO add '//' handling
struct dentry *vfs_dentry_resolve(const char *path, int mode)
{
extern struct process_s *process_current;
extern struct dentry *vfs_root_node;
struct dentry *curr_dentry;
struct dentry *old_dentry;
struct dentry *file;
struct dentry *next;
struct dentry *tmp;
int name_lenght;
char name[24];
// Check VFS validity
if (vfs_root_node == NULL){
if (vfs_root_node == NULL)
{
kvram_clear();
printk(0, 0, "VFS root error !");
kvram_display();
@ -23,61 +46,109 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode)
}
// Get start inode
if (path[0] != '/'){
// TODO get current process working directory
return (NULL);
if (path[0] != '/')
{
// Check if current process validity
if (process_current == NULL)
return (NULL);
// Get current working directory
file = process_current->working_dir;
next = process_current->working_dir->child;
} else {
curr_dentry = vfs_root_node->child;
old_dentry = vfs_root_node;
path = path + 1;
// Get root inode
file = vfs_root_node;
next = vfs_root_node->child;
// Update path (skip '/')
path = &path[1];
}
// VFS walk entry !
while (path[0] != '\0')
{
// Get file name
name_lenght = 0;
while (name_lenght < 24 &&
path[name_lenght] != '/' &&
path[name_lenght] != '\0')
{
name[name_lenght] = path[name_lenght];
name_lenght = name_lenght + 1;
}
// Check error
if (path[name_lenght] != '/' && path[name_lenght] != '\0')
// Get next file name
if (get_name(&name_lenght, path, name) != 0)
return (NULL);
// Add null char
name[name_lenght] = '\0';
// Check '..' file (parent directory)
if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
{
if (file->parent != NULL)
{
next = file->parent->child;
file = file->parent->child;
}
path = &path[3];
continue;
}
// Check parthname or path
if (mode == 1 && path[name_lenght] == '\0')
return (old_dentry);
// Check '.' or '//' file (current directory)
if (name[0] == '\0' || (name[0] == '.' && name[1] == '\0'))
{
path = (path[name_lenght] == '/') ? &path[name_lenght + 1] : &path[name_lenght];
continue;
}
// Check potential error
if (curr_dentry == NULL)
// Check parthname or path mode
if (path[name_lenght] == '\0' &&
mode == VFS_DENTRY_RESOLVE_FLAG_PATHNAME)
break;
// Check next file entry
if (next == NULL)
return (NULL);
// Try to find file in the current VFS level.
while (strncmp(curr_dentry->name, name, name_lenght) != 0)
while (strncmp(next->name, name, name_lenght) != 0)
{
curr_dentry = vfs_dentry_find_next_sibling(curr_dentry);
if (curr_dentry == NULL)
tmp = next;
next = vfs_dentry_find_next_sibling(next);
if (next == NULL)
{
// Debug !
kvram_clear();
printk(0, 0, "vfs_resolve(): sibling error !");
printk(0, 1, "old next: %s$", tmp->name);
printk(0, 2, "file: %s$", file->name);
printk(0, 3, "name: %s$", name);
kvram_display();
DBG_WAIT;
while (1);
return (NULL);
}
}
// Update current file
file = next;
// Directory check
if (path[name_lenght] == '/')
{
// Check type
if ((curr_dentry->mode & __S_IFDIR) == 0)
if ((file->mode & __S_IFDIR) == 0)
{
// Debug !
kvram_clear();
printk(0, 0, "vfs_resolve(): dir error !");
kvram_display();
DBG_WAIT;
return (NULL);
}
// Try to find first child
old_dentry = curr_dentry;
curr_dentry = vfs_dentry_find_first_child(curr_dentry);
next = vfs_dentry_find_first_child(next);
if (next != NULL)
{
// Debug !
kvram_clear();
printk(0, 0, "vfs_resolve(): child info !");
printk(0, 1, "file name: %s$", file->name);
printk(0, 2, "next name: %s$", next->name);
printk(0, 3, "name: %s$", name);
kvram_display();
DBG_WAIT;
}
// Update name lenght to skip '/' char
name_lenght = name_lenght + 1;
@ -86,5 +157,5 @@ struct dentry *vfs_dentry_resolve(const char *path, int mode)
// Update path
path = &path[name_lenght];
}
return (curr_dentry);
return (file);
}

View File

@ -21,8 +21,9 @@ off_t vfs_lseek(FILE *file, off_t offset, int whence)
if (whence == SEEK_END)
{
//TODO: get file size !!
//TODO: use copy-on-write system !!
//file->cursor = file->size + offset - 1;
return (file->cursor);
return (-1);
}
return (-1);
}

View File

@ -2,9 +2,7 @@
#include <kernel/fs/stat.h>
#include <kernel/util.h>
// Intrenal functions
extern struct dentry *vfs_dentry_resolve(const char *path, int mode);
/* vfs_open() - Open file named pathname */
int vfs_open(FILE *file, char const *pathname, int flags)
{
struct dentry *dentry;
@ -14,7 +12,8 @@ int vfs_open(FILE *file, char const *pathname, int flags)
if (dentry == NULL)
{
kvram_clear();
printk(0, 0, "VFS_open(): path error '%s'", pathname);
printk(0, 0, "VFS_open() error !");
printk(0, 1, "path error '%s'", pathname);
kvram_display();
DBG_WAIT;
return (-1);
@ -30,6 +29,18 @@ int vfs_open(FILE *file, char const *pathname, int flags)
return (-2);
}
// debug
kvram_clear();
printk(0, 0, "vfs_open(): inode found !");
printk(0, 1, "path: %s", pathname);
printk(0, 2, "name: %s", dentry->name);
printk(0, 3, "inode: %p", dentry->inode);
printk(0, 4, "file_op: %p", dentry->dentry_op.file_op);
kvram_display();
DBG_WAIT;
//TODO: update interne dentry counter !!
// Initialize new file.
file->private = dentry->inode;
file->permission = dentry->mode & (~__S_IFMT);

View File

@ -10,7 +10,9 @@ ssize_t vfs_read(FILE *file, void *buf, size_t count)
return (-1);
// Get / check file's informations
if (file->private == NULL || file->file_op->read == NULL)
if (file->private == NULL ||
file->file_op == NULL ||
file->file_op->read == NULL)
return (-1);
// Read with FS specifique primitive and return the numbe of reading bytes.

View File

@ -10,7 +10,9 @@ ssize_t vfs_write(FILE *file, const void *buf, size_t count)
return (-1);
// Get / check file's informations
if (file->private == NULL || file->file_op->write == NULL)
if (file->private == NULL ||
file->file_op == NULL ||
file->file_op->write == NULL)
return (-1);
// Writa with FS specifique primitive and return the numbe of reading bytes.

View File

@ -3,9 +3,7 @@
#include <kernel/fs/stat.h>
#include <kernel/util.h>
// Internal functions
struct dentry *vfs_dentry_resolve(const char *path, int mode);
/* vfs_mkdir() - Attempts to create a directory named pathname */
int vfs_mkdir(const char *pathname, mode_t mode)
{
extern struct dentry *vfs_root_node;
@ -18,14 +16,14 @@ int vfs_mkdir(const char *pathname, mode_t mode)
name = (name == NULL) ? (void *)pathname : &name[1];
// Get parent dentry
parent_dentry = vfs_dentry_resolve(pathname, 1);
parent_dentry = vfs_dentry_resolve(pathname, VFS_DENTRY_RESOLVE_FLAG_PATHNAME);
// Check parent dentry and FS primitives
if (parent_dentry == NULL || parent_dentry->dentry_op.inode_op->mkdir == NULL)
return (-1);
// Try to create new dentry
folder = pm_alloc(sizeof(struct dentry));
folder = vfs_dentry_alloc(name, mode | __S_IFDIR);
if (folder == NULL)
return (-2);
@ -33,24 +31,17 @@ int vfs_mkdir(const char *pathname, mode_t mode)
folder->inode = parent_dentry->dentry_op.inode_op->mkdir(parent_dentry->inode, name, mode);
if (folder->inode == NULL)
{
pm_free(folder);
vfs_dentry_free(folder);
return (-3);
}
// Initialize new dentry
memset(folder->name, 0x00, VFS_DENTRY_NAME_LENGHT);
strncpy(folder->name, name, VFS_DENTRY_NAME_LENGHT);
folder->mode = mode | __S_IFDIR;
folder->parent = parent_dentry;
folder->next = parent_dentry->child;
folder->child = NULL;
// Set FS primitives operations
folder->dentry_op.file_op = parent_dentry->dentry_op.file_op;
folder->dentry_op.inode_op = parent_dentry->dentry_op.inode_op;
folder->mnt.inode = NULL;
folder->mnt.inode_op = NULL;
folder->mnt.file_op = NULL;
// Release dentry
folder->parent = parent_dentry;
folder->next = parent_dentry->child;
parent_dentry->child = folder;
return (0);
}

View File

@ -2,6 +2,7 @@
#include <kernel/fs/stat.h>
#include <kernel/util.h>
/* gevice_get() - Find internal device */
struct device *device_get(dev_t major)
{
extern uint32_t bdevice_section;
@ -19,6 +20,7 @@ struct device *device_get(dev_t major)
return (NULL);
}
/* vfs_mknod - Create VFS inode (file, device special file, or pipe) named pathname */
int vfs_mknod(const char *pathname, mode_t mode, dev_t dev)
{
extern struct dentry *vfs_root_node;
@ -27,60 +29,54 @@ int vfs_mknod(const char *pathname, mode_t mode, dev_t dev)
struct dentry *file;
char *name;
// Check device
// TODO: remove me !
if (dev == 0)
return (-2);
// Get parent dentry
parent_dentry = vfs_dentry_resolve(pathname, 1);
parent_dentry = vfs_dentry_resolve(pathname, VFS_DENTRY_RESOLVE_FLAG_PATHNAME);
if (parent_dentry == NULL)
{
kvram_clear();
printk(0, 0, "mknod: parent dentry error !");
kvram_display();
DBG_WAIT;
return (-1);
}
// Get folder name
name = strrchr(pathname, '/');
name = (name == NULL) ? (void *)pathname : &name[1];
// Try to find open device
// Try to find the device
// TODO: handle othe file (mode) !!!
device = device_get(dev_get_major(dev));
if (device == NULL)
{
kvram_clear();
printk(0, 0, "mknod: device error !");
kvram_display();
DBG_WAIT;
return (-2);
}
// Tru to create empty node
file = vfs_dentry_alloc(name, mode | __S_IFCHR);
if (file == NULL)
{
kvram_clear();
printk(0, 0, "mknod: dentry alloc error !");
kvram_display();
DBG_WAIT;
return (-3);
}
// Try to open device
file->inode = device->open(dev_get_major(dev), dev_get_minor(dev));
if (file->inode == NULL)
{
kvram_clear();
printk(0, 0, "mknod: device inode error !");
kvram_display();
DBG_WAIT;
vfs_dentry_free(file);
return (-4);
}
// Debug !
kvram_clear();
printk(0, 0, "New mknod device !");
printk(0, 1, "dentry: %p$", file);
printk(0, 2, "inode: %p$", file->inode);
printk(0, 3, "name: %s$", file->name);
printk(0, 4, "dev->file_op: %p$", &device->file_op);
kvram_display();
DBG_WAIT;
DBG_WAIT;
// Set file operations
file->dentry_op.file_op = &device->file_op;
// Add file into VFS
file->parent = parent_dentry;
file->next = parent_dentry->child;
parent_dentry->child = file;
return (0);

View File

@ -42,8 +42,12 @@ int vfs_mount(const char *source, const char *target,
// Check ROOT mount.
if (target == NULL && mountflags == (unsigned long)VFS_MOUNT_ROOT)
{
// Check VFS root
if (vfs_root_node != NULL)
return (-4);
// Alloc root mnt
vfs_root_node = pm_alloc(sizeof(struct dentry));
vfs_root_node = vfs_dentry_alloc("/", __S_IFDIR);
if (vfs_root_node == NULL)
return (-1);
@ -58,22 +62,23 @@ int vfs_mount(const char *source, const char *target,
while (1) { __asm__ volatile ("sleep"); }
}
// Initialize entry
vfs_root_node->name[0] = '/';
vfs_root_node->name[1] = '\0';
vfs_root_node->parent = NULL;
vfs_root_node->child = NULL;
vfs_root_node->next = NULL;
// Get File System primitives
vfs_root_node->dentry_op.file_op = &filesystem->file_operations;
vfs_root_node->dentry_op.inode_op = &filesystem->inode_operations;
vfs_root_node->mnt.inode = NULL;
vfs_root_node->mnt.file_op = NULL;
vfs_root_node->mnt.inode_op = NULL;
// Debug !
kvram_clear();
printk(0, 0, "vfs_root_node = %p", vfs_root_node);
printk(0, 1, "vfs_root_node = %s$", vfs_root_node->name);
printk(0, 2, "vfs_root_node = %p", vfs_root_node->child);
printk(0, 3, "vfs_root_node = %p", vfs_root_node->next);
kvram_display();
DBG_WAIT;
return (0);
}
// Get target inode informations
struct dentry *mnt = vfs_dentry_resolve(target, 0);
struct dentry *mnt = vfs_dentry_resolve(target, VFS_DENTRY_RESOLVE_FLAG_FULL_PATH);
if (mnt == NULL)
return (-1);

View File

@ -9,7 +9,7 @@
.align 2
_exception_handler_pre:
! Due to TRAPA syscall API we should
! Due to TRAPA syscall ABI we should
! switch stack to avoid variodic argument
! corruption.
mov.l .process_current, r2 ! get current_process address

View File

@ -5,6 +5,7 @@
pid_t process_create(const char *name)
{
extern struct dentry *vfs_root_node;
extern process_t *process_current;
process_t *process;
pid_t process_pid;
@ -69,6 +70,17 @@ pid_t process_create(const char *name)
process->context.ssr = 0x00000000;
process->context.spc = 0x00000000;
// Initialise file cache
for (int i = 0 ; i < PROCESS_NB_OPEN_FILE ; i = i + 1)
{
process->opfile[i].status = PROCESS_FILE_SLOT_UNUSED;
process->opfile[i].file.private = NULL;
process->opfile[i].file.file_op = NULL;
process->opfile[i].file.cursor = 0;
process->opfile[i].file.permission = 0;
}
process->working_dir = vfs_root_node;
// Initialize processes.
process->parent = process_current;
process->child = NULL;

View File

@ -44,12 +44,15 @@ void *sys_get_handler(int sysno)
return (0);
// DEBUG
/* kvram_clear();
printk(0, 0, "sysno = %d", sysno);
printk(0, 0, "handler = %p", sys_handler[sysno]);
kvram_clear();
printk(0, 0, "TRAPA ABI pre_handler !");
printk(0, 1, "sysno = %d", sysno);
printk(0, 2, "handler = %p", sys_handler[sysno]);
kvram_display();
DBG_WAIT;
*/
DBG_WAIT;
DBG_WAIT;
// Return syscall
return ((void *)sys_handler[sysno]);
}

75
src/kernel/test.c Normal file
View File

@ -0,0 +1,75 @@
#include <kernel/fs/vfs.h>
#include <kernel/devices/tty.h>
#include <kernel/memory.h>
#include <kernel/util.h>
// Tree-wrapper
static void vfs_test(struct dentry *node, int level)
{
int curr_line;
// Check error.
if (node == NULL)
return;
// Space management.
for (int i = 0 ; i < level ; i++)
tty_write(NULL, " ", 1);
// Display name
tty_write(NULL, node->name, strlen(node->name));
tty_write(NULL, "\n", 1);
// Walk into child and sibling
vfs_test(vfs_dentry_find_first_child(node), level + 1);
vfs_test(vfs_dentry_find_next_sibling(node), level);
}
void kernel_test(void)
{
extern struct dentry *vfs_root_node;
char path[] = "/../dev/./../dev/////tty";
void *test;
FILE file;
// Debug !
kvram_clear();
printk(0, 0, "Kernel test mode entry !");
printk(0, 1, "Check VFS...");
kvram_display();
DBG_WAIT;
// Check root node
printk(0, 2, "vfs_root_node = %p", vfs_root_node);
printk(0, 3, "vfs_root_node = %s$", vfs_root_node->name);
printk(0, 4, "vfs_root_node = %p", vfs_root_node->child);
printk(0, 5, "vfs_root_node = %p", vfs_root_node->next);
kvram_display();
DBG_WAIT;
// VFS test
tty_open(0, 0);
vfs_test(vfs_root_node, 0);
tty_write(NULL, "FINI !\n", 7);
DBG_WAIT;
DBG_WAIT;
// Try to open file using VFS
if (vfs_open(&file, path, 0))
{
kvram_clear();
printk(0, 0, "vfs_open(): error !");
printk(0, 1, "path %s$", path);
kvram_display();
while (1) { __asm__ volatile ("sleep"); }
}
// Display file informations
kvram_clear();
printk(0, 0, "vfs_open: success !");
printk(0, 1, "path: %s$", path);
printk(0, 2, "file->private: %p", file.private);
printk(0, 3, "file->file_op: %p", file.file_op);
kvram_display();
while (1);
}

View File

@ -30,13 +30,14 @@ SECTIONS
/*
** ROM sections
*/
_brom = 0x00300000;
_srom = 0x200 + SIZEOF(.text) +
SIZEOF(.data) +
SIZEOF(.vhex) +
SIZEOF(.ubc);
. = ORIGIN(rom);
_brom = ABSOLUTE (0x00300000) ;
_srom = ABSOLUTE (0x200 +
SIZEOF(.text) +
SIZEOF(.data) +
SIZEOF(.vhex) +
SIZEOF(.ubc)) ;
.text : {
/* Source Code */
*(.pretext)