diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-18 15:15:57 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-18 15:15:57 +0200 |
commit | daa6c2450fa0646619698f0dc01b0456b2541317 (patch) | |
tree | 1065acdd5e1f2c0febafa345e4a36c9a35dbb100 | |
parent | 7d5a38ada35ac196919c26675f211adb995b84ae (diff) | |
download | TCE-daa6c2450fa0646619698f0dc01b0456b2541317.tar.gz TCE-daa6c2450fa0646619698f0dc01b0456b2541317.zip |
Added process arguments when loaded as modules.
-rw-r--r-- | doc/syscalls.txt | 4 | ||||
-rw-r--r-- | menu_cdrom.lst | 4 | ||||
-rw-r--r-- | src/kernel/config.h | 5 | ||||
-rw-r--r-- | src/kernel/core/kmain.cpp | 20 | ||||
-rw-r--r-- | src/kernel/linker/elf.cpp | 4 | ||||
-rw-r--r-- | src/kernel/linker/elf.h | 2 | ||||
-rw-r--r-- | src/kernel/task/task.cpp | 67 | ||||
-rw-r--r-- | src/kernel/task/task.h | 3 | ||||
-rw-r--r-- | src/user/lib/start.c | 6 | ||||
-rw-r--r-- | src/user/test/main.c | 12 |
10 files changed, 96 insertions, 31 deletions
diff --git a/doc/syscalls.txt b/doc/syscalls.txt index 39982c0..833041a 100644 --- a/doc/syscalls.txt +++ b/doc/syscalls.txt @@ -21,6 +21,10 @@ id=eax Name Parameters Description 12 mmap (see linux specs) not implemented 13 munmap (see linux specs) not implemented + 14 run ebx: char* filename spans a new process and run the executable filename + ecx: char** args + 15 waitpid ebx: int pid wait for a process to exit, returns retval. + 20 open ebx: char* filename open a file, returns a descriptor ecx: mode 21 open_relative ebx: root open a file, returns a descriptor diff --git a/menu_cdrom.lst b/menu_cdrom.lst index 1b99614..4728398 100644 --- a/menu_cdrom.lst +++ b/menu_cdrom.lst @@ -2,5 +2,5 @@ timeout 10 title T/CE kernel /kernel.elf -module /test.elf -module /initrd +module /initrd somewhere +module /test.elf arg diff --git a/src/kernel/config.h b/src/kernel/config.h index ffb56d2..21035ba 100644 --- a/src/kernel/config.h +++ b/src/kernel/config.h @@ -2,8 +2,7 @@ #define DEF_CONFIG_H #define K_OS_NAME "T/CE" -#define K_OS_VER "0.1.0" -#define K_OS_CODENAME "Mind Your VFS" - +#define K_OS_VER "0.1.1" +#define K_OS_CODENAME "executify" #endif diff --git a/src/kernel/core/kmain.cpp b/src/kernel/core/kmain.cpp index 58a3c48..96c4050 100644 --- a/src/kernel/core/kmain.cpp +++ b/src/kernel/core/kmain.cpp @@ -80,7 +80,25 @@ extern "C" void kmain(multiboot_info_t* mbd, int32_t magic) { char* cmd = (char*)mods[i].string; *ke_vt << " * " << cmd << " \t"; if (elf_check((uint8_t*)mods[i].mod_start) == 0) { - process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_USER); + + char *args[16] = { cmd, 0 }; + int a = 1; + for (char* c = cmd; c != 0; c++) { + if (*c == ' ') { + *c = 0; + args[a] = c + 1; + a++; + if (a == 15) { + args[a] = 0; + break; + } + } else if (*c == 0) { + args[a] = 0; + break; + } + } + + process *pr = elf_exec((uint8_t*)mods[i].mod_start, PL_USER, args); // todo add args if (pr == 0) { *ke_vt << "Error loading\n"; } else { diff --git a/src/kernel/linker/elf.cpp b/src/kernel/linker/elf.cpp index 0375e40..8fc2e0c 100644 --- a/src/kernel/linker/elf.cpp +++ b/src/kernel/linker/elf.cpp @@ -44,14 +44,14 @@ thread_entry elf_load(uint8_t *data, process* process) { return (thread_entry)ehdr->e_entry; } -process* elf_exec(uint8_t *data, int privilege) { +process* elf_exec(uint8_t *data, int privilege, char** args) { if (elf_check(data)) return 0; process* p = new process(0, 0, privilege); thread_entry e = elf_load(data, p); - new thread(p, e, 0, 0); + new thread(p, e, p->set_args(args), 0); return p; } diff --git a/src/kernel/linker/elf.h b/src/kernel/linker/elf.h index 184f410..12216b7 100644 --- a/src/kernel/linker/elf.h +++ b/src/kernel/linker/elf.h @@ -58,6 +58,6 @@ struct phdr { int elf_check(uint8_t *data); //0 if ok, -1 if not a valid ELF thread_entry elf_load(uint8_t *data, process* process); //Load an ELF to a process, return entry point -process* elf_exec(uint8_t *data, int privilege); //Creates a new process and a thread for running ELF file +process* elf_exec(uint8_t *data, int privilege, char **args); //Creates a new process and a thread for running ELF file #endif diff --git a/src/kernel/task/task.cpp b/src/kernel/task/task.cpp index e513608..1a5d535 100644 --- a/src/kernel/task/task.cpp +++ b/src/kernel/task/task.cpp @@ -340,37 +340,36 @@ static void process_delete(process *pr) { kfree(pr); } -size_t process_sbrk(size_t size) { - 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; +size_t process::sbrk(size_t size) { + if (data == 0) return -1; + ASSERT(data < K_HIGHHALF_ADDR); + if (data + size >= K_HIGHHALF_ADDR) return -1; size_t ret; - if (p->dataseg == 0) { - size_t start = p->data; + if (dataseg == 0) { + size_t start = data; if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000; size_t end = start + size; if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000; segment *s = new simpleseg(start, end - start, 1); if (s == 0) return -5; - p->dataseg = s->map(p->pagedir, 0); - if (p->dataseg == 0) return -1; + dataseg = s->map(pagedir, 0); + if (dataseg == 0) return -1; ret = start; - p->data = start + size; + data = start + size; } else { - size_t start = p->dataseg->start; - size_t end = p->data + size; + size_t start = dataseg->start; + size_t end = data + size; if (end <= start) return -1; if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000; - simpleseg *s = (simpleseg*)(p->dataseg->seg); - s->resize(p->dataseg, end - start); + simpleseg *s = (simpleseg*)(dataseg->seg); + s->resize(dataseg, end - start); - ret = p->data; - p->data += size; + ret = data; + data += size; } /* (DBG) ke_vt->writeStr("(sbrk "); ke_vt->writeHex(size); @@ -380,8 +379,40 @@ size_t process_sbrk(size_t size) { return ret; } +void* process::set_args(char** args) { + if (args == 0) return 0; + + cli(); // we're writing to this process's user space + page_directory *r = current_pagedir; + pagedir_switch(pagedir); + + int len = sizeof(char*), argc = 0; + for (char** a = args; *a != 0; a++) { + len += strlen(*a) + 1 + sizeof(char*); + argc++; + } + + void* p = (void*)sbrk(len); + char** si = (char**)p; + char* s = (char*)p + ((argc + 1) * sizeof(char*)); + for (int i = 0; i < argc; i++) { + si[i] = s; + strcpy(s, args[i]); + s += strlen(args[i]) + 1; + } + si[argc] = 0; + + pagedir_switch(r); + sti(); + + return p; +} + +// syscalls +size_t process_sbrk(size_t size) { + return current_process->sbrk(size); +} void process_brk(size_t ptr) { ASSERT(ptr < K_HIGHHALF_ADDR); - process_sbrk(ptr - current_process->data); + current_process->sbrk(ptr - current_process->data); } - diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index 1c32657..99738b9 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -41,6 +41,9 @@ class process { process() : fd(4, 4) {} // must not be used directly process(process *parent, uint32_t uid, uint32_t privilege); + + void* set_args(char** args); + size_t sbrk(size_t size); }; class thread { diff --git a/src/user/lib/start.c b/src/user/lib/start.c index 3dbb994..2521f97 100644 --- a/src/user/lib/start.c +++ b/src/user/lib/start.c @@ -1,8 +1,8 @@ #include <tce/syscall.h> -extern int main(); +extern int main(char **args); -void start() { - int ret = main(); +void start(char **args) { + int ret = main(args); process_exit(ret); } diff --git a/src/user/test/main.c b/src/user/test/main.c index c98a619..81753bd 100644 --- a/src/user/test/main.c +++ b/src/user/test/main.c @@ -78,7 +78,17 @@ void fprint(FILE f, char *s) { write(f, 0, strlen(s), s); } -int main() { +int main(char** args) { + char**a; + if (args != 0) { + printk("args"); + for (a = args; *a != 0; a++) { + printk(" - "); + printk(*a); + } + printk("\n"); + } + printk("(test app) malloc(42) = "); printk_hex((uint32_t)malloc(42)); printk("\n"); |