summaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/Makefile5
-rw-r--r--src/kernel/config.h4
-rw-r--r--src/kernel/core/kmain.cpp3
-rw-r--r--src/kernel/lib/earray.cpp6
-rw-r--r--src/kernel/lib/earray.h2
-rw-r--r--src/kernel/mem/_dlmalloc.h2
-rw-r--r--src/kernel/mem/mem.h4
-rw-r--r--src/kernel/task/syscall.cpp71
-rw-r--r--src/kernel/task/task.cpp19
-rw-r--r--src/kernel/task/task.h8
-rw-r--r--src/kernel/vfs/node.cpp122
-rw-r--r--src/kernel/vfs/node.h41
-rw-r--r--src/kernel/vfs/vdir.cpp55
-rw-r--r--src/kernel/vfs/vdir.h32
14 files changed, 345 insertions, 29 deletions
diff --git a/src/kernel/Makefile b/src/kernel/Makefile
index 2a18bc8..0537388 100644
--- a/src/kernel/Makefile
+++ b/src/kernel/Makefile
@@ -2,9 +2,10 @@ Out = kernel.elf
Obj = core/loader_.o core/kmain.o core/sys.o \
core/monitor.o task/timer.o \
task/idt.o task/idt_.o task/task.o task/task_.o task/syscall.o task/sched.o \
- lib/bitset.o lib/std.o lib/cpp.o lib/earray.o \
+ lib/bitset.o lib/std.o lib/cpp.o \
mem/mem.o mem/paging.o mem/gdt.o mem/_dlmalloc.o mem/seg.o \
- linker/elf.o
+ linker/elf.o \
+ vfs/node.o vfs/vdir.o
ExtObj = $(SrcPath)/common/_common.o
diff --git a/src/kernel/config.h b/src/kernel/config.h
index 0fb4697..ffb56d2 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -2,8 +2,8 @@
#define DEF_CONFIG_H
#define K_OS_NAME "T/CE"
-#define K_OS_VER "0.0.5"
-#define K_OS_CODENAME "CPLUSPLUS==\\o/"
+#define K_OS_VER "0.1.0"
+#define K_OS_CODENAME "Mind Your VFS"
#endif
diff --git a/src/kernel/core/kmain.cpp b/src/kernel/core/kmain.cpp
index 8b77bcf..eb2c3ec 100644
--- a/src/kernel/core/kmain.cpp
+++ b/src/kernel/core/kmain.cpp
@@ -11,6 +11,7 @@
#include <mem/paging.h>
#include <mem/mem.h>
#include <linker/elf.h>
+#include <vfs/node.h>
/* The kernel's main procedure. This function is called in loader_.asm.
This function calls the initializer functions for all system parts.
@@ -55,6 +56,8 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) {
//kheap_init();
timer_init(30);
tasking_init();
+
+ vfs_setup();
monitor_write("\nLoading modules :\n");
for (i = 0; i < mbd->mods_count; i++) {
diff --git a/src/kernel/lib/earray.cpp b/src/kernel/lib/earray.cpp
index 5760822..3a41f18 100644
--- a/src/kernel/lib/earray.cpp
+++ b/src/kernel/lib/earray.cpp
@@ -1,5 +1,3 @@
-#include "earray.h"
-
#include <mem/mem.h>
#include <core/sys.h>
#include <lib/cpp.h>
@@ -101,7 +99,7 @@ T *earray<T>::at(int num) {
mutex_unlock(&mutex);
return 0;
}
- void* ret = data[i][j];
+ T* ret = data[i][j];
mutex_unlock(&mutex);
return ret;
}
@@ -145,7 +143,7 @@ void earray<T>::set(int num, T* ptr) {
}
}
} else {
- if (data[a] = 0) {
+ if (data[a] == 0) {
data[a] = (T**)kmalloc(vect_len * sizeof(T*));
for (i = 0; i < vect_len; i++) data[a][i] = 0;
}
diff --git a/src/kernel/lib/earray.h b/src/kernel/lib/earray.h
index d3d7a9b..9a43612 100644
--- a/src/kernel/lib/earray.h
+++ b/src/kernel/lib/earray.h
@@ -32,6 +32,6 @@ struct earray {
int count() { return elements; }
};
-
+#include <earray.cpp>
#endif
diff --git a/src/kernel/mem/_dlmalloc.h b/src/kernel/mem/_dlmalloc.h
index a80273c..23682be 100644
--- a/src/kernel/mem/_dlmalloc.h
+++ b/src/kernel/mem/_dlmalloc.h
@@ -12,7 +12,7 @@
#define LACKS_SYS_PARAM_H
#define LACKS_STDLIB_H
-#define USE_DL_PREFIX
+// #define USE_DL_PREFIX
#define USE_LOCKS 2
diff --git a/src/kernel/mem/mem.h b/src/kernel/mem/mem.h
index 085d9ce..4201983 100644
--- a/src/kernel/mem/mem.h
+++ b/src/kernel/mem/mem.h
@@ -14,8 +14,8 @@ void kfree_page(void* page);
extern "C" void* ksbrk(size_t size);
extern "C" void kbrk(void* ptr);
-#define kmalloc dlmalloc
-#define kfree dlfree
+#define kmalloc malloc
+#define kfree free
extern bool _no_more_ksbrk;
extern size_t mem_placementAddr;
diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp
index 678677d..797c5db 100644
--- a/src/kernel/task/syscall.cpp
+++ b/src/kernel/task/syscall.cpp
@@ -3,6 +3,7 @@
#include "timer.h"
#include <core/monitor.h>
#include <core/sys.h>
+#include <vfs/node.h>
#define CALL0(name, scname) static void scname(registers* r) { r->eax = name(); }
#define CALL1(name, scname) static void scname(registers* r) { \
@@ -11,6 +12,8 @@
r->eax = name(r->ebx, r->ecx); }
#define CALL3(name, scname) static void scname(registers* r) { \
r->eax = name(r->ebx, r->ecx, r->edx); }
+#define CALL4(name, scname) static void scname(registers* r) { \
+ r->eax = name(r->ebx, r->ecx, r->edx, r->esi); }
#define CALL0V(name, scname) static void scname(registers* r) { name(); }
#define CALL1V(name, scname) static void scname(registers* r) { name(r->ebx); }
#define CALL2V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx); }
@@ -26,29 +29,83 @@ CALL0(proc_priv, proc_priv_sc);
CALL1(process_sbrk, proc_sbrk_sc);
CALL1V(process_brk, proc_brk_sc);
+CALL1V(close, close_sc);
+
static void printk_sc(registers *r) {
monitor_write((char*)r->ebx);
}
static void thread_new_sc(registers* r) {
cli();
- new thread(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx);
+ new thread(current_process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx);
sti();
}
+static void open_sc(registers *r) {
+ r->eax = open((char*)r->ebx, r->ecx);
+}
+
+static void open_relative_sc(registers *r) {
+ r->eax = open_relative(r->ebx, (char*)r->ecx, r->edx);
+}
+
+static void stat_sc(registers *r) {
+ r->eax = stat((char*)r->ebx, (file_info*)r->ecx);
+}
+
+static void stat_relative_sc(registers *r) {
+ r->eax = stat_relative(r->ebx, (char*)r->ecx, (file_info*)r->edx);
+}
+
+static void statf_sc(registers *r) {
+ r->eax = statf(r->ebx, (file_info*)r->ecx);
+}
+
+static void read_sc(registers *r) {
+ r->eax = read(r->ebx, r->ecx, r->edx, (char*)r->esi);
+}
+
+static void write_sc(registers *r) {
+ r->eax = write(r->ebx, r->ecx, r->edx, (char*)r->esi);
+}
+
+static void link_sc(registers *r) {
+ r->eax = link((char*)r->ebx, (char*)r->ecx, r->edx);
+}
+
+
int_callback syscalls[NUMBER_OF_SYSCALLS] = { // This must correspond to common/include/tce/syscalls.h
- 0,
- thread_exit_sc, //0
+ 0, // 0
+ thread_exit_sc,
schedule_sc,
thread_sleep_sc,
process_exit_sc,
- printk_sc,
- thread_new_sc, //5
+ printk_sc, //5
+ thread_new_sc,
irq_wait_sc,
proc_priv_sc,
- proc_sbrk_sc,
+ 0,
+ proc_sbrk_sc, //10
proc_brk_sc,
- 0 };
+ 0,
+ 0,
+ 0,
+ 0, //15
+ 0,
+ 0,
+ 0,
+ 0,
+ open_sc, //20
+ open_relative_sc,
+ stat_sc,
+ stat_relative_sc,
+ statf_sc,
+ close_sc, //25
+ read_sc,
+ write_sc,
+ link_sc,
+ 0
+ };
/* Called in idt_.asm on a system call (interrupt 64).
diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp
index 92820f9..3998bfe 100644
--- a/src/kernel/task/task.cpp
+++ b/src/kernel/task/task.cpp
@@ -20,7 +20,7 @@ extern "C" uint32_t read_eip();
extern "C" void task_idle(void*);
static uint32_t nextpid = 1;
-process *processes = 0, *kernel_process;
+process *processes = 0, *kernel_process = 0, *current_process = 0;
thread *current_thread = 0, *idle_thread = 0;
uint32_t tasking_tmpStack[KSTACKSIZE];
@@ -78,8 +78,9 @@ void schedule() {
current_thread = sched_dequeue();
ASSERT(current_thread != 0);
+ current_process = current_thread->process;
- pagedir_switch(current_thread->process->pagedir);
+ pagedir_switch(current_process->pagedir);
gdt_setKernelStack(((uint32_t)current_thread->kernelStack_addr) + current_thread->kernelStack_size);
@@ -135,8 +136,8 @@ void thread::wakeUp() {
/* Returns the privilege level of the current process. */
int proc_priv() {
- if (current_thread == 0 || current_thread->process == 0) return PL_UNKNOWN;
- return current_thread->process->privilege;
+ if (current_thread == 0 || current_process == 0) return PL_UNKNOWN;
+ return current_process->privilege;
}
/* For internal use only. Called by thread_exit_stackJmp on a stack that will not be deleted.
@@ -272,7 +273,7 @@ thread::thread(class process *proc, thread_entry entry_point, void *data, void *
}
/* Creates a new process. Creates a struct process and fills it up. */
-process::process(process* _parent, uint32_t _uid, uint32_t _privilege) {
+process::process(process* _parent, uint32_t _uid, uint32_t _privilege) : fd(12, 64) {
pid = (nextpid++);
uid = _uid;
thread_count = 0;
@@ -284,6 +285,8 @@ process::process(process* _parent, uint32_t _uid, uint32_t _privilege) {
data = 0;
dataseg = 0;
+ fd.add((node*)-1); // descriptor #0 must not be used
+
stack = 0;
if (privilege >= PL_USER) { //We are running in user mode
size_t stacksBottom = K_HIGHHALF_ADDR - 0x01000000;
@@ -338,7 +341,7 @@ static void process_delete(process *pr) {
}
size_t process_sbrk(size_t size) {
- process *p = current_thread->process;
+ process *p = current_process;
if (p->data == 0) return -1;
ASSERT(p->data < K_HIGHHALF_ADDR);
if (p->data + size >= K_HIGHHALF_ADDR) return -1;
@@ -378,9 +381,7 @@ size_t process_sbrk(size_t size) {
}
void process_brk(size_t ptr) {
- process *p = current_thread->process;
-
ASSERT(ptr < K_HIGHHALF_ADDR);
- process_sbrk(ptr - p->data);
+ process_sbrk(ptr - current_process->data);
}
diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h
index 301f8be..1c32657 100644
--- a/src/kernel/task/task.h
+++ b/src/kernel/task/task.h
@@ -5,6 +5,8 @@
#include <mem/paging.h>
#include "idt.h"
+#include <lib/earray.h>
+
#define TS_RUNNING 0
#define TS_WAKEWAIT 2 //Waiting to be waked up by something precise (thread currently blocked)
@@ -21,6 +23,7 @@
typedef void (*thread_entry)(void*);
class thread;
+class node;
class process {
public:
@@ -34,7 +37,9 @@ class process {
process *next; //Forms a linked list
thread *threads;
- process() {} // must not be used directly
+ earray<node> fd; // file descriptors
+
+ process() : fd(4, 4) {} // must not be used directly
process(process *parent, uint32_t uid, uint32_t privilege);
};
@@ -55,6 +60,7 @@ class thread {
};
extern thread *current_thread;
+extern process *current_process;
void tasking_init();
#ifdef __cplusplus
diff --git a/src/kernel/vfs/node.cpp b/src/kernel/vfs/node.cpp
new file mode 100644
index 0000000..9900a3c
--- /dev/null
+++ b/src/kernel/vfs/node.cpp
@@ -0,0 +1,122 @@
+#include "node.h"
+#include "vdir.h"
+#include <core/monitor.h>
+
+int node::open(process *proc, int mode) {
+ //TODO : permission checks
+ return 0; // ok
+}
+
+int node::stat(file_info *info) {
+ info->type = type;
+ info->dev_type = dev_type;
+ info->mode = mode;
+ info->uid = uid;
+ info->gid = gid;
+ info->size = this->get_size();
+ return 0;
+}
+
+node *root = 0;
+
+void vfs_setup() {
+ root = new vdir(0);
+ root->add_child(".dev", new vdir(root));
+
+ monitor_write("[VFS] ");
+}
+
+node* vfs_find(node* root, char* path) {
+ node* el = root;
+ char *member = path;
+
+ while (*path != 0 && el != 0) {
+ if (*path == '/') {
+ if (member == path) {
+ member++;
+ path++;
+ } else {
+ *path = 0;
+ el = el->get_child(member);
+ path++;
+ member = path;
+ }
+ } else {
+ path++;
+ }
+ }
+ if (el != 0 && member != path) {
+ el = el->get_child(member);
+ }
+
+ return el;
+}
+
+node* vfs_read_fd(FILE d) {
+ return current_process->fd.at(d);
+}
+
+// Syscalls
+
+static FILE i_open(node* r, char* filename, int mode) {
+ node* f = vfs_find(r, filename);
+ if (f == 0) return E_NOT_FOUND;
+ //TODO : different actions depending on open mode
+ int e = f->open(current_process, mode);
+ if (e != 0) return e;
+ return current_process->fd.add(f);
+}
+
+FILE open(char* filename, int mode) {
+ return i_open(root, filename, mode);
+}
+
+FILE open_relative(FILE root, char* filename, int mode) {
+ node* n = vfs_read_fd(root);
+ if (n == 0) return E_INVALID_FD;
+ return i_open(n, filename, mode);
+}
+
+int stat(char* filename, file_info *info) {
+ node *f = vfs_find(root, filename);
+ if (f == 0) return E_NOT_FOUND;
+ return f->stat(info);
+}
+
+int stat_relative(FILE root, char* filename, file_info *info) {
+ node *r = vfs_read_fd(root);
+ if (r == 0) return E_INVALID_FD;
+ node *f = vfs_find(r, filename);
+ if (f == 0) return E_NOT_FOUND;
+ return f->stat(info);
+}
+
+int statf(FILE file, file_info *info) {
+ node *f = vfs_read_fd(file);
+ if (f == 0) return E_INVALID_FD;
+ return f->stat(info);
+}
+
+void close(FILE file) {
+ node *f = vfs_read_fd(file);
+ if (f != 0) {
+ f->close(current_process);
+ current_process->fd.set(file, 0);
+ }
+}
+
+int read(FILE file, size_t offset, size_t len, char* buffer) {
+ node *f = vfs_read_fd(file);
+ if (f == 0) return E_INVALID_FD;
+ return f->read(offset, len, buffer);
+}
+
+int write(FILE file, size_t offset, size_t len, char* buffer) {
+ node *f = vfs_read_fd(file);
+ if (f == 0) return E_INVALID_FD;
+ return f->write(offset, len, buffer);
+}
+
+int link(char* from, char* to, int mode) {
+ return E_NOT_IMPLEMENTED;
+}
diff --git a/src/kernel/vfs/node.h b/src/kernel/vfs/node.h
new file mode 100644
index 0000000..2d16dab
--- /dev/null
+++ b/src/kernel/vfs/node.h
@@ -0,0 +1,41 @@
+#ifndef DEF_VFS_NODE_H
+#define DEF_VFS_NODE_H
+
+#include <tce/vfs.h>
+#include <tce/syscalls.h>
+
+#include <task/task.h>
+
+class node {
+ public:
+ node* parent;
+ int type, dev_type;
+ int mode, uid, gid;
+
+ node(node* p, int t) : parent(p), type(t) {}
+
+ virtual int open(process *proc, int mode);
+ virtual void close(process *proc) {}
+ virtual int read(size_t offset, size_t len, char *buffer) { return E_NOT_IMPLEMENTED; }
+ virtual int write(size_t offset, size_t len, char* buffer) { return E_NOT_IMPLEMENTED; }
+ int stat(file_info *info);
+ virtual node* get_child(char* name) { return 0; }
+ virtual int add_child(char* name, node *child) { return E_NOT_IMPLEMENTED; }
+ virtual size_t get_size() { return 0; }
+};
+
+void vfs_setup();
+node* vfs_find(node* root, char* filename);
+
+// syscall interface
+FILE open(char* filename, int mode);
+FILE open_relative(FILE root, char* filename, int mode);
+int stat(char* filename, file_info *info);
+int stat_relative(FILE root, char* filename, file_info *info);
+int statf(FILE file, file_info *info);
+void close(FILE file);
+int read(FILE file, size_t offset, size_t len, char *buffer);
+int write(FILE file, size_t offset, size_t len, char *buffer);
+int link(char* from, char* to, int mode);
+
+#endif
diff --git a/src/kernel/vfs/vdir.cpp b/src/kernel/vfs/vdir.cpp
new file mode 100644
index 0000000..299c0e7
--- /dev/null
+++ b/src/kernel/vfs/vdir.cpp
@@ -0,0 +1,55 @@
+#include "vdir.h"
+
+vdir::vdir(node* parent) : node(parent, FT_DIR), children(8, 64) {
+ children.add(new vdir_child(".", this));
+ child_count = 1;
+
+ if (parent != 0) {
+ children.add(new vdir_child("..", parent));
+ child_count++;
+ }
+}
+
+node* vdir::get_child(char* name) {
+ for (unsigned i = 0; i < child_count; i++) {
+ vdir_child *c = children.at(i);
+ ASSERT(c != 0);
+ if (strcmp(c->name, name) == 0) return c->el;
+ }
+ return 0;
+}
+
+int vdir::read(size_t offset, size_t len, char* buffer) {
+ if (offset >= child_count) return 0;
+ vdir_child *c = children.at(offset);
+ ASSERT(c != 0);
+ size_t nlen = strlen(c->name);
+ if (len <= nlen) {
+ return E_TOO_SHORT;
+ }
+ strcpy(buffer, c->name);
+ return nlen;
+}
+
+int vdir::write(size_t offset, size_t len, char* buffer) {
+ // rename file
+ if (offset >= child_count) return E_INVALID_RANGE;
+ vdir_child *c = children.at(offset);
+ ASSERT(c != 0);
+ if (len == 0) return E_INVALID;
+ kfree(c->name);
+ c->name = (char*)kmalloc(len + 1);
+ for (unsigned i = 0; i < len; i++) c->name[i] = buffer[i];
+ c->name[len] = 0;
+ return len;
+}
+
+size_t vdir::get_size() {
+ return child_count;
+}
+
+int vdir::add_child(char* name, node *child) {
+ ASSERT((int)child_count == children.add(new vdir_child(name, child)));
+ child_count++;
+ return 0;
+}
diff --git a/src/kernel/vfs/vdir.h b/src/kernel/vfs/vdir.h
new file mode 100644
index 0000000..9595409
--- /dev/null
+++ b/src/kernel/vfs/vdir.h
@@ -0,0 +1,32 @@
+#ifndef DEF_VFS_VDIR_H
+#define DEF_VFS_VDIR_H
+
+#include "node.h"
+#include <lib/earray.h>
+#include <string.h>
+
+struct vdir_child {
+ char* name;
+ node *el;
+
+ vdir_child(char* na, node* nd) : el(nd) {
+ name = strdup(na);
+ }
+};
+
+class vdir : public node {
+ earray<vdir_child> children;
+ size_t child_count;
+
+ public:
+ vdir(node* parent);
+
+ virtual int read(size_t offset, size_t len, char* buffer);
+ virtual int write(size_t offset, size_t len, char* buffer); // rename file
+ virtual node* get_child(char* name);
+ virtual int add_child(char* name, node *child);
+ virtual size_t get_size();
+};
+
+#endif
+