diff --git a/.gitignore b/.gitignore index 56762699..11e6adb9 100644 --- a/.gitignore +++ b/.gitignore @@ -7,14 +7,18 @@ *.img *.a *.log +*.swp *.DS_Store +*.swp tags +Makefile include/metalsvm/config.h tools/make_initrd newlib/examples/hello +newlib/examples/jacobi newlib/examples/echo newlib/examples/tests -newlib/examples/jacobi +newlib/examples/mshell newlib/examples/server newlib/examples/client newlib/tmp/* diff --git a/Makefile.example b/Makefile.example index c74fd26b..0ac25df0 100644 --- a/Makefile.example +++ b/Makefile.example @@ -59,7 +59,6 @@ newlib: RANLIB_FOR_TARGET=$(RANLIB_FOR_TARGET) \ STRIP_FOR_TARGET=$(STRIP_FOR_TARGET) \ READELF_FOR_TARGET=$(READELF_FOR_TARGET) -C newlib - tools: $(MAKE) -C tools diff --git a/arch/x86/include/asm/kb.h b/arch/x86/include/asm/kb.h index 74d66d6c..1b2dfb40 100644 --- a/arch/x86/include/asm/kb.h +++ b/arch/x86/include/asm/kb.h @@ -43,6 +43,18 @@ extern "C" { */ void keyboard_init(void); +typedef struct +{ + char* buffer; + size_t maxsize; + size_t size; + tid_t tid; +} kb_buffer_t; + +extern kb_buffer_t kb_buffer; + +void kb_flush(); + #endif #ifdef __cplusplus diff --git a/arch/x86/kernel/kb.c b/arch/x86/kernel/kb.c index ac07d146..237c3280 100644 --- a/arch/x86/kernel/kb.c +++ b/arch/x86/kernel/kb.c @@ -17,13 +17,26 @@ * This file is part of MetalSVM. */ +#include #include #include +#include #include #include #ifdef CONFIG_KEYBOARD +kb_buffer_t kb_buffer = {NULL, 0, 0, 0 }; + +void kb_flush() { + kfree(kb_buffer.buffer, (kb_buffer.maxsize * sizeof(char))); + kb_buffer.buffer = NULL; + kb_buffer.size = 0; + kb_buffer.maxsize = 0; + kb_buffer.tid = 0; + return; +} + /* * KBDUS means US Keyboard Layout. This is a scancode table * used to layout a standard US keyboard. I have left some @@ -42,8 +55,8 @@ static const unsigned char kbdus[128] = { 0, 27, '1', '2', '3', '4', '5', '6', ' '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */ 'm', ',', '.', '/', 0, /* Right shift */ '*', 0, /* Alt */ - ' ', /* Space bar */ - 0, /* Caps lock */ + ' ', /* 57 - Space bar */ + 0, /* 58 - Caps lock */ 0, /* 59 - F1 key ... > */ 0, 0, 0, 0, 0, 0, 0, 0, 0, /* < ... F10 */ 0, /* 69 - Num lock */ @@ -98,7 +111,26 @@ static void keyboard_handler(struct state *r) * held. If shift is held using the larger lookup table, * you would add 128 to the scancode when you look for it */ - kputchar(kbdus[scancode]); + if (kb_buffer.size <= kb_buffer.maxsize && kb_buffer.buffer != NULL) { + if (scancode == 14) { + if (kb_buffer.size != 0) { + kb_buffer.size--; + kputchar(kbdus[scancode]); + kputchar(kbdus[57]); + kputchar(kbdus[scancode]); + } + } + else { + kputchar(kbdus[scancode]); + memcpy(kb_buffer.buffer + kb_buffer.size, &kbdus[scancode], 1); + kb_buffer.size++; + } + if (scancode == 28 || scancode == 15 || kb_buffer.size >= kb_buffer.maxsize) { + kputchar(kbdus[scancode]); + wakeup_task(kb_buffer.tid); + reschedule(); + } + } } } diff --git a/drivers/char/Makefile b/drivers/char/Makefile index aac9ef95..f20cc532 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -1,4 +1,5 @@ -C_source := null.c +C_source := stdio.c socket.c + MODULE := drivers_char include $(TOPDIR)/Makefile.inc diff --git a/drivers/char/null.c b/drivers/char/socket.c old mode 100644 new mode 100755 similarity index 58% rename from drivers/char/null.c rename to drivers/char/socket.c index 4fa0d840..71133413 --- a/drivers/char/null.c +++ b/drivers/char/socket.c @@ -1,5 +1,5 @@ /* - * Copyright 2010 Stefan Lankes, Chair for Operating Systems, + * Copyright 2011 Marian Ohligs, Chair for Operating Systems, * RWTH Aachen University * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,32 +22,67 @@ #include #include #include +#include +#include -/* Implementation of a simple null device */ +#if defined(CONFIG_LWIP) && LWIP_SOCKET +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif -static ssize_t null_read(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) + +/* Implementation of a simple netio device */ + +static ssize_t socket_read(fildes_t* file, uint8_t* buffer, size_t size) { - memset(buffer, 0x00, size); + int ret = 0; +#if defined(CONFIG_LWIP) && LWIP_SOCKET + ret = lwip_read((int)file->offset, buffer, size); - return size; + if (ret < 0) + ret = -errno; +#endif + kprintf("return size: %i", ret); + return ret; } -static ssize_t null_write(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) +static ssize_t socket_write(fildes_t* file, uint8_t* buffer, size_t size) { - return size; + int ret = 0; +#if defined(CONFIG_LWIP) && LWIP_SOCKET + ret = lwip_write(file->offset, buffer, size); + if (ret < 0) + ret = -errno; +#endif + return ret; } -static int null_open(vfs_node_t* node) +static int socket_open(fildes_t* file, const char* name) { return 0; } -static int null_close(vfs_node_t* node) +static int socket_close(fildes_t* file) { - return 0; + int ret = 0; +#if defined(CONFIG_LWIP) && LWIP_SOCKET + //ret = lwip_close(file->offset); + if (ret < 0) + ret = -errno; +#endif + return ret; } -int null_init(vfs_node_t* node, const char* name) +int socket_init(vfs_node_t* node, const char* name) { uint32_t i, j; vfs_node_t* new_node; @@ -70,10 +105,10 @@ int null_init(vfs_node_t* node, const char* name) memset(new_node, 0x00, sizeof(vfs_node_t)); new_node->type = FS_CHARDEVICE; - new_node->open = &null_open; - new_node->close = &null_close; - new_node->read = &null_read; - new_node->write = &null_write; + new_node->open = &socket_open; + new_node->close = &socket_close; + new_node->read = &socket_read; + new_node->write = &socket_write; spinlock_init(&new_node->lock); blist= &node->block_list; diff --git a/drivers/char/stdio.c b/drivers/char/stdio.c new file mode 100644 index 00000000..32ac4755 --- /dev/null +++ b/drivers/char/stdio.c @@ -0,0 +1,325 @@ +/* + * Copyright 2011 Marian Ohligs, Chair for Operating Systems, + * RWTH Aachen University + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of MetalSVM. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Functions of a simple null device */ + +static ssize_t null_read(fildes_t* file, uint8_t* buffer, size_t size) +{ + memset(buffer, 0x00, size); + + file->offset += size; + return size; +} + +static ssize_t null_write(fildes_t* file, uint8_t* buffer, size_t size) +{ + return size; +} + +static int null_open(fildes_t* file, const char* name) +{ + return 0; +} + +static int null_close(fildes_t* file) +{ + return 0; +} + +/* Read Function of a stdio device */ + +static ssize_t stdio_read(fildes_t* file, uint8_t* buffer, size_t size) +{ + kb_buffer.buffer = kmalloc(size * sizeof(char)); + kb_buffer.maxsize = size; + kb_buffer.size = 0; + kb_buffer.tid = per_core(current_task)->id; + block_current_task(); + //per_core(current_task)->status = TASK_BLOCKED; + reschedule(); + + size = kb_buffer.size; + memcpy(buffer, kb_buffer.buffer, size); + + /*cleaning up */ + kb_flush(); + + //kprintf("Size: %i, offset: %i, buffer: %s", size, buffer, offset); + file->offset += size; + return size; +} + +/* Write Function of a stdio device */ + +static ssize_t stdio_write(fildes_t* file, uint8_t* buffer, size_t size) +{ + int i; + for (i = 0; ioffset += size; + return size; +} + +/* Init Functions */ + +int null_init(vfs_node_t* node, const char* name) +{ + uint32_t i, j; + vfs_node_t* new_node; + dir_block_t* blockdir; + dirent_t* dirent; + block_list_t* blist; + + if (BUILTIN_EXPECT(!node || !name, 0)) + return -EINVAL; + + if (BUILTIN_EXPECT(node->type != FS_DIRECTORY, 0)) + return -EINVAL; + + if (finddir_fs(node, name)) + return -EINVAL; + + new_node = kmalloc(sizeof(vfs_node_t)); + if (BUILTIN_EXPECT(!new_node, 0)) + return -ENOMEM; + + memset(new_node, 0x00, sizeof(vfs_node_t)); + new_node->type = FS_CHARDEVICE; + new_node->open = &null_open; + new_node->close = &null_close; + new_node->read = &null_read; + new_node->write = &null_write; + spinlock_init(&new_node->lock); + + blist= &node->block_list; + do { + for(i=0; idata[i]) { + blockdir = (dir_block_t*) blist->data[i]; + for(j=0; jentries[j]; + if (!dirent->vfs_node) { + dirent->vfs_node = new_node; + strncpy(dirent->name, name, MAX_FNAME); + return 0; + } + } + } + } + + if (!blist->next) { + blist->next = (block_list_t*) kmalloc(sizeof(block_list_t)); + if (blist->next) + memset(blist->next, 0x00, sizeof(block_list_t)); + } + + } while(blist); + + kfree(new_node, sizeof(vfs_node_t)); + + return -ENOMEM; +} + + +int stdin_init(vfs_node_t* node, const char* name) +{ + uint32_t i, j; + vfs_node_t* new_node; + dir_block_t* blockdir; + dirent_t* dirent; + block_list_t* blist; + + if (BUILTIN_EXPECT(!node || !name, 0)) + return -EINVAL; + + if (BUILTIN_EXPECT(node->type != FS_DIRECTORY, 0)) + return -EINVAL; + + if (finddir_fs(node, name)) + return -EINVAL; + + new_node = kmalloc(sizeof(vfs_node_t)); + if (BUILTIN_EXPECT(!new_node, 0)) + return -ENOMEM; + + memset(new_node, 0x00, sizeof(vfs_node_t)); + new_node->type = FS_CHARDEVICE; + new_node->open = &null_open; + new_node->close = &null_close; + new_node->read = &stdio_read; + new_node->write = &null_write; + spinlock_init(&new_node->lock); + + blist= &node->block_list; + do { + for(i=0; idata[i]) { + blockdir = (dir_block_t*) blist->data[i]; + for(j=0; jentries[j]; + if (!dirent->vfs_node) { + dirent->vfs_node = new_node; + strncpy(dirent->name, name, MAX_FNAME); + return 0; + } + } + } + } + + if (!blist->next) { + blist->next = (block_list_t*) kmalloc(sizeof(block_list_t)); + if (blist->next) + memset(blist->next, 0x00, sizeof(block_list_t)); + } + + } while(blist); + + kfree(new_node, sizeof(vfs_node_t)); + + return -ENOMEM; +} + + +int stdout_init(vfs_node_t* node, const char* name) +{ + uint32_t i, j; + vfs_node_t* new_node; + dir_block_t* blockdir; + dirent_t* dirent; + block_list_t* blist; + + if (BUILTIN_EXPECT(!node || !name, 0)) + return -EINVAL; + + if (BUILTIN_EXPECT(node->type != FS_DIRECTORY, 0)) + return -EINVAL; + + if (finddir_fs(node, name)) + return -EINVAL; + + new_node = kmalloc(sizeof(vfs_node_t)); + if (BUILTIN_EXPECT(!new_node, 0)) + return -ENOMEM; + + memset(new_node, 0x00, sizeof(vfs_node_t)); + new_node->type = FS_CHARDEVICE; + new_node->open = &null_open; + new_node->close = &null_close; + new_node->read = &null_read; + new_node->write = &stdio_write; + spinlock_init(&new_node->lock); + + blist= &node->block_list; + do { + for(i=0; idata[i]) { + blockdir = (dir_block_t*) blist->data[i]; + for(j=0; jentries[j]; + if (!dirent->vfs_node) { + dirent->vfs_node = new_node; + strncpy(dirent->name, name, MAX_FNAME); + return 0; + } + } + } + } + + if (!blist->next) { + blist->next = (block_list_t*) kmalloc(sizeof(block_list_t)); + if (blist->next) + memset(blist->next, 0x00, sizeof(block_list_t)); + } + + } while(blist); + + kfree(new_node, sizeof(vfs_node_t)); + + return -ENOMEM; +} + + +int stderr_init(vfs_node_t* node, const char* name) +{ + uint32_t i, j; + vfs_node_t* new_node; + dir_block_t* blockdir; + dirent_t* dirent; + block_list_t* blist; + + if (BUILTIN_EXPECT(!node || !name, 0)) + return -EINVAL; + + if (BUILTIN_EXPECT(node->type != FS_DIRECTORY, 0)) + return -EINVAL; + + if (finddir_fs(node, name)) + return -EINVAL; + + new_node = kmalloc(sizeof(vfs_node_t)); + if (BUILTIN_EXPECT(!new_node, 0)) + return -ENOMEM; + + memset(new_node, 0x00, sizeof(vfs_node_t)); + new_node->type = FS_CHARDEVICE; + new_node->open = &null_open; + new_node->close = &null_close; + new_node->read = &null_read; + new_node->write = &stdio_write; + spinlock_init(&new_node->lock); + + blist= &node->block_list; + do { + for(i=0; idata[i]) { + blockdir = (dir_block_t*) blist->data[i]; + for(j=0; jentries[j]; + if (!dirent->vfs_node) { + dirent->vfs_node = new_node; + strncpy(dirent->name, name, MAX_FNAME); + return 0; + } + } + } + } + + if (!blist->next) { + blist->next = (block_list_t*) kmalloc(sizeof(block_list_t)); + if (blist->next) + memset(blist->next, 0x00, sizeof(block_list_t)); + } + + } while(blist); + + kfree(new_node, sizeof(vfs_node_t)); + + return -ENOMEM; +} diff --git a/fs/fs.c b/fs/fs.c index 1be0f206..a56c9f9d 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -17,15 +17,18 @@ * This file is part of MetalSVM. */ +#include #include #include #include #include +#include vfs_node_t* fs_root = NULL; // The root of the filesystem. -ssize_t read_fs(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) +ssize_t read_fs(fildes_t* file, uint8_t* buffer, size_t size) { + vfs_node_t* node = file->node; ssize_t ret = -EINVAL; if (BUILTIN_EXPECT(!node || !buffer, 0)) @@ -34,56 +37,87 @@ ssize_t read_fs(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) spinlock_lock(&node->lock); // Has the node got a read callback? if (node->read != 0) - ret = node->read(node, buffer, size, offset); + ret = node->read(file, buffer, size); spinlock_unlock(&node->lock); return ret; } -ssize_t write_fs(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) +ssize_t write_fs(fildes_t* file, uint8_t* buffer, size_t size) { + vfs_node_t* node = file->node; ssize_t ret = -EINVAL; if (BUILTIN_EXPECT(!node || !buffer, 0)) return ret; spinlock_lock(&node->lock); - // Has the node got a write callback? + // Has the node got a write callback? if (node->write != 0) - ret = node->write(node, buffer, size, offset); + ret = node->write(file, buffer, size); spinlock_unlock(&node->lock); return ret; } -int open_fs(vfs_node_t* node, uint8_t read, uint8_t write) +int open_fs(fildes_t* file, const char* name) { - int ret = -EINVAL; + uint32_t ret = 0, i, j = 1; + vfs_node_t* file_node = NULL; /* file node */ + vfs_node_t* dir_node = NULL; + char* fname = kmalloc(sizeof(char)*MAX_FNAME); - if (BUILTIN_EXPECT(!node, 0)) + if (BUILTIN_EXPECT(!name, 0)) return ret; - spinlock_lock(&node->lock); - // Has the node got an open callback? - if (node->open != 0) - ret = node->open(node); - spinlock_unlock(&node->lock); + if (name[0] == '/') + file_node = fs_root; + + while((name[j] != '\0') && (file_node != NULL)) { + i = 0; + while((name[j] != '/') && (name[j] != '\0')) { + fname[i] = name[j]; + i++; j++; + } + fname[i] = '\0'; + dir_node = file_node; /* file must be a dictionary */ + file_node = finddir_fs(dir_node, fname); + if (name[j] == '/') + j++; + } + + /* file exists */ + if(file_node) { + spinlock_lock(&file_node->lock); + file->node = file_node; + // Has the file_node got an open callback? + if (file_node->open != 0) + ret = file->node->open(file, NULL); + spinlock_unlock(&file_node->lock); + } else { /* file doesn't exist */ + spinlock_lock(&dir_node->lock); + file->node = dir_node; + // Has the dir_node got an open callback? + if (dir_node->open != 0) + ret = dir_node->open(file, fname); + spinlock_unlock(&dir_node->lock); + } return ret; } -int close_fs(vfs_node_t* node) +int close_fs(fildes_t* file) { int ret = -EINVAL; - if (BUILTIN_EXPECT(!node, 0)) + if (BUILTIN_EXPECT(!(file->node), 0)) return ret; - spinlock_lock(&node->lock); + spinlock_lock(&file->node->lock); // Has the node got a close callback? - if (node->close != 0) - ret = node->close(node); - spinlock_unlock(&node->lock); + if (file->node->close != 0) + ret = file->node->close(file); + spinlock_unlock(&file->node->lock); return ret; } @@ -161,4 +195,3 @@ vfs_node_t* findnode_fs(const char* name) return ret; } - diff --git a/fs/initrd.c b/fs/initrd.c index a0932eff..09719171 100644 --- a/fs/initrd.c +++ b/fs/initrd.c @@ -23,7 +23,10 @@ #include #include #include +#include #include +#include + #ifdef CONFIG_ROCKCREEK #include #endif @@ -52,18 +55,25 @@ typedef struct { char fname[MAX_FNAME]; } initrd_file_desc_t; -static ssize_t initrd_read(vfs_node_t* node, uint8_t* buffer, size_t size, off_t offset) +static ssize_t initrd_read(fildes_t* file, uint8_t* buffer, size_t size) { uint32_t i, pos = 0, found = 0; + off_t offset = 0; char* data = NULL; + vfs_node_t* node = file->node; block_list_t* blist = &node->block_list; + if (file->flags & O_WRONLY) + return -EACCES; + + /* init the tmp offset */ + offset = file->offset; + /* searching for the valid data block */ if (offset) { pos = offset / node->block_size; offset = offset % node->block_size; } - do { for(i=0; idata[i]) { @@ -85,14 +95,178 @@ static ssize_t initrd_read(vfs_node_t* node, uint8_t* buffer, size_t size, off_t * The user has to restart the read operation * for the next block. */ - if (offset+size >= node->block_size) + if ((offset + size) >= node->block_size) size = node->block_size - offset; memcpy(buffer, data + offset, size); + file->offset += size; return size; } +static ssize_t initrd_write(fildes_t* file, uint8_t* buffer, size_t size) +{ + uint32_t i, pos = 0, found = 0; + off_t offset = 0; + char* data = NULL; + vfs_node_t* node = file->node; + block_list_t* blist = &node->block_list; + + if (file->flags & O_RDONLY) + return -EACCES; + + if (file->flags & O_APPEND) + file->offset = node->block_size; + + /* init the tmp offset */ + offset = file->offset; + + /* searching for the valid data block */ + if (offset) { + pos = offset / MAX_DATAENTRIES; + offset = offset % MAX_DATAENTRIES; + } + + do { + 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) + memset(blist->next, 0x00, + sizeof(block_list_t)); + } + blist = blist->next; + } while(blist && !data); + + /* you may have to increase nodesize */ + if (node->block_size < (file->offset + size)) + node->block_size = file->offset + 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. + */ + memcpy(data + offset, buffer, size); + file->offset += size; + return size; +} + +static int initrd_open(fildes_t* file, const char* name) +{ + if (file->node->type == FS_FILE) { + if ((file->flags & O_CREAT) && (file->flags & O_EXCL)) + return -EEXIST; + + /* in the case of O_TRUNC kfree all the nodes */ + if (file->flags & O_TRUNC) { + uint32_t i; + char* data = NULL; + block_list_t* blist = &file->node->block_list; + block_list_t* lastblist = NULL; + + /* the first blist pointer have do remain valid. */ + for(i=0; idata[i]) { + kfree(blist->data[i], + sizeof(data_block_t)); + } + } + if (blist->next) { + lastblist = blist; + blist = blist->next; + lastblist->next = NULL; + + /* kfree all other blist pointers */ + do { + for(i=0; idata[i]) { + kfree(blist->data[i], sizeof(data_block_t)); + } + } + lastblist = blist; + blist = blist->next; + kfree(lastblist, sizeof(block_list_t)); + } while(blist); + } + + /* reset the block_size */ + file->node->block_size = 0; + } + } + + if (file->node->type == FS_DIRECTORY) { + if (!file->flags & O_CREAT) + return -ENOENT; + + uint32_t i, j; + block_list_t* blist = NULL; + /* CREATE FILE */ + vfs_node_t* new_node = kmalloc(sizeof(vfs_node_t)); + if (BUILTIN_EXPECT(!new_node, 0)) + return -EINVAL; + + blist = &file->node->block_list; + dir_block_t* dir_block; + dirent_t* dirent; + + memset(new_node, 0x00, sizeof(vfs_node_t)); + new_node->type = FS_FILE; + new_node->read = initrd_read; + new_node->write = initrd_write; + new_node->open = initrd_open; + spinlock_init(&new_node->lock); + + /* create a entry for the new node in the directory block of current node */ + do { + for(i=0; idata[i]) { + dir_block = (dir_block_t*) blist->data[i]; + for(j=0; jentries[j]; + if (!dirent->vfs_node) { + dirent->vfs_node = new_node; + strncpy(dirent->name, (char*) name, MAX_FNAME); + goto exit_create_file; // there might be a better Solution *************** + } + } + } + } + /* if all blocks are reserved, we have to allocate a new one */ + 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(blist); + +exit_create_file: + file->node = new_node; + file->node->block_size = 0; + + } + return 0; +} + + static dirent_t* initrd_readdir(vfs_node_t* node, uint32_t index) { uint32_t i, j, count; @@ -167,9 +341,10 @@ static vfs_node_t* initrd_mkdir(vfs_node_t* node, const char* name) new_node->readdir = &initrd_readdir; new_node->finddir = &initrd_finddir; new_node->mkdir = &initrd_mkdir; + new_node->open = &initrd_open; 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; @@ -237,6 +412,7 @@ int initrd_init(void) initrd_root.readdir = &initrd_readdir; initrd_root.finddir = &initrd_finddir; initrd_root.mkdir = &initrd_mkdir; + initrd_root.open = &initrd_open; spinlock_init(&initrd_root.lock); /* create default directory block */ @@ -257,6 +433,15 @@ int initrd_init(void) tmp = mkdir_fs(fs_root, "dev"); /* create the character device "null" */ null_init(tmp, "null"); + /* create the standart input device "stdin" */ + stdin_init(tmp, "stdin"); + /* create the standart output device "stdout" */ + stdout_init(tmp, "stdout"); + /* create the standart error-output device "stderr" */ + stderr_init(tmp, "stderr"); + /* create the standart device "netchar" */ + socket_init(tmp, "socket"); + /* For every module.. */ #ifdef CONFIG_MULTIBOOT @@ -305,6 +490,8 @@ int initrd_init(void) memset(new_node, 0x00, sizeof(vfs_node_t)); new_node->type = FS_FILE; new_node->read = initrd_read; + new_node->write = initrd_write; + new_node->open = initrd_open; new_node->block_size = file_desc->length; new_node->block_list.data[0] = ((char*) header) + file_desc->offset; spinlock_init(&new_node->lock); diff --git a/include/metalsvm/fs.h b/include/metalsvm/fs.h index 10b8412a..b281c8be 100644 --- a/include/metalsvm/fs.h +++ b/include/metalsvm/fs.h @@ -27,7 +27,7 @@ #define __FS_H__ #include -#include +#include #define FS_FILE 0x01 #define FS_DIRECTORY 0x02 @@ -37,8 +37,38 @@ //#define FS_SYMLINK 0x06 //#define FS_MOUNTPOINT 0x08 // Is the file an active mountpoint? -struct vfs_node; +/*file descriptor init*/ +#define NR_OPEN 100 + +/*open flags*/ + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +#define O_CREAT 64 +#define O_EXCL 128 +//#define O_NOCTTY 256 +#define O_TRUNC 512 +#define O_APPEND 1024 +//#define O_NDELAY 2048 +//#define O_SYNC 4096 +//#define O_ASYNC 8192 + +/*lseek defines*/ +#ifndef SEEK_SET +#define SEEK_SET 0 /* set file offset to offset */ +#endif +#ifndef SEEK_CUR +#define SEEK_CUR 1 /* set file offset to current plus offset */ +#endif +#ifndef SEEK_END +#define SEEK_END 2 /* set file offset to EOF plus offset */ +#endif + +struct vfs_node; +struct fildes; /** @defgroup fsprototypes FS access function prototypes * * These typedefs define the type of callbacks - called when read/write/open/close are called.\n @@ -48,13 +78,13 @@ struct vfs_node; */ /** @brief Read function pointer */ -typedef ssize_t (*read_type_t) (struct vfs_node *, uint8_t*, size_t, off_t); +typedef ssize_t (*read_type_t) (struct fildes *, uint8_t*, size_t); /** @brief Write function pointer */ -typedef ssize_t (*write_type_t) (struct vfs_node *, uint8_t*, size_t, off_t); +typedef ssize_t (*write_type_t) (struct fildes *, uint8_t*, size_t); /** @brief Open function pointer */ -typedef int (*open_type_t) (struct vfs_node *); +typedef int (*open_type_t) (struct fildes *, const char *name); /** @brief Close function pointer */ -typedef int (*close_type_t) (struct vfs_node *); +typedef int (*close_type_t) (struct fildes *); /** @brief Read directory function pointer */ typedef struct dirent *(*readdir_type_t) (struct vfs_node *, uint32_t); /** @brief Find directory function pointer */ @@ -66,6 +96,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 { @@ -106,8 +138,16 @@ typedef struct vfs_node { block_list_t block_list; } vfs_node_t; +/** @brief file descriptor structure */ +typedef struct fildes { + vfs_node_t* node; /* */ + off_t offset; /* */ + int flags; /* */ + int mode; /* */ +} fildes_t; + /** @brief Directory entry structure */ -typedef struct dirent{ +typedef struct dirent { /// Directory name char name[MAX_FNAME]; /// Corresponding VFS node pointer @@ -120,6 +160,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 @@ -140,7 +185,7 @@ extern vfs_node_t* fs_root; // The root of the filesystem. * - number of bytes copied (size) * - 0 on error */ -ssize_t read_fs(vfs_node_t * node, uint8_t* buffer, size_t size, off_t offset); +ssize_t read_fs(fildes_t* file, uint8_t* buffer, size_t size); /** @brief Write into the file system from the buffer * @param node Pointer to the node to write to @@ -151,12 +196,12 @@ ssize_t read_fs(vfs_node_t * node, uint8_t* buffer, size_t size, off_t offset); * - number of bytes copied (size) * - 0 on error */ -ssize_t write_fs(vfs_node_t * node, uint8_t* buffer, size_t size, off_t offset); +ssize_t write_fs(fildes_t* file, uint8_t* buffer, size_t size); /** @brief Yet to be documented */ -int open_fs(vfs_node_t * node, uint8_t read, uint8_t write); +int open_fs(fildes_t* file, const char* fname); /** @brief Yet to be documented */ -int close_fs(vfs_node_t * node); +int close_fs(fildes_t * file); /** @brief Get dir entry at index * @param node VFS node to get dir entry from @@ -196,6 +241,10 @@ vfs_node_t* findnode_fs(const char* name); /* @} */ int null_init(vfs_node_t* node, const char* name); +int stdin_init(vfs_node_t* node, const char* name); +int stdout_init(vfs_node_t* node, const char* name); +int stderr_init(vfs_node_t* node, const char* name); +int socket_init(vfs_node_t* node, const char* name); int initrd_init(void); #endif diff --git a/include/metalsvm/tasks_types.h b/include/metalsvm/tasks_types.h index d1fd7cf0..3e47b78c 100644 --- a/include/metalsvm/tasks_types.h +++ b/include/metalsvm/tasks_types.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -91,6 +92,8 @@ typedef struct task { spinlock_t vma_lock; /// List of VMAs vma_t* vma_list; + /// Filedescriptor table + fildes_t* fildes_table; /// starting time/tick of the task uint64_t start_tick; /// Start address of the heap diff --git a/kernel/init.c b/kernel/init.c index d17fbe9c..fb13ff9c 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -177,6 +177,10 @@ static void list_fs(vfs_node_t* node, uint32_t depth) { int j, i = 0; dirent_t* dirent = NULL; + fildes_t* file = kmalloc(sizeof(fildes_t)); + file->offset = 0; + file->flags = 0; + while ((dirent = readdir_fs(node, i)) != 0) { for(j=0; jtype == FS_FILE) { char buff[16] = {[0 ... 15] = 0x00}; + + file->node = new_node; + file->offset = 0; + file->flags = 0; - read_fs(new_node, (uint8_t*)buff, 8, 0); + read_fs(file, (uint8_t*)buff, 8); for(j=0; j #include #include +#include #include #include #include @@ -39,25 +40,131 @@ #include #include -/* - * We set the a bit LWIP_FD_BIT to determine, - * if the descriptor belongs to LwIP or MetalSVM. - */ -#define LWIP_FD_BIT (1 << 28) #endif -static int sys_write(int fildes, const char *buf, size_t len) +static int get_fildes(){ + int fd; + + for (fd = 0; fd < NR_OPEN; fd++) { + if (per_core(current_task)->fildes_table[fd].node == NULL) { + return fd; + } + } + + /* can't get any free fd */ + return -EMFILE; +} + +static int sys_open(const char* name, int flags, int mode) { - int i; + int fd, check; + fildes_t* file = NULL; - if (BUILTIN_EXPECT(!buf, 0)) - return -1; + fd = get_fildes(); + /* validate the fd */ + if (fd < 0) + return fd; - for (i = 0; ifildes_table[fd]); + file->offset = 0; + file->mode = mode; + file->flags = flags; + + check = open_fs(file, (char*) name); + if (check < 0) { + /* file doesn't exist! */ + file->node = NULL; + return check; + } + + return fd; +} + +#if defined(CONFIG_LWIP) && LWIP_SOCKET +static int sys_socket(int domain, int type, int protocol) +{ + int fd; + fildes_t* file = NULL; + + fd = get_fildes(); + /* validate the fd */ + if (fd < 0) + return fd; + + file = &(per_core(current_task)->fildes_table[fd]); + file->offset = lwip_socket(domain, type, protocol); + file->mode = 0; + file->flags = 0; + file->node = findnode_fs("/dev/socket"); + + return fd; +} + +static int sys_accept(int s, struct sockaddr* addr, socklen_t* addrlen) +{ + int fd; + fildes_t* file = NULL; + + fd = get_fildes(); + /* validate the fd */ + if (fd < 0) + return fd; + + file = &(per_core(current_task)->fildes_table[fd]); + file->offset = lwip_accept(s, addr, addrlen); + file->mode = 0; + file->flags = 0; + file->node = findnode_fs("/dev/socket"); + + return fd; +} + +#endif + + +static int sys_close(int fd) +{ + fildes_t* file = &(per_core(current_task)->fildes_table[fd]); + close_fs(file); + file->node = NULL; + file->offset = 0; + file->mode = 0; + file->flags = 0; + return 0; + +} + +static int sys_lseek(int fd, off_t pos, int origin) +{ + int ret = -EINVAL; + fildes_t* file = &(per_core(current_task)->fildes_table[fd]); + + // Disabled for testing purposes + if (BUILTIN_EXPECT(file->node->type != FS_FILE + && file->node->type != FS_CHARDEVICE, 0)); + return -EINVAL; + + switch(origin) + { + case SEEK_SET: { /* set file offset to offset */ + file->offset = pos; + ret = 0; + break; + } + case SEEK_CUR: { /* set file offset to current plus offset */ + ret = pos + file->offset; + break; + } + case SEEK_END: { /* set file offset to EOF plus offset */ + file->offset = pos + file->node->block_size; + ret = 0; + break; + } + default: + ret = -EINVAL; + break; } - - return len; + return ret; } static int sys_sbrk(int incr) @@ -102,37 +209,44 @@ int syscall_handler(uint32_t sys_nr, ...) ret = 0; break; case __NR_write: { - int fildes = va_arg(vl, int); + int fd = va_arg(vl, int); const char* buf = va_arg(vl, const char*); size_t len = va_arg(vl, size_t); - -#if defined(CONFIG_LWIP) && LWIP_SOCKET - if (fildes & LWIP_FD_BIT) { - ret = lwip_write(fildes & ~LWIP_FD_BIT, buf, len); - if (ret < 0) - ret = -errno; - } else ret = sys_write(fildes, buf, len); -#else - ret = sys_write(fildes, buf, len); -#endif + if (fd >= 0) + ret = write_fs(&(per_core(current_task)->fildes_table[fd]), + (uint8_t*)buf, len); + break; + } + case __NR_open: { + const char* name = va_arg(vl, const char*); + int flags = va_arg(vl, int); + int mode = va_arg(vl, int); + ret = sys_open(name, flags, mode); break; } - case __NR_open: - ret = 1; - break; case __NR_close: { -#if defined(CONFIG_LWIP) && LWIP_SOCKET - int s = va_arg(vl, int); - if (s & LWIP_FD_BIT) { - ret = lwip_close(s & ~LWIP_FD_BIT); - if (ret < 0) - ret = -errno; - } else ret = 0; -#else - ret = 0; -#endif - break; - } + int fd = va_arg(vl, int); + if (fd >= 0) + 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); + if (fd >= 0) + ret = read_fs(&(per_core(current_task)->fildes_table[fd]), + (uint8_t*)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); + if (fd >= 0) + ret = sys_lseek(fd, pos, origin); + break; + } case __NR_sbrk: { int incr = va_arg(vl, int); @@ -167,30 +281,14 @@ int syscall_handler(uint32_t sys_nr, ...) break; } #if defined(CONFIG_LWIP) && LWIP_SOCKET - case __NR_read: { - int s = va_arg(vl, int); - void* mem = va_arg(vl, void*); - size_t len = va_arg(vl, size_t); - - if (!(s & LWIP_FD_BIT)) { - ret = -ENOTSOCK; - break; - } - - ret = lwip_read(s & ~LWIP_FD_BIT, mem, len); - if (ret < 0) - ret = -errno; - break; - } case __NR_closesocket: { - int s = va_arg(vl, int); + int fd = va_arg(vl, int); - if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) { + if (fd < 0) { ret = -ENOTSOCK; break; } - - ret = lwip_close(s & ~LWIP_FD_BIT); + //ret = lwip_close(per_core(current_task)->fildes_table[fd].offset); if (ret < 0) ret = -errno; break; @@ -200,71 +298,65 @@ int syscall_handler(uint32_t sys_nr, ...) int type = va_arg(vl, int); int protocol = va_arg(vl, int); - ret = lwip_socket(domain, type, protocol); - if (ret >= 0) - ret |= LWIP_FD_BIT; - else - ret = -errno; + ret = sys_socket(domain, type, protocol); break; } case __NR_connect: { - int s = va_arg(vl, int); + int fd = va_arg(vl, int); const struct sockaddr* name = va_arg(vl, const struct sockaddr*); socklen_t namelen = va_arg(vl, socklen_t); - if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) { + if (per_core(current_task)->fildes_table[fd].offset < 0) { ret = -ENOTSOCK; break; } + //kprintf("lwip_connect: %p with lenght %i and Socket %i", name, namelen, per_core(current_task)->fildes_table[fd].offset); - ret = lwip_connect(s & ~LWIP_FD_BIT, name, namelen); + + ret = lwip_connect(per_core(current_task)->fildes_table[fd].offset, name, namelen); if (ret < 0) ret = -errno; break; } case __NR_bind: { - int s = va_arg(vl, int); + int fd = va_arg(vl, int); const struct sockaddr* name = va_arg(vl, const struct sockaddr*); socklen_t namelen = va_arg(vl, socklen_t); - if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) { + if (per_core(current_task)->fildes_table[fd].offset < 0) { ret = -ENOTSOCK; break; } - - ret = lwip_bind(s & ~LWIP_FD_BIT, name, namelen); + ret = lwip_bind(per_core(current_task)->fildes_table[fd].offset, name, namelen); if (ret < 0) ret = -errno; break; } - case __NR_listen:{ - int s = va_arg(vl, int); + case __NR_listen: { + int fd = va_arg(vl, int); int backlog = va_arg(vl, int); - if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) { + if (per_core(current_task)->fildes_table[fd].offset < 0) { ret = -ENOTSOCK; break; } - ret = lwip_listen(s & ~LWIP_FD_BIT, backlog); + ret = lwip_listen(per_core(current_task)->fildes_table[fd].offset, backlog); if (ret < 0) ret = -errno; break; } case __NR_accept: { - int s = va_arg(vl, int); + int fd = va_arg(vl, int); struct sockaddr* addr = va_arg(vl, struct sockaddr*); socklen_t* addrlen = va_arg(vl, socklen_t*); - if (BUILTIN_EXPECT(!(s & LWIP_FD_BIT), 0)) { + if (per_core(current_task)->fildes_table[fd].offset < 0) { ret = -ENOTSOCK; break; } - - ret = lwip_accept(s & ~LWIP_FD_BIT, addr, addrlen); - if (ret >= 0) - ret |= LWIP_FD_BIT; - else + ret = sys_accept(per_core(current_task)->fildes_table[fd].offset, addr, addrlen); + if (ret < 0) ret = -errno; break; } diff --git a/kernel/tasks.c b/kernel/tasks.c index 10f4a50a..53186cbe 100644 --- a/kernel/tasks.c +++ b/kernel/tasks.c @@ -47,8 +47,9 @@ * A task's id will be its position in this array. */ static task_t task_table[MAX_TASKS] = { \ - [0] = {0, TASK_IDLE, 0, 0, 0, NULL, NULL, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0, 0}, \ - [1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, 0, 0, NULL, NULL, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, 0, 0, 0, 0}}; + [0] = {0, TASK_IDLE, 0, 0, 0, NULL, NULL, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, NULL, 0, 0, 0, 0}, \ + [1 ... MAX_TASKS-1] = {0, TASK_INVALID, 0, 0, 0, NULL, NULL, 0, ATOMIC_INIT(0), SPINLOCK_INIT, NULL, SPINLOCK_INIT, NULL, NULL, 0, 0, 0, 0}}; + static spinlock_irqsave_t table_lock = SPINLOCK_IRQSAVE_INIT; #if MAX_CORES > 1 static runqueue_t runqueues[MAX_CORES] = { \ @@ -190,6 +191,10 @@ static void NORETURN do_exit(int arg) { kfree((void*) tmp, sizeof(vma_t)); } + //remove fildes_table + if(!curr_task->fildes_table) + kfree(curr_task->fildes_table, sizeof(fildes_t)*NR_OPEN); + spinlock_unlock(&curr_task->vma_lock); drop_pgd(); // delete page directory and its page tables @@ -320,7 +325,7 @@ create_task_out: int sys_fork(void) { int ret = -ENOMEM; - unsigned int i, core_id; + unsigned int i, core_id, fd_i; task_t* parent_task = per_core(current_task); vma_t** child; vma_t* parent; @@ -364,6 +369,16 @@ int sys_fork(void) tmp = *child; child = &((*child)->next); } + + + /* init fildes_table */ + task_table[i].fildes_table = kmalloc(sizeof(fildes_t)*NR_OPEN); + memset(task_table[i].fildes_table, 0x00, sizeof(fildes_t)*NR_OPEN); + + // copy filedescriptors + for (fd_i = 0; fd_i < NR_OPEN; fd_i++) { + task_table[i].fildes_table[fd_i].node = per_core(current_task)->fildes_table[fd_i].node; + } mailbox_wait_msg_init(&task_table[i].inbox); memset(task_table[i].outbox, 0x00, sizeof(mailbox_wait_msg_t*)*MAX_TASKS); @@ -492,6 +507,12 @@ static int load_task(load_args_t* largs) elf_header_t header; elf_program_header_t prog_header; //elf_section_header_t sec_header; + ///!!! kfree is missing! + fildes_t *file = kmalloc(sizeof(fildes_t)); + file->offset = 0; + file->flags = 0; + + //TODO: init the hole fildes_t struct! vfs_node_t* node; task_t* curr_task = per_core(current_task); int err; @@ -499,16 +520,15 @@ static int load_task(load_args_t* largs) if (!largs) return -EINVAL; - node = largs->node; - if (!node) + file->node = largs->node; + if (!file->node) return -EINVAL; - err = read_fs(node, (uint8_t*)&header, sizeof(elf_header_t), 0); + read_fs(file, (uint8_t*)&header, sizeof(elf_header_t)); if (err < 0) { kprintf("read_fs failed: %d\n", err); return err; } - if (BUILTIN_EXPECT(header.ident.magic != ELF_MAGIC, 0)) goto invalid; @@ -529,7 +549,8 @@ static int load_task(load_args_t* largs) // interpret program header table for (i=0; ioffset = header.ph_offset+i*header.ph_entry_size; + if (read_fs(file, (uint8_t*)&prog_header, sizeof(elf_program_header_t)) == 0) { kprintf("Could not read programm header!\n"); continue; } @@ -562,7 +583,8 @@ static int load_task(load_args_t* largs) curr_task->start_heap = curr_task->end_heap = prog_header.virt_addr+prog_header.mem_size; // load program - read_fs(node, (uint8_t*)prog_header.virt_addr, prog_header.file_size, prog_header.offset); + file->offset = prog_header.offset; + read_fs(file, (uint8_t*)prog_header.virt_addr, prog_header.file_size); flags = VMA_CACHEABLE; if (prog_header.flags & PF_R) @@ -608,7 +630,8 @@ static int load_task(load_args_t* largs) #if 0 // interpret section header table for (i=0; i #include #include -#undef errno -extern int errno; + +/*file descriptor init*/ +#define NR_OPEN 10 +#define FS_INIT { [0 ... NR_OPEN-1] = {NULL, 0, 0} } + +/*open flags*/ + +//#define O_RDONLY 0 +//#define O_WRONLY 1 +#define O_RDWR 2 + +#define O_CREAT 64 +#define O_EXCL 128 +//#define O_NOCTTY 256 +#define O_TRUNC 512 +#define O_APPEND 1024 + int main(int argc, char** argv) { - int i; - const char str[] = "Hello World!!!\n"; - - for(i=0; environ[i]; i++) - printf("environ[%d] = %s\n", i, environ[i]); - for(i=0; i +#include +#include +#include +#include +#include +#include + +void showlogo() { + printf("\n\n"); + printf("================================================================================\n"); + printf(" m(etalsvm)shell\n\n"); + printf("================================================================================\n"); +} + +void help() { + printf("possible commands: \n"); + printf("exit > exit shell \n"); +} + +int main(int argc, char** argv) +{ + char* command = malloc(1024*sizeof(char)); + + int size, status = 0; + pid_t pid; + system("clear"); + showlogo(); + while(1) { + printf("$ "); + size = scanf("%s", command); + if(!strcmp(command, "exit")) { + return 0; + } + if(!strcmp(command, "help")) { + help(); + } else { + pid = fork(); + if (pid == 0) { //child + char* newargv[] = {command, NULL}; + char* newenv[] = {"USER=root", "PATH=/bin:/sbin:/usr/bin", "PWD=/", "TEMP=/tmp", NULL}; + + execve(command, newargv, newenv); + return errno; + } else { + wait(&status); + } + } + } + return errno; +} + diff --git a/newlib/examples/test b/newlib/examples/test new file mode 100644 index 00000000..e7cf92e9 --- /dev/null +++ b/newlib/examples/test @@ -0,0 +1,3 @@ +test +hallo +huso diff --git a/newlib/src/libgloss/metalsvm/lseek.c b/newlib/src/libgloss/metalsvm/lseek.c index f263ad72..bffb4e77 100644 --- a/newlib/src/libgloss/metalsvm/lseek.c +++ b/newlib/src/libgloss/metalsvm/lseek.c @@ -40,12 +40,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; } diff --git a/newlib/src/libgloss/metalsvm/open.c b/newlib/src/libgloss/metalsvm/open.c index 918d2dc9..2081f76f 100644 --- a/newlib/src/libgloss/metalsvm/open.c +++ b/newlib/src/libgloss/metalsvm/open.c @@ -50,7 +50,7 @@ _DEFUN (_open, (file, flags, mode), { int ret; - ret = SYSCALL2(__NR_open, flags, mode); + ret = SYSCALL3(__NR_open, file, flags, mode); if (ret < 0) { errno = -ret; ret = -1; diff --git a/tools/Makefile b/tools/Makefile index b47cc898..ee97610b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -7,7 +7,7 @@ LDFLGAS = DEFINES= NASM = nasm NASMFLAGS = -fbin -EXECFILES = $(shell find ../newlib/examples -perm -u+r+x -type f) +EXECFILES = $(shell find ../newlib/examples -perm -u+r+x -type f) ../newlib/examples/test # other implicit rules %.o : %.c