Merge remote-tracking branch 'origin/ohligs'

This commit is contained in:
Stefan Lankes 2011-09-15 20:48:16 +02:00
commit 89eeef276b
22 changed files with 1087 additions and 178 deletions

6
.gitignore vendored
View file

@ -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/*

View file

@ -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

View file

@ -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

View file

@ -17,13 +17,26 @@
* This file is part of MetalSVM.
*/
#include <metalsvm/stdlib.h>
#include <metalsvm/stdio.h>
#include <metalsvm/string.h>
#include <metalsvm/tasks.h>
#include <asm/kb.h>
#include <asm/irq.h>
#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();
}
}
}
}

View file

@ -1,4 +1,5 @@
C_source := null.c
C_source := stdio.c socket.c
MODULE := drivers_char
include $(TOPDIR)/Makefile.inc

65
drivers/char/null.c → drivers/char/socket.c Normal file → Executable file
View file

@ -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 <metalsvm/stdio.h>
#include <metalsvm/errno.h>
#include <metalsvm/fs.h>
#include <metalsvm/spinlock.h>
#include <lwip/opt.h>
/* Implementation of a simple null device */
#if defined(CONFIG_LWIP) && LWIP_SOCKET
#include <lwip/mem.h>
#include <lwip/raw.h>
#include <lwip/icmp.h>
#include <lwip/netif.h>
#include <lwip/sys.h>
#include <lwip/timers.h>
#include <lwip/inet_chksum.h>
#include <lwip/ip.h>
#include <lwip/sockets.h>
#include <lwip/inet.h>
#include <lwip/err.h>
#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;

325
drivers/char/stdio.c Normal file
View file

@ -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 <metalsvm/stdlib.h>
#include <metalsvm/string.h>
#include <metalsvm/stdio.h>
#include <metalsvm/errno.h>
#include <metalsvm/fs.h>
#include <asm/kb.h>
#include <metalsvm/tasks.h>
#include <metalsvm/spinlock.h>
/* 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; i<size; i++, buffer++) {
kputchar(*buffer);
}
file->offset += 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; i<MAX_DATABLOCKS; i++) {
if (blist->data[i]) {
blockdir = (dir_block_t*) blist->data[i];
for(j=0; j<MAX_DIRENTRIES; j++) {
dirent = &blockdir->entries[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; i<MAX_DATABLOCKS; i++) {
if (blist->data[i]) {
blockdir = (dir_block_t*) blist->data[i];
for(j=0; j<MAX_DIRENTRIES; j++) {
dirent = &blockdir->entries[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; i<MAX_DATABLOCKS; i++) {
if (blist->data[i]) {
blockdir = (dir_block_t*) blist->data[i];
for(j=0; j<MAX_DIRENTRIES; j++) {
dirent = &blockdir->entries[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; i<MAX_DATABLOCKS; i++) {
if (blist->data[i]) {
blockdir = (dir_block_t*) blist->data[i];
for(j=0; j<MAX_DIRENTRIES; j++) {
dirent = &blockdir->entries[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;
}

73
fs/fs.c
View file

@ -17,15 +17,18 @@
* This file is part of MetalSVM.
*/
#include <metalsvm/stdlib.h>
#include <metalsvm/stdio.h>
#include <metalsvm/string.h>
#include <metalsvm/fs.h>
#include <metalsvm/errno.h>
#include <metalsvm/spinlock.h>
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;
}

View file

