From 4460d92843a70fa08cc8d05d1ff583419525d788 Mon Sep 17 00:00:00 2001 From: Marian Ohligs Date: Thu, 12 May 2011 11:29:31 +0200 Subject: [PATCH 1/2] add syscall lseek (not working yet) some design changes in kernel/systcall.c --- kernel/syscall.c | 55 +++++++++++++++++----------- newlib/src/libgloss/metalsvm/lseek.c | 13 ++++++- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/kernel/syscall.c b/kernel/syscall.c index d849354f..8c0af17e 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -25,19 +25,6 @@ #include #include -static int sys_read(int fd, const char *buf, size_t len) -{ - unsigned int readbytes; - readbytes = read_fs( - per_core(current_task)->fildes_table[fd].node, - (uint8_t*)buf, len, - per_core(current_task)->fildes_table[fd].offset); - per_core(current_task)->fildes_table[fd].offset += readbytes; - //kprintf("fd:%i, Dateilaenge:%i, Dateiinhalt: %s \n", fd, len, buf); - /* Beware: still reading above file limit! */ - return readbytes; -} - static int sys_write(int fd, const char *buf, size_t len) { unsigned int wrotebytes; @@ -70,7 +57,25 @@ static int sys_close(int fd) per_core(current_task)->fildes_table[fd].offset = 0; return 0; - } +} + +static int sys_read(int fd, const char *buf, size_t len) +{ + unsigned int readbytes; + readbytes = read_fs( + per_core(current_task)->fildes_table[fd].node, + (uint8_t*)buf, len, + per_core(current_task)->fildes_table[fd].offset); + per_core(current_task)->fildes_table[fd].offset += readbytes; + //kprintf("fd:%i, Dateilaenge:%i, Dateiinhalt: %s X: %i\n", fd, len, buf, readbytes); + /* Beware: still reading above file limit! */ + return readbytes; +} + +static int sys_lseek(int fd, off_t pos, int origin) +{ + return 2; +} static int sys_sbrk(int incr) { @@ -113,13 +118,6 @@ int syscall_handler(uint32_t sys_nr, ...) sys_exit(va_arg(vl, uint32_t)); ret = 0; break; - case __NR_read: { - int fd = va_arg(vl, int); - const char* buf = va_arg(vl, const char*); - size_t len = va_arg(vl, size_t); - ret = sys_read(fd, buf, len); - break; - } case __NR_write: { int fd = va_arg(vl, int); const char* buf = va_arg(vl, const char*); @@ -139,6 +137,21 @@ int syscall_handler(uint32_t sys_nr, ...) ret = sys_close(fd); break; } + case __NR_read: { + int fd = va_arg(vl, int); + const char* buf = va_arg(vl, const char*); + size_t len = va_arg(vl, size_t); + ret = sys_read(fd, buf, len); + break; + } + case __NR_lseek: { + int fd = va_arg(vl, int); + off_t pos = va_arg(vl, off_t); + int origin = va_arg(vl, int); + ret = sys_lseek(fd, pos, origin); + kprintf("hallo!!! %i", ret); + break; + } case __NR_sbrk: { int incr = va_arg(vl, int); diff --git a/newlib/src/libgloss/metalsvm/lseek.c b/newlib/src/libgloss/metalsvm/lseek.c index 82328753..2c2ff4ec 100644 --- a/newlib/src/libgloss/metalsvm/lseek.c +++ b/newlib/src/libgloss/metalsvm/lseek.c @@ -24,12 +24,21 @@ #undef errno extern int errno; #include "warning.h" +#include "syscall.h" int -_DEFUN (lseek, (file, ptr, dir), +_DEFUN (_lseek, (file, ptr, dir), int file _AND int ptr _AND int dir) { - return 0; + int ret; + + ret = SYSCALL3(__NR_lseek, file, ptr, dir); + if (ret < 0) { + errno = -ret; + ret = -1; + } + + return ret; } From b94875ccfe7dd773a2b77e07c4db54ca4f4002b3 Mon Sep 17 00:00:00 2001 From: Marian Ohligs Date: Mon, 16 May 2011 10:19:13 +0200 Subject: [PATCH 2/2] initrd_write: - writing strings of any length now possible --- drivers/stdin/stdin.c | 2 +- fs/initrd.c | 83 +++++++++++----------------------- include/metalsvm/fs.h | 7 +++ include/metalsvm/fs_types.h | 4 +- include/metalsvm/tasks_types.h | 2 +- kernel/syscall.c | 11 +++-- newlib/examples/hello.c | 14 +++--- newlib/examples/test | 2 +- 8 files changed, 52 insertions(+), 73 deletions(-) diff --git a/drivers/stdin/stdin.c b/drivers/stdin/stdin.c index 7904f62a..07f7a4df 100644 --- a/drivers/stdin/stdin.c +++ b/drivers/stdin/stdin.c @@ -29,7 +29,7 @@ static ssize_t stdin_read(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) { while(size) { - size = kputs((char*)buffer); + size -= kputs((char*)buffer); } return size; } diff --git a/fs/initrd.c b/fs/initrd.c index ee97aa97..ad1aef3e 100644 --- a/fs/initrd.c +++ b/fs/initrd.c @@ -65,7 +65,6 @@ static ssize_t initrd_read(vfs_node_t* node, uint8_t* buffer, size_t size, off_t pos = offset / node->block_size; offset = offset % node->block_size; } - do { for(i=0; idata[i]) { @@ -98,85 +97,55 @@ static ssize_t initrd_read(vfs_node_t* node, uint8_t* buffer, size_t size, off_t static ssize_t initrd_write(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) { - uint32_t i, writtenbytes = 0, writebytes = 0; - char* data = NULL; - block_list_t* blist = &node->block_list; - - do { - data = (char*) blist->data[0]; - if ((size - writtenbytes) >= MAX_DATABLOCKS) - writebytes = MAX_DATABLOCKS; - else - writebytes = size - writtenbytes; - - memcpy(data, buffer, writebytes); - writtenbytes += writebytes; - //kprintf("geschrieben: %i", writtenbytes); - - if (!blist->next) { - blist->next = (block_list_t*) kmalloc(sizeof(block_list_t)); - if (blist->next) { - memset(blist->next, 0x00, sizeof(block_list_t)); - } - } - - blist = blist->next; - } while(size > writtenbytes); - - return writtenbytes; - -/* uint32_t i, pos = 0, found = 0; + off_t nodeoffset = offset; char* data = NULL; block_list_t* blist = &node->block_list; - kprintf("tatsachen offset %i\n", offset); + if (BUILTIN_EXPECT(node->type != FS_FILE, 0)) + return NULL; - // searching for the valid data block + /* searching for the valid data block */ if (offset) { - pos = offset / node->block_size; - offset = offset % node->block_size; + pos = offset / MAX_DATAENTRIES; + offset = offset % MAX_DATAENTRIES; } - kprintf("Pos: %i, Offset: %i, %i", pos, offset, node->block_size); - - do { - for(i=0; idata[i]) { - found++; - if (found > pos) - data = (char*) blist->data[i]; - break; - } - } - if all blocks have already been used, we have to allocate a new one + for (i = 0; i < MAX_DATABLOCKS && !data; i++) { + if ((size + offset) >= MAX_DATAENTRIES) + size = MAX_DATAENTRIES - offset; + if(!blist->data[i]) { + blist->data[i] = (data_block_t*) kmalloc(sizeof(data_block_t)); + if (blist->data[i]) + memset(blist->data[i], 0x00, sizeof(data_block_t)); + } + found++; + if (found > pos) { + data = (char*) blist->data[i]; + } + } + if (!blist->next) { blist->next = (block_list_t*) kmalloc(sizeof(block_list_t)); - if (blist->next) { - kprintf("?"); + if (blist->next) memset(blist->next, 0x00, sizeof(block_list_t)); - } } - blist = blist->next; } while(blist && !data); - if (BUILTIN_EXPECT(!data, 0)) - return 0; -*/ + /* you may have to increase nodesize */ + if (node->block_size < (nodeoffset + size)) + node->block_size = nodeoffset + size; /* * If the data block is not large engough, * we copy only the rest of the current block. * The user has to restart the write operation * for the next block. */ -/* if (offset+size >= node->block_size) - size = node->block_size - offset; - memcpy(data + offset, buffer, size); -*/ //return size; + return size; } @@ -257,7 +226,7 @@ static vfs_node_t* initrd_mkdir(vfs_node_t* node, const char* name) new_node->mkdir = &initrd_mkdir; spinlock_init(&new_node->lock); - /* create default directory block */ + /* create default directory entry */ dir_block = (dir_block_t*) kmalloc(sizeof(dir_block_t)); if (BUILTIN_EXPECT(!dir_block, 0)) goto out; diff --git a/include/metalsvm/fs.h b/include/metalsvm/fs.h index 58897aa2..695bf107 100644 --- a/include/metalsvm/fs.h +++ b/include/metalsvm/fs.h @@ -66,6 +66,8 @@ typedef struct vfs_node *(*mkdir_type_t) (struct vfs_node *, const char *name); #define MAX_DATABLOCKS 12 #define MAX_DIRENTRIES 32 +#define MAX_DATAENTRIES 4096 + /** @brief Block list structure. VFS nodes keep those in a list */ typedef struct block_list { @@ -120,6 +122,11 @@ typedef struct { dirent_t entries[MAX_DIRENTRIES]; } dir_block_t; +typedef struct { + ///Array of data entries + char entries[MAX_DATAENTRIES]; +} data_block_t; + extern vfs_node_t* fs_root; // The root of the filesystem. /** @defgroup fsfunc FS related functions diff --git a/include/metalsvm/fs_types.h b/include/metalsvm/fs_types.h index 9b9df7e3..afe74086 100644 --- a/include/metalsvm/fs_types.h +++ b/include/metalsvm/fs_types.h @@ -32,8 +32,8 @@ typedef struct fildes { off_t offset; /* */ } fildes_t; -#define MAX_FILDES 10 -#define FS_INIT { [0 ... MAX_FILDES-1] = {NULL, 0} } +#define NR_OPEN 10 +#define FS_INIT { [0 ... NR_OPEN-1] = {NULL, 0} } #ifdef __cplusplus } diff --git a/include/metalsvm/tasks_types.h b/include/metalsvm/tasks_types.h index 7ba2d9a2..65e07575 100644 --- a/include/metalsvm/tasks_types.h +++ b/include/metalsvm/tasks_types.h @@ -72,7 +72,7 @@ typedef struct task { /// List of VMAs vma_t* vma_list; /// Filedescriptor table - fildes_t fildes_table[MAX_FILDES]; + fildes_t fildes_table[NR_OPEN]; /// Additional status flags. For instance, to signalize the using of the FPU uint32_t flags; /// starting time/tick of the task diff --git a/kernel/syscall.c b/kernel/syscall.c index 8c0af17e..46471282 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -29,7 +29,7 @@ static int sys_write(int fd, const char *buf, size_t len) { unsigned int wrotebytes; wrotebytes = write_fs(per_core(current_task)->fildes_table[fd].node, (uint8_t*)buf, len, per_core(current_task)->fildes_table[fd].offset); - //kprintf("ins Dateis. geschr. -- fd:%i, Dateilaenge:%i, Schreiblaenge: %i, Dateiinhalt: %s \n", fd, len, wrotebytes, buf); + kprintf("writing into filesystem -- fd:%i, Filelength:%i, Writtenbytes: %i, Bufferlength: %s \n", fd, len, wrotebytes, buf); per_core(current_task)->fildes_table[fd].offset += wrotebytes; return wrotebytes; @@ -38,13 +38,13 @@ static int sys_write(int fd, const char *buf, size_t len) static int sys_open(const char* file, int flags, int mode) { int fd; - for (fd = 3; fd < MAX_FILDES; fd++) { + for (fd = 3; fd < NR_OPEN; fd++) { if (per_core(current_task)->fildes_table[fd].node == NULL) { per_core(current_task)->fildes_table[fd].node = findnode_fs((char*) file); return fd; } } - if (fd >= MAX_FILDES) { + if (fd >= NR_OPEN) { kprintf("Unable to create filedescriptor"); return -EINVAL; } @@ -67,14 +67,15 @@ static int sys_read(int fd, const char *buf, size_t len) (uint8_t*)buf, len, per_core(current_task)->fildes_table[fd].offset); per_core(current_task)->fildes_table[fd].offset += readbytes; - //kprintf("fd:%i, Dateilaenge:%i, Dateiinhalt: %s X: %i\n", fd, len, buf, readbytes); + /*kprintf("fd:%i, Filelength:%i, Bufferlength: %s X: %i\n", fd, len, buf, readbytes); */ /* Beware: still reading above file limit! */ return readbytes; } static int sys_lseek(int fd, off_t pos, int origin) { - return 2; + kprintf("lseek used, but not ready yet"); + return 0; } static int sys_sbrk(int incr) diff --git a/newlib/examples/hello.c b/newlib/examples/hello.c index 61f9efc5..6ec4d968 100644 --- a/newlib/examples/hello.c +++ b/newlib/examples/hello.c @@ -27,20 +27,22 @@ extern int errno; int main(int argc, char** argv) { - //int i; - char* str = (char *)malloc(20 * sizeof(char)); + int i; + long offset_x = 5; + char* str = (char *)malloc(50 * sizeof(char)); FILE* testfile; testfile = fopen("/bin/test", "w+r"); setbuf(testfile, NULL); fflush(NULL); - fwrite("wsblablaxxxyyyyzzzzzz", 1, 19, testfile); + fwrite("wsx", 3, 1, testfile); + fwrite("nextnextnext", 1, 10, testfile); + fclose(testfile); testfile = fopen("/bin/test", "w+r"); setbuf(testfile, NULL); - fread(str, 1, 20, testfile); - fflush(NULL); - printf("Aus Datei gelesen (/bin/test):%s\n", str); + fread(str, 2, 40, testfile); + printf("reading (/bin/test):%s\n", str); return errno; } diff --git a/newlib/examples/test b/newlib/examples/test index d00491fd..4bcfe98e 100644 --- a/newlib/examples/test +++ b/newlib/examples/test @@ -1 +1 @@ -1 +d