diff --git a/include/kernel/fs/vfs.h b/include/kernel/fs/vfs.h index c3ceca2..a4ca5e4 100644 --- a/include/kernel/fs/vfs.h +++ b/include/kernel/fs/vfs.h @@ -9,7 +9,10 @@ #include // 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 diff --git a/include/kernel/process.h b/include/kernel/process.h index 9a160b9..262620f 100644 --- a/include/kernel/process.h +++ b/include/kernel/process.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -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]; diff --git a/include/lib/unistd.h b/include/lib/unistd.h index 7ed0851..ba72c8f 100644 --- a/include/lib/unistd.h +++ b/include/lib/unistd.h @@ -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); diff --git a/src/kernel/bootstrap/start.c b/src/kernel/bootstrap/start.c index dbd5a17..64918d4 100644 --- a/src/kernel/bootstrap/start.c +++ b/src/kernel/bootstrap/start.c @@ -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. diff --git a/src/kernel/fs/vfs/dentry/alloc.c b/src/kernel/fs/vfs/dentry/alloc.c index f4f50e2..1b08754 100644 --- a/src/kernel/fs/vfs/dentry/alloc.c +++ b/src/kernel/fs/vfs/dentry/alloc.c @@ -2,6 +2,7 @@ #include #include +/* 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; diff --git a/src/kernel/fs/vfs/dentry/find_first_child.c b/src/kernel/fs/vfs/dentry/find_first_child.c index 3ec8eaa..463a386 100644 --- a/src/kernel/fs/vfs/dentry/find_first_child.c +++ b/src/kernel/fs/vfs/dentry/find_first_child.c @@ -3,6 +3,15 @@ #include #include +// +// 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; diff --git a/src/kernel/fs/vfs/dentry/find_next_sibling.c b/src/kernel/fs/vfs/dentry/find_next_sibling.c index b12fb81..882b0b1 100644 --- a/src/kernel/fs/vfs/dentry/find_next_sibling.c +++ b/src/kernel/fs/vfs/dentry/find_next_sibling.c @@ -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); diff --git a/src/kernel/fs/vfs/dentry/free.c b/src/kernel/fs/vfs/dentry/free.c index c61d5f2..0132541 100644 --- a/src/kernel/fs/vfs/dentry/free.c +++ b/src/kernel/fs/vfs/dentry/free.c @@ -1,6 +1,8 @@ #include #include +/* 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 diff --git a/src/kernel/fs/vfs/dentry/resolve.c b/src/kernel/fs/vfs/dentry/resolve.c index 6a51923..3a87371 100644 --- a/src/kernel/fs/vfs/dentry/resolve.c +++ b/src/kernel/fs/vfs/dentry/resolve.c @@ -1,20 +1,43 @@ #include #include +#include #include -//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); } diff --git a/src/kernel/fs/vfs/file/lseek.c b/src/kernel/fs/vfs/file/lseek.c index cf241d6..e05818c 100644 --- a/src/kernel/fs/vfs/file/lseek.c +++ b/src/kernel/fs/vfs/file/lseek.c @@ -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); } diff --git a/src/kernel/fs/vfs/file/open.c b/src/kernel/fs/vfs/file/open.c index 88dea46..eed76d4 100644 --- a/src/kernel/fs/vfs/file/open.c +++ b/src/kernel/fs/vfs/file/open.c @@ -2,9 +2,7 @@ #include #include -// 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); diff --git a/src/kernel/fs/vfs/file/read.c b/src/kernel/fs/vfs/file/read.c index 93e1e70..f1e6fce 100644 --- a/src/kernel/fs/vfs/file/read.c +++ b/src/kernel/fs/vfs/file/read.c @@ -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. diff --git a/src/kernel/fs/vfs/file/write.c b/src/kernel/fs/vfs/file/write.c index 9d49069..9714fb9 100644 --- a/src/kernel/fs/vfs/file/write.c +++ b/src/kernel/fs/vfs/file/write.c @@ -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. diff --git a/src/kernel/fs/vfs/inode/mkdir.c b/src/kernel/fs/vfs/inode/mkdir.c index b9c294e..956555e 100644 --- a/src/kernel/fs/vfs/inode/mkdir.c +++ b/src/kernel/fs/vfs/inode/mkdir.c @@ -3,9 +3,7 @@ #include #include -// 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); } diff --git a/src/kernel/fs/vfs/inode/mknod.c b/src/kernel/fs/vfs/inode/mknod.c index 9e08b25..f3c13bf 100644 --- a/src/kernel/fs/vfs/inode/mknod.c +++ b/src/kernel/fs/vfs/inode/mknod.c @@ -2,6 +2,7 @@ #include #include +/* 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); diff --git a/src/kernel/fs/vfs/superblock/mount.c b/src/kernel/fs/vfs/superblock/mount.c index 2a70992..a51ec1a 100644 --- a/src/kernel/fs/vfs/superblock/mount.c +++ b/src/kernel/fs/vfs/superblock/mount.c @@ -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); diff --git a/src/kernel/hardware/vbr/exception_pre.s b/src/kernel/hardware/vbr/exception_pre.s index 2a819a6..6e5ec5c 100644 --- a/src/kernel/hardware/vbr/exception_pre.s +++ b/src/kernel/hardware/vbr/exception_pre.s @@ -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 diff --git a/src/kernel/process/create.c b/src/kernel/process/create.c index cd33b9b..e318333 100644 --- a/src/kernel/process/create.c +++ b/src/kernel/process/create.c @@ -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; diff --git a/src/kernel/syscall/handler.c b/src/kernel/syscall/handler.c index 745d759..c14ce50 100644 --- a/src/kernel/syscall/handler.c +++ b/src/kernel/syscall/handler.c @@ -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]); } diff --git a/src/kernel/test.c b/src/kernel/test.c new file mode 100644 index 0000000..6f529ec --- /dev/null +++ b/src/kernel/test.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include + +// 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); +} diff --git a/src/kernel/vhex.ld b/src/kernel/vhex.ld index 4da4763..086afc9 100644 --- a/src/kernel/vhex.ld +++ b/src/kernel/vhex.ld @@ -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)