diff --git a/src/main.c b/src/main.c index 88bf799..de9b709 100644 --- a/src/main.c +++ b/src/main.c @@ -15,8 +15,8 @@ #include "job.h" #include "term.h" #include "ui.h" -#include "vfs/vfs.h" #include "uns_wren_utils.h" +#include "vfs/vfs.h" static int tick_ctr = 0; static int shift_state = 0; diff --git a/src/syscalls.S b/src/syscalls.S index 49d74fb..8258761 100644 --- a/src/syscalls.S +++ b/src/syscalls.S @@ -7,6 +7,9 @@ .global __str_to_name .global __find_first .global __find_next +.global __open_file_os +.global __close_file_os +.global __readfile_os .section ".text" @@ -54,6 +57,15 @@ __find_first: __find_next: syscall(0x1db8) +__open_file_os: + syscall(0x1da3) + +__close_file_os: + syscall(0x1da4) + +__readfile_os: + syscall(0x1dac) + syscall_table: .long 0x80020070 diff --git a/src/vfs/vfs.c b/src/vfs/vfs.c index c5d1d3b..e499b99 100644 --- a/src/vfs/vfs.c +++ b/src/vfs/vfs.c @@ -17,6 +17,9 @@ extern void _name_to_str(char *dest, const uint16_t *source, int n); extern void _str_to_name(uint16_t *dest, const char *source, int n); extern int _find_first(const uint16_t *pathname, int *FindHandle, const uint16_t *foundfile, struct BFile_FileInfo *fileinfo); extern int _find_next(int FindHandle, const uint16_t *foundfile, struct BFile_FileInfo *fileinfo); +extern int _open_file_os(const unsigned short *filename, int mode, int zero); +extern int _close_file_os(int handle); +extern int _readfile_os(int handle, void *buf, int size, int pos); static vfs_entry_t *vfs_root; @@ -99,11 +102,19 @@ static void populate_vfs_fls(const char *path, vfs_entry_t *dir) { _name_to_str(foundfile_str, foundfile, 64); if (foundfile_str[0] != '@' && strcmp(foundfile_str, ".") != 0 && strcmp(foundfile_str, "..") != 0) { + vfs_entry_t *e; if (fileinfo.type == BFile_Type_Directory) { - vfs_new_dir(foundfile_str, dir); + e = vfs_new_dir(foundfile_str, dir); } else { - vfs_new_file(foundfile_str, dir); + e = vfs_new_file(foundfile_str, dir); } + + // embed full path str + char data_str[64]; + strcpy(data_str, path); + strcat(data_str, foundfile_str); + e->data = kmalloc(64, NULL); + _str_to_name((uint16_t *)e->data, data_str, 64); } ret = _find_next(shandle, foundfile, &fileinfo); @@ -134,14 +145,11 @@ void vfs_init(void) { vfs_root->childs = NULL; vfs_root->next = NULL; - - vfs_entry_t* sysfs = vfs_new_dir("sys", vfs_root); + vfs_entry_t *sysfs = vfs_new_dir("sys", vfs_root); sysfs->driver = vfs_drv_sysfs; - vfs_entry_t *media = vfs_new_dir("media", vfs_root); - vfs_entry_t *fls0 = vfs_new_dir("fls0", media); fls0->driver = vfs_drv_fls; cpu_atomic_start(); @@ -154,7 +162,7 @@ void vfs_init(void) { vfs_debug_tree(); } -static vfs_entry_t* vfs_find_child(vfs_entry_t* parent, const char* child_name) { +static vfs_entry_t *vfs_find_child(vfs_entry_t *parent, const char *child_name) { if (parent == NULL) return NULL; @@ -164,7 +172,7 @@ static vfs_entry_t* vfs_find_child(vfs_entry_t* parent, const char* child_name) if (child_name[0] == '\0') return parent; - vfs_entry_t* fe = parent->childs; + vfs_entry_t *fe = parent->childs; while (1) { if (fe == NULL) @@ -179,18 +187,18 @@ static vfs_entry_t* vfs_find_child(vfs_entry_t* parent, const char* child_name) return fe; } -static vfs_entry_t* vfs_find_entry(const char* path) { - vfs_entry_t* fe = vfs_root; +static vfs_entry_t *vfs_find_entry(const char *path) { + vfs_entry_t *fe = vfs_root; - char buf[128]; + char buf[64]; int i = 0; int j = 0; while (1) { buf[i++] = path[j++]; - if (buf[i-1] == '/' || buf[i-1] == '\0') { - buf[i-1] = '\0'; + if (buf[i - 1] == '/' || buf[i - 1] == '\0') { + buf[i - 1] = '\0'; fe = vfs_find_child(fe, buf); if (fe == NULL) @@ -199,29 +207,43 @@ static vfs_entry_t* vfs_find_entry(const char* path) { i = 0; } - if (buf[i-1] == '\0') + if (buf[i - 1] == '\0') break; } return fe; } -vfs_handle_t* vfs_open(const char* path) { - vfs_entry_t* f_entry = vfs_find_entry(path); +vfs_handle_t *vfs_open(const char *path) { + vfs_entry_t *f_entry = vfs_find_entry(path); if (f_entry == NULL) return NULL; - vfs_handle_t* f_handle = kmalloc(sizeof(vfs_handle_t), NULL); + vfs_handle_t *f_handle = kmalloc(sizeof(vfs_handle_t), NULL); f_handle->entry = f_entry; - f_handle->pos_r = 0; - f_handle->pos_w = 0; + f_handle->pos = 0; f_handle->mode = vfs_RW; - f_handle->size = -1; + f_handle->size = 0; return f_handle; } -void vfs_close(vfs_handle_t* f_handle) { - kfree(f_handle); +void vfs_close(vfs_handle_t *f_handle) { kfree(f_handle); } + +int vfs_read(vfs_handle_t *fh, int n, char buf[n]) { + switch (fh->entry->type) { + case vfs_drv_fls: + cpu_atomic_start(); + const int fd = _open_file_os((unsigned short *)fh->entry->data, 1, 0); // open in mode RO_SHARE + const int nb_read = _readfile_os(fd, buf, n, fh->pos); + _close_file_os(fd); + cpu_atomic_end(); + fh->pos += nb_read; + return nb_read; + + default: + term_kprint("I/O driver not implemented"); + return -1; + } } \ No newline at end of file diff --git a/src/vfs/vfs.h b/src/vfs/vfs.h index 0591861..0304231 100644 --- a/src/vfs/vfs.h +++ b/src/vfs/vfs.h @@ -26,6 +26,9 @@ typedef struct vfs_entry { // dir only struct vfs_entry *childs; struct vfs_entry *next; + + // driver-specific + void *data; } vfs_entry_t; typedef struct vfs_handle { @@ -35,8 +38,7 @@ typedef struct vfs_handle { vfs_RW = 3, } mode; - uint32_t pos_r; - uint32_t pos_w; + uint32_t pos; uint32_t size; vfs_entry_t *entry; @@ -45,6 +47,9 @@ typedef struct vfs_handle { void vfs_init(void); vfs_handle_t *vfs_open(const char *path); -void vfs_close(vfs_handle_t* f_handle); +void vfs_close(vfs_handle_t *f_handle); + +int vfs_read(vfs_handle_t *f, int n, char buf[n]); +int vfs_write(vfs_handle_t *f, int n, char buf[n]); #endif // #ifndef UNS_VFS_H \ No newline at end of file