@ -23,7 +23,10 @@
#include <metalsvm/fs.h>
#include <metalsvm/errno.h>
#include <asm/multiboot.h>
#include <metalsvm/spinlock.h>
#include <asm/processor.h>
#include <metalsvm/spinlock.h>
#ifdef CONFIG_ROCKCREEK
#include <asm/icc.h>
#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; i<MAX_DATABLOCKS && !data; i++) {
if (blist->data[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; i<MAX_DATABLOCKS && !data; i++) {
if (blist->data[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; i<MAX_DATABLOCKS && !data; i++) {
if (blist->data[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; i<MAX_DATABLOCKS; i++) {
if (blist->data[i]) {
dir_block = (dir_block_t*) blist->data[i];
for(j=0; j<MAX_DIRENTRIES; j++) {
dirent = &dir_block->entries[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);

View file

@ -27,7 +27,7 @@
#define __FS_H__
#include <metalsvm/stddef.h>
#include <metalsvm/spinlock.h>
#include <metalsvm/spinlock_types.h>
#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

View file

@ -32,6 +32,7 @@
#include <metalsvm/stddef.h>
#include <metalsvm/vma.h>
#include <metalsvm/spinlock_types.h>
#include <metalsvm/fs.h>
#include <metalsvm/mailbox_types.h>
#include <asm/tasks_types.h>
#include <asm/atomic.h>
@ -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

View file

@ -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; j<depth; j++)
@ -188,8 +192,12 @@ static void list_fs(vfs_node_t* node, uint32_t depth)
if (new_node) {
if (new_node->type == 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<depth+1; j++)
kputs(" ");
kprintf("content: %s\n", buff);
@ -199,6 +207,7 @@ static void list_fs(vfs_node_t* node, uint32_t depth)
i++;
}
kfree(file, sizeof(fildes_t));
}
static void list_root(void) {

View file

@ -21,6 +21,7 @@
#include <metalsvm/stdio.h>
#include <metalsvm/syscall.h>
#include <metalsvm/tasks.h>
#include <metalsvm/string.h>
#include <metalsvm/errno.h>
#include <metalsvm/spinlock.h>
#include <metalsvm/time.h>
@ -39,25 +40,131 @@
#include <lwip/inet.h>
#include <lwip/err.h>
/*
* 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; i<len; i++, buf++) {
kputchar(*buf);
file = &(per_core(current_task)->fildes_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;
}

View file

@ -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; i<header.ph_entry_count; i++) {
if (read_fs(node, (uint8_t*)&prog_header, sizeof(elf_program_header_t), header.ph_offset+i*header.ph_entry_size) == 0) {
file->offset = 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<header.sh_entry_count; i++) {
if (read_fs(node, (uint8_t*)&sec_header, sizeof(elf_section_header_t), header.sh_offset+i*header.sh_entry_size) == 0) {
file.offset = header.sh_offset+i*header.sh_entry_size;
if (read_fs(&file, (uint8_t*)&sec_header, sizeof(elf_section_header_t)) == 0) {
kprintf("Could not read section header!\n");
continue;
}
@ -716,7 +739,7 @@ static int STDCALL user_entry(void* arg)
int create_user_task(tid_t* id, const char* fname, char** argv)
{
vfs_node_t* node;
int argc = 0;
int argc = 0, ret = 0;
size_t i, buffer_size = 0;
load_args_t* load_args = NULL;
char *dest, *src;
@ -750,7 +773,25 @@ int create_user_task(tid_t* id, const char* fname, char** argv)
while ((*dest++ = *src++) != 0);
}
return create_task(id, user_entry, load_args, NORMAL_PRIO);
/*
* if 'tid_t' id is not initalized, create_task will not set 'tid_t id'
* We need the tid to initalize the fildes, thus we have to check this
*/
if (!id)
id = kmalloc(sizeof(tid_t));
/* == === create new task === == */
ret = create_task(id, user_entry, load_args, NORMAL_PRIO);
/* init fildes_table */
task_table[*id].fildes_table = kmalloc(sizeof(fildes_t)*NR_OPEN);
memset(task_table[*id].fildes_table, 0x00, sizeof(fildes_t)*NR_OPEN);
task_table[*id].fildes_table[0].node = findnode_fs("/dev/stdin");
task_table[*id].fildes_table[1].node = findnode_fs("/dev/stdout");
task_table[*id].fildes_table[2].node = findnode_fs("/dev/stderr");
return ret;
}
/** @brief Used by the execve-Systemcall */

View file

@ -404,13 +404,14 @@ void* client_task(void* e)
int test_init(void)
{
char* argv[] = {"/bin/tests", NULL};
char* server_argv[] = {"/bin/server", "6789", NULL};
char* client_argv[] = {"/bin/client", "127.0.0.1", "6789", NULL};
char* argv[] = {"/bin/mshell", NULL};
// char* argv[] = {"/bin/tests", NULL};
// char* server_argv[] = {"/bin/server", "6789", NULL};
// char* client_argv[] = {"/bin/client", "127.0.0.1", "6789", NULL};
sem_init(&producing, 1);
sem_init(&consuming, 0);
mailbox_int32_init(&mbox);
//sem_init(&producing, 1);
//sem_init(&consuming, 0);
//mailbox_int32_init(&mbox);
#if defined(CONFIG_LWIP) && defined(CONFIG_ROCKCREEK)
@ -425,16 +426,16 @@ int test_init(void)
// create_kernel_task(NULL,client_task,NULL);
#endif
create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, foo, "Hello from foo1", NORMAL_PRIO);
//create_kernel_task(NULL, join_test, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, producer, , NORMAL_PRIO);
//create_kernel_task(NULL, consumer, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, mail_ping, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, mail_noise, NULL, NORMAL_PRIO);
//create_kernel_task(NULL, svm_test, NULL, NORMAL_PRIO);
//create_user_task(NULL, "/bin/hello", argv);
create_user_task(NULL, "/bin/tests", argv);
//create_user_task(NULL, "/bin/jacobi", argv);
create_user_task(NULL, "/bin/mshell", argv);
//create_user_task(NULL, "/bin/jacobi", argv);
//create_user_task(NULL, "/bin/server", server_argv);
//sleep(5);

View file

@ -11,7 +11,7 @@ LDFLAGS =
default: all
all: hello tests jacobi server client
all: hello tests jacobi mshell server client
jacobi: jacobi.o
$(CC_FOR_TARGET) -T link.ld -o $@ $(LDFLAGS) $< -lm
@ -31,6 +31,12 @@ hello: hello.o
$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
chmod a-x $@.sym
mshell: mshell.o
$(CC_FOR_TARGET) -T link.ld -o $@ $(LDFLAGS) $<
$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym
$(OBJCOPY_FOR_TARGET) $(STRIP_DEBUG) $@
chmod a-x $@.sym
server: server.o
$(CC_FOR_TARGET) -T link.ld -o $@ $(LDFLAGS) $< -lsocket
$(OBJCOPY_FOR_TARGET) $(KEEP_DEBUG) $@ $@.sym

View file

@ -22,22 +22,33 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
#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<argc; i++)
printf("argv[%d] = %s\n", i, argv[i]);
write(1, str, strlen(str));
printf("Hello from printf!!!\n");
char* teststr = malloc(sizeof(char)*100);
int testfile = open("/bin/test2", O_CREAT | O_EXCL, "wr");
write(testfile, "hello in new file '/bin/test2'", 30);
lseek(testfile, 0, SEEK_SET);
read(testfile, teststr, 100);
close(testfile);
printf("Gelesen aus neuer Datei: %s", teststr);
return errno;
}

57
newlib/examples/mshell.c Normal file
View file

@ -0,0 +1,57 @@
/*
* Copyright 2011 Marian Ohligs, Chair for Operating Systems,
* RWTH Aachen University
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
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;
}

3
newlib/examples/test Normal file
View file

@ -0,0 +1,3 @@
test
hallo
huso

View file

@ -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;
}

View file

@ -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;

View file

@ -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