From 1d8891c7df337d192b57a78e084c5d1b6ddf0838 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Janosch=20Gr=C3=A4f?= Date: Sun, 5 Apr 2009 18:20:01 +0200 Subject: [PATCH] kernel: ~Stack can grow now (upto 4MB) *: ~Many fixes --- apps/Makefile | 2 + apps/include/proc.h | 9 +- apps/include/setjmp.h | 2 +- apps/include/unistd.h | 9 +- apps/init/Makefile | 17 +-- apps/{test/test.c => init/exe.c} | 59 ++++---- apps/init/exe_elf.c | 44 ++---- apps/init/exe_elf.h | 5 +- apps/init/grub.c | 125 +++++++++++++++++ apps/{test/test.c => init/init.c} | 56 ++++---- apps/init/init.conf.h | 34 ----- apps/{test/test.c => init/init.h} | 72 +++++----- apps/init/init2.c | 116 ++++++++++------ apps/init/init_ramdisk.c | 33 ----- apps/init/{init.c => proc.c} | 140 ++----------------- apps/init/procfs.c | 282 ++++++++++++++++++++++++++++++++++++++ apps/lib/crt0/crt0.c | 44 ------ apps/lib/libavl/Makefile | 72 ++++------ apps/lib/libcdi/Makefile | 66 ++++----- apps/lib/libcdi/fs.c | 1 + apps/lib/libcrypt/Makefile | 12 +- apps/lib/libfuse/Makefile | 72 ++++------ apps/lib/libm/Makefile | 3 +- apps/lib/libmeinos/Makefile | 104 ++++++-------- apps/lib/libmeinos/rpc.c | 9 +- apps/lib/readline/Makefile | 6 +- apps/lib/zlib/Makefile | 71 ++++------ apps/ramdisk/dir.c | 1 - apps/ramdisk/init.c | 1 - apps/rc/Makefile | 24 ++++ apps/rc/boot.c | 89 ++++++++++++ apps/rc/helper.c | 73 ++++++++++ apps/{test/test.c => rc/helper.h} | 53 +++---- apps/rc/rc.c | 112 +++++++++++++++ apps/rc/runlevel.c | 1 + apps/test/test.c | 9 +- files/etc/init.d/com | 10 ++ files/etc/init.d/dma | 2 + files/etc/init.d/pci | 2 + files/etc/init.d/psdev | 2 + files/etc/init.d/ramdisk | 4 + files/etc/init.d/vterm | 1 + files/etc/inittab | 23 ++++ files/etc/keyboard_layouts/IGNORE | 1 + files/grub/menu.lst | 4 +- files/var/db/IGNORE | 1 + files/var/run/utmp | 1 + files/var/tmp/IGNORE | 1 + include/syscalls.h | 30 ++-- kernel2/Makefile | 197 +++++++++----------------- kernel2/include/memmap.h | 3 + kernel2/include/memuser.h | 1 + kernel2/include/procm.h | 2 + kernel2/memuser.c | 85 +++++++----- kernel2/procm.c | 39 +++++- run_stacktrace.sh | 3 +- 56 files changed, 1311 insertions(+), 929 deletions(-) copy apps/{test/test.c => init/exe.c} (56%) create mode 100644 apps/init/grub.c copy apps/{test/test.c => init/init.c} (56%) mode change 100644 => 100755 delete mode 100644 apps/init/init.conf.h copy apps/{test/test.c => init/init.h} (53%) delete mode 100644 apps/init/init_ramdisk.c rename apps/init/{init.c => proc.c} (51%) mode change 100755 => 100644 create mode 100644 apps/init/procfs.c rewrite apps/lib/libavl/Makefile (61%) rewrite apps/lib/libcdi/Makefile (62%) rewrite apps/lib/libfuse/Makefile (62%) rewrite apps/lib/libmeinos/Makefile (68%) rewrite apps/lib/zlib/Makefile (61%) create mode 100644 apps/rc/Makefile create mode 100644 apps/rc/boot.c create mode 100644 apps/rc/helper.c copy apps/{test/test.c => rc/helper.h} (54%) create mode 100644 apps/rc/rc.c create mode 100644 apps/rc/runlevel.c create mode 100644 files/etc/init.d/com create mode 100644 files/etc/init.d/dma create mode 100644 files/etc/init.d/pci create mode 100644 files/etc/init.d/psdev create mode 100644 files/etc/init.d/ramdisk create mode 100644 files/etc/init.d/vterm create mode 100644 files/etc/inittab create mode 100644 files/etc/keyboard_layouts/IGNORE create mode 100644 files/var/db/IGNORE create mode 100644 files/var/run/utmp create mode 100644 files/var/tmp/IGNORE rewrite kernel2/Makefile (69%) diff --git a/apps/Makefile b/apps/Makefile index 66ea19f..9f43c4c 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -30,6 +30,7 @@ all_apps: clean_apps # HACK! make -C utils/ make -C cirrus/ make -C fat/ + make -C rc/ #make -C joystick/ #make -C ext2/ @@ -60,6 +61,7 @@ clean_apps: make -C utils/ clean make -C cirrus/ clean make -C fat/ clean + make -C rc/ clean #make -C joystick/ clean #make -C ext2/ clean diff --git a/apps/include/proc.h b/apps/include/proc.h index 6b2d217..3a9aec4 100644 --- a/apps/include/proc.h +++ b/apps/include/proc.h @@ -22,7 +22,6 @@ #include #include #include -#include #define getchild(i) getchildbypid(getpid(),i) @@ -110,6 +109,14 @@ static __inline__ pid_t getchildbypid(pid_t pid,size_t i) { return syscall_call(SYSCALL_PROC_GETCHILD,2,pid,i); } +static __inline__ int *proc_getstack(pid_t pid) { + return (int*)syscall_call(SYSCALL_PROC_GETSTACK,1,pid); +} + +static __inline__ int proc_setstack(pid_t pid,int *stack) { + syscall_call(SYSCALL_PROC_GETSTACK,2,pid,stack); +} + char *getname(pid_t pid); void **proc_mempagelist(pid_t pid,size_t *_num_pages); int proc_pack_procdata(char **argv,char **env,char *cwd,mode_t cmask); diff --git a/apps/include/setjmp.h b/apps/include/setjmp.h index 3bf92be..ecd1679 100644 --- a/apps/include/setjmp.h +++ b/apps/include/setjmp.h @@ -24,7 +24,7 @@ #define siglongjmp(env,val) longjmp(env,val) #define _longjmp(env,val) longjmp(env,val) -typedef void** jmp_buf; +typedef int jmp_buf[6]; typedef jmp_buf sigjmp_buf; int setjmp(jmp_buf env); diff --git a/apps/include/unistd.h b/apps/include/unistd.h index 140c31f..b9297f9 100644 --- a/apps/include/unistd.h +++ b/apps/include/unistd.h @@ -42,8 +42,6 @@ #define STDERR_FILENO 2 #define _exit(r) _Exit(r) -#define getpid() syscall_call(SYSCALL_PROC_GETPID,0) -#define getppid() getppidbypid(getpid()) #define dup(fildes) dup2(fildes,0) @@ -136,4 +134,11 @@ static __inline__ setregid(gid_t rgid,gid_t egid) { syscall_call(SYSCALL_PROC_SETGID,2,2,egid); } +static __inline__ pid_t getpid(void) { + return syscall_call(SYSCALL_PROC_GETPID,0); +} +static __inline__ pid_t getppid(void) { + getppidbypid(getpid()); +} + #endif diff --git a/apps/init/Makefile b/apps/init/Makefile index 79fc3d9..b6fa597 100644 --- a/apps/init/Makefile +++ b/apps/init/Makefile @@ -1,6 +1,6 @@ -include ../../Makefile.config -all: all_init all_init2 all_init_ramdisk +all: all_init all_init2 all_init: init init.objdump cp $< ../../files/bin @@ -8,26 +8,17 @@ all_init: init init.objdump all_init2: init2 init2.objdump cp $< ../../files/bin -all_init_ramdisk: init_ramdisk init_ramdisk.objdump - cp $< ../../files/bin - -init: init.c exe_elf.c - $(APPS_CC) -o $@ $^ +init: init.c grub.c proc.c procfs.c exe.c exe_elf.c + $(APPS_CC) -o $@ $^ -lfuse init2: init2.c $(APPS_CC) -o $@ $^ -init_ramdisk: init_ramdisk.c - $(APPS_CC) -o $@ $^ - init.objdump: init $(APPS_OBJDUMP) -d -S $^ > $@ init2.objdump: init2 $(APPS_OBJDUMP) -d -S $^ > $@ -init_ramdisk.objdump: init_ramdisk - $(APPS_OBJDUMP) -d -S $^ > $@ - clean: - rm -f init init2 init_ramdisk *.objdump + rm -f init init2 *.objdump diff --git a/apps/test/test.c b/apps/init/exe.c similarity index 56% copy from apps/test/test.c copy to apps/init/exe.c index a19c2de..bbcc4d3 100644 --- a/apps/test/test.c +++ b/apps/init/exe.c @@ -14,41 +14,36 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . -*/ +*/ #include -#include -#include -#include -#include - -int main() { - pid_t child; -dbgmsg("test: Hello World\n"); -while (1); - int p[2]; - if (pipe(p)==0) { - dbgmsg("p[0] = %d\n",p[0]); - dbgmsg("p[1] = %d\n",p[1]); - - if ((child = fork())==0) { - dbgmsg("writing to pipe\n"); - //write(p[1],"Hello World\n",16); - dbgmsg("write\n"); - } - else { - char buf[16]; - - dbgmsg("reading from pipe\n"); - read(p[0],buf,16); - buf[15] = 0; - dbgmsg("read: %s\n",buf); - } - - dbgmsg("reached end\n"); +#include + +#include "init.h" +#include "exe_elf.h" + +exe_t *exe_create(const char *file) { + exe_t *exe = malloc(sizeof(exe_t*)); + + // try ELF + exe->data = elf_create(file); + if (exe->data!=NULL) { + exe->type = EXE_ELF; + return exe; } - else dbgmsg("pipe() failed: (#%d) %s\n",errno,strerror(errno)); + else elf_destroy((elf_t*)exe->data); - while (1); + // not an executable + free(exe); + return NULL; +} + +void *exe_load(exe_t *exe,pid_t pid) { + if (exe->type==EXE_ELF) return elf_load((elf_t*)exe->data,pid); + else return NULL; +} +void exe_destroy(exe_t *exe) { + if (exe->type==EXE_ELF) elf_destroy((elf_t*)exe->data); + free(exe); } diff --git a/apps/init/exe_elf.c b/apps/init/exe_elf.c index e7a68b6..ca77bbe 100644 --- a/apps/init/exe_elf.c +++ b/apps/init/exe_elf.c @@ -26,37 +26,6 @@ #include "exe_elf.h" -#if 0 /** @todo remove? */ -static int elf_loadseg(pid_t pid,int fh,void *mem_addr,size_t mem_size,size_t file_addr,size_t file_size,int writable) { - if (mem_addr<(void*)USERSPACE_ADDRESS) return -1; - size_t i; - int ret = 0; - pid_t own_pid = getpid(); - - lseek(fh,file_addr,SEEK_SET); - - for (i=0;ifile_size?0:(i+PAGE_SIZE>file_size?file_size%PAGE_SIZE:PAGE_SIZE); - if (cur_count>0) { - read(fh,buf,cur_count); - dbgmsg("Loading from disk: 0x%x 0x%x 0x%x\n",mem_addr+i,file_addr+i,cur_count); - } - else { - memset(buf,0,PAGE_SIZE); - dbgmsg("Zeroing: 0x%x\n",mem_addr+i); - } - if (proc_memmap(pid,mem_addr+i,mem_getphysaddr(buf),writable,1,0)!=NULL) proc_memunmap(own_pid,buf); - else { - proc_memfree(own_pid,buf); - ret = -1; - break; - } - } - return ret; -} -#endif - /** * Validates ELF header * @param header Pointer to ELF header @@ -77,15 +46,22 @@ static int elf_loadseg(pid_t pid,int fh,void *mem_addr,size_t mem_size,size_t fi int ret = 0; pid_t own_pid = getpid(); - lseek(fh,file_addr,SEEK_SET); - + //lseek(fh,file_addr,SEEK_SET); + //dbgmsg("[0x%x:0x%x -> 0x%x:0x%x]\n",file_addr,file_size,mem_addr,mem_size); for (i=0;ifile_size?0:(i+PAGE_SIZE>file_size?file_size%PAGE_SIZE:PAGE_SIZE); - if (cur_count>0) read(fh,buf,cur_count); + //dbgmsg("<{0x%x 0x%x} buf=0x%x; cur_count=0x%x>\n",file_addr+i,mem_addr+i,buf,cur_count); + if (cur_count>0) { + //dbgmsg("TODO: BUG! lseek get's offset by 0x1000: %s:%d\n",__FILE__,__LINE__); + lseek(fh,file_addr+i,SEEK_SET); + read(fh,buf,cur_count); + //dbgmsg("read(%d) = 0x%x\n",fh,tmp); + } else memset(buf,0,PAGE_SIZE); if (proc_memmap(pid,mem_addr+i,mem_getphysaddr(buf),writable,1,0)!=NULL) proc_memunmap(own_pid,buf); else { + dbgmsg("Error at 0x%x!\n",mem_addr+i); proc_memfree(own_pid,buf); ret = -1; break; diff --git a/apps/init/exe_elf.h b/apps/init/exe_elf.h index e670334..ee66c51 100644 --- a/apps/init/exe_elf.h +++ b/apps/init/exe_elf.h @@ -17,6 +17,9 @@ */ #ifndef _EXE_ELF_H_ +#define _EXE_ELF_H_ + +#include #define ET_NONE 0 #define ET_REL 1 @@ -116,4 +119,4 @@ elf_t *elf_create(const char *file); void elf_destroy(elf_t *elf); void *elf_load(elf_t *elf,pid_t pid); -#endif +#endif /* _EXE_ELF_H_ */ diff --git a/apps/init/grub.c b/apps/init/grub.c new file mode 100644 index 0000000..e135117 --- /dev/null +++ b/apps/init/grub.c @@ -0,0 +1,125 @@ +/* + meinOS - A unix-like x86 microkernel operating system + Copyright (C) 2008 Janosch Gräf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include + +// Default mount parameters for boot device +#ifndef BOOT_FS + #define BOOT_FS "iso9660" +#endif +#ifndef BOOT_MP + #define BOOT_MP "/boot" +#endif +#ifndef BOOT_DEV + #define BOOT_DEV "/dev/cdrom0" +#endif +#ifndef BOOT_RO + #define BOOT_RO 1 +#endif + +static int sigusr1_count = 0; + +/** + * SIGUSR1 Handler. Is called when process finishs initialzation + * @param sig Signal. MUST be SIGUSR1 + */ +static void sigusr1_handler(int sig) { + sigusr1_count++; +} + +/** + * Waits for a program to initialize + * @return If waiting was successful or timeout occured + */ +static int init_wait_grub_module(void) { + useconds_t t = 0; + const useconds_t timeout = 10000; // 10 seconds + while (sigusr1_count==0 && t -#include -#include -#include -#include +#include -int main() { - pid_t child; -dbgmsg("test: Hello World\n"); -while (1); - int p[2]; - if (pipe(p)==0) { - dbgmsg("p[0] = %d\n",p[0]); - dbgmsg("p[1] = %d\n",p[1]); - - if ((child = fork())==0) { - dbgmsg("writing to pipe\n"); - //write(p[1],"Hello World\n",16); - dbgmsg("write\n"); - } - else { - char buf[16]; - - dbgmsg("reading from pipe\n"); - read(p[0],buf,16); - buf[15] = 0; - dbgmsg("read: %s\n",buf); - } - - dbgmsg("reached end\n"); - } - else dbgmsg("pipe() failed: (#%d) %s\n",errno,strerror(errno)); - - while (1); +#include "init.h" +/*static void init_computer_shutdown() { + pid_t child; + while ((child = getchild(0))!=-1) kill(child,SIGKILL); + exit(0); +}*/ + +int main(int argc,char *argv[]) { + // Initialize standard init RPC functions + rpc_func(proc_fork,"i",sizeof(int)); + rpc_func(proc_exec,"$i",PATH_MAX+sizeof(int)); + //rpc_func_create("computer_shutdown",init_computer_shutdown,"",0); + + // Start GRUB modules + pid_t *grub_modules = init_get_grub_modules(); + init_sort_grub_modules(grub_modules); + if (init_run_grub_modules(grub_modules)==-1) return 1; + + // Initialize ProcFS + procfs_init(grub_modules); + procfs_run(); + + return 0; } diff --git a/apps/init/init.conf.h b/apps/init/init.conf.h deleted file mode 100644 index c04d377..0000000 --- a/apps/init/init.conf.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _INIT_CONF_H_ -#define _INIT_CONF_H_ - -/// @todo generate this header from some config file in /etc/init.d - -// Default mount parameters for boot device -#ifndef BOOT_FS - #define BOOT_FS "iso9660" -#endif -#ifndef BOOT_MP - #define BOOT_MP "/boot" -#endif -#ifndef BOOT_DEV - #define BOOT_DEV "/dev/cdrom0" -#endif -#ifndef BOOT_RO - #define BOOT_RO 1 -#endif - -// Drivers to initialize -static const char *init_programs[] = { - "vfs", - "devfs", - "ata", - "cdrom", - "iso9660", - "vterm", - NULL -}; - -#define INIT_PROGRAM(n) init_programs[n] -#define INIT2_PROGRAM "init2" - -#endif diff --git a/apps/test/test.c b/apps/init/init.h similarity index 53% copy from apps/test/test.c copy to apps/init/init.h index a19c2de..2311526 100644 --- a/apps/test/test.c +++ b/apps/init/init.h @@ -16,39 +16,41 @@ along with this program. If not, see . */ +#ifndef _INIT_H_ +#define _INIT_H_ + #include -#include -#include -#include -#include - -int main() { - pid_t child; -dbgmsg("test: Hello World\n"); -while (1); - int p[2]; - if (pipe(p)==0) { - dbgmsg("p[0] = %d\n",p[0]); - dbgmsg("p[1] = %d\n",p[1]); - - if ((child = fork())==0) { - dbgmsg("writing to pipe\n"); - //write(p[1],"Hello World\n",16); - dbgmsg("write\n"); - } - else { - char buf[16]; - - dbgmsg("reading from pipe\n"); - read(p[0],buf,16); - buf[15] = 0; - dbgmsg("read: %s\n",buf); - } - - dbgmsg("reached end\n"); - } - else dbgmsg("pipe() failed: (#%d) %s\n",errno,strerror(errno)); - - while (1); - -} + +#include "exe_elf.h" + +// Executables + +typedef struct { + void *data; + enum { + EXE_ELF + } type; +} exe_t; + +exe_t *exe_create(const char *file); +void *exe_load(exe_t *exe,pid_t pid); +void exe_destroy(exe_t *exe); + +// Grub modules + +pid_t *init_get_grub_modules(); +int init_run_grub_modules(pid_t *modules); +void init_sort_grub_modules(pid_t *modules); + +// Proc + +int proc_exec(const char *file,int var); +pid_t proc_fork(void *child_entry); + +// ProcFS +int procfs_init(pid_t *grub_modules); +int procfs_run(void); +int procfs_proc_new(pid_t pid,const char *name,const char *exe); +int procfs_proc_update(pid_t pid,const char *name,const char *exe); + +#endif /* _INIT_H_ */ diff --git a/apps/init/init2.c b/apps/init/init2.c index 391177a..6cfc90f 100644 --- a/apps/init/init2.c +++ b/apps/init/init2.c @@ -16,65 +16,93 @@ along with this program. If not, see . */ -#include -#include -#include -#include #include -#include -#include -#include +#include +#include +#include -#define INIT_D "/boot/etc/init.d/initd.conf" +#include -int main() { +#define INIT_INITTAB "/boot/etc/inittab" +static int current_runlevel = 0; +static void init_set_runlevel(int new) { + current_runlevel = new; +} - while (1); +static int init_get_runlevel(void) { + return current_runlevel; +} - FILE *fd = fopen(INIT_D,"r"); - int flags = fcntl(fileno(fd),F_GETFD); - fcntl(fileno(fd),flags|FD_CLOEXEC); +/*static int init_load_inittab(const char *file) { + FILE *fd = fopen(INIT_INITTAB,"r"); if (fd!=NULL) { - char buf[1024]; + regex_t regex; + regmatch_t regmatch[8]; + + // "^[:space:]*[^:]*:[^:]*:[^:]*:[^:]*[:space:]*$" + regcomp(®ex,":?[^:]:?",REG_NEWLINE); + while (!feof(fd)) { - fgets(buf,1024,fd); - if (buf[0]!=0 && buf[0]!='\n' && buf[0]!='#') { - dbgmsg("system(%s) = %d\n",buf,system(buf)); -while (1); + static char line[256]; + + // read line + fgets(line,256,fd); + + // comment + if (line[0]=='#') { + continue; } -#if 0 /** @todo remove */ - size_t i; - size_t j = 0; - size_t k = 0; - char **argv = NULL; - for (i=0;buf[i];i++) { - if (buf[i]==':') { - argv = realloc(argv,(k+1)*sizeof(char*)); - argv[k] = malloc(i-j+1); - memcpy(argv[k],buf+j,i-j); - argv[k][i-j] = 0; - k++; - j = i+1; - } + // match it + regexec(®ex,line,8,regmatch,0); +while (1); + int i; + for (i=0;i<8;i++) { + if (regmatch[i].rm_so!=-1) { + size_t len = regmatch[i].rm_eo-regmatch[i].rm_so; + char *buf = malloc(len+1); + memcpy(buf,line+regmatch[i].rm_so,len); + buf[len] = 0; + dbgmsg("Match #%d: \"%s\"\n",i,buf); + free(buf); } - argv = realloc(argv,(k+2)*sizeof(char*)); - argv[k] = malloc(i-j+1); - memcpy(argv[k],buf+j,i-j); - argv[k][i-j] = 0; - argv[k+1] = NULL; + } + while (1); + } - if (fork()==0) execv(argv[0],argv); + regfree(®ex); - for (i=0;argv[i];i++) free(argv[i]); - free(argv); -#endif - } - fclose(fd); return 0; } - else return 1; + else { + return -1; + } +}*/ + +int main() { + kill(1,SIGUSR1); + + /// @todo Put in /etc/init.d + dbgmsg("Starting ramdisk...\n"); + pid_t pid = fork(); + if (pid==0) { + execl("/boot/bin/ramdisk","ramdisk",0); + dbgmsg("Didn't start ramdisk, something went wrong.\n"); + return 0; + } + dbgmsg("Mounting ramdisk...\n"); + do sleep(1); + while (vfs_mount("ramdisk","/",NULL,0)!=-1); + + //init_load_inittab(INIT_INITTAB); + + rpc_func(init_set_runlevel,"i",sizeof(int)); + rpc_func(init_get_runlevel,"",0); + + rpc_mainloop(-1); + + return 0; } diff --git a/apps/init/init_ramdisk.c b/apps/init/init_ramdisk.c deleted file mode 100644 index b878e1f..0000000 --- a/apps/init/init_ramdisk.c +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include -#include - -static void ramdisk_link(char *dir) { - char *dest; - asprintf(&dest,"/boot%s",dir); - symlink(dest,dir); - free(dest); -} - -int main() { - // Mount ramdisk -dbgmsg("initrd: Hello!\n"); - while (vfs_mount("ramdisk","/",NULL,0)==-1) sleep(1); -dbgmsg("initrd: mounted ramdisk\n"); -while (1); - // create directories - mkdir("/dev",0777); - mkdir("/boot",0777); - mkdir("/tmp",0777); - mkdir("/mnt",0777); - mkdir("/var",0777); - mkdir("/var/log",0777); - - // create symlinks - ramdisk_link("/bin"); - ramdisk_link("/etc"); - ramdisk_link("/usr"); - - return 0; -} diff --git a/apps/init/init.c b/apps/init/proc.c old mode 100755 new mode 100644 similarity index 51% rename from apps/init/init.c rename to apps/init/proc.c index 0c21452..c9301b4 --- a/apps/init/init.c +++ b/apps/init/proc.c @@ -16,98 +16,18 @@ along with this program. If not, see . */ +#include #include -#include -#include -#include -#include -#include -#include #include +#include #include -#include - -#include "exe_elf.h" -#include "init.conf.h" - -static int sigusr1_count; - -/** - * SIGUSR1 Handler. Is called when process finishs initialzation - * @param sig Signal. MUST be SIGUSR1 - */ -static void sigusr1_handler(int sig) { - sigusr1_count++; -} - -/** - * Initializes Initialization ;) - */ -static void init_init() { - signal(SIGUSR1,sigusr1_handler); -} - -/** - * Runs a program (Sends SIGCONT) - * @param name Name of program to run - */ -static void init_run(const char *name) { - pid_t pid = getpidbyname(name); - sigusr1_count = 0; - proc_run(pid); -} - -/** - * Waits for a program to initialize - * @param name Name of program to wait for - * @return If waiting was successful or timeout occured - */ -static int init_wait(const char *name) { - useconds_t t = 0; - const useconds_t timeout = 10000; // 10 seconds - while (sigusr1_count==0 && tdata = elf_create(file); - if (exe->data!=NULL) { - exe->type = EXE_ELF; - return exe; - } - else elf_destroy((elf_t*)exe->data); - - // not an executable - free(exe); - return NULL; -} - -static void *exe_load(exe_t *exe,pid_t pid) { - if (exe->type==EXE_ELF) return elf_load((elf_t*)exe->data,pid); - else return NULL; -} +#include +#include -static void exe_destroy(exe_t *exe) { - if (exe->type==EXE_ELF) elf_destroy((elf_t*)exe->data); -} +#include "init.h" -static pid_t proc_fork(void *child_entry) { +pid_t proc_fork(void *child_entry) { // Create process - char *name = getname(rpc_curpid); pid_t pid = proc_create(name,getuidbypid(rpc_curpid),getgidbypid(rpc_curpid),rpc_curpid); @@ -142,6 +62,10 @@ static pid_t proc_fork(void *child_entry) { } } + // Set stack (we already created one by copying address space) + int *stack = proc_getstack(rpc_curpid); + proc_setstack(pid,stack); + // Set entrypoint of child proc_jump(pid,child_entry); } @@ -149,11 +73,11 @@ static pid_t proc_fork(void *child_entry) { return pid; } -static int proc_exec(const char *file,int var) { - dbgmsg("proc_exec(%s,%d)\n",file,var); +int proc_exec(const char *file,int var) { // Change process char *_file = strdup(file); proc_setname(rpc_curpid,basename(_file)); + free(_file); proc_setvar(rpc_curpid,var); // Load executable @@ -169,8 +93,8 @@ static int proc_exec(const char *file,int var) { void *entrypoint = exe_load(exe,rpc_curpid); if (entrypoint!=NULL) { - proc_jump(rpc_curpid,entrypoint); proc_createstack(rpc_curpid); + proc_jump(rpc_curpid,entrypoint); } else { dbgmsg("failed loading executable!"); @@ -183,41 +107,3 @@ static int proc_exec(const char *file,int var) { } else return errno; } - -static void init_computer_shutdown() { - pid_t child; - while ((child = getchild(0))!=-1) kill(child,SIGKILL); - exit(0); -} - -int main(int argc,char *argv[]) { - size_t i; - - init_init(); - for (i=0;INIT_PROGRAM(i);i++) { - //dbgmsg("init: starting %s...",INIT_PROGRAM(i)); - init_run(INIT_PROGRAM(i)); - - if (!init_wait(INIT_PROGRAM(i))) { - dbgmsg("init: %s does not respond. initialization failed!\n",init_programs[i]); - return 1; - } - //dbgmsg("done\n"); - - if (strcmp(INIT_PROGRAM(i),"iso9660")==0) { - // Initial mount of boot device - vfs_mount(BOOT_FS,BOOT_MP,BOOT_DEV,BOOT_RO); - sleep(1); - } - } - - rpc_func(proc_fork,"i",sizeof(int)); - rpc_func(proc_exec,"$i",PATH_MAX+sizeof(int)); - rpc_func_create("computer_shutdown",init_computer_shutdown,"",0); - - init_run(INIT2_PROGRAM); - - rpc_mainloop(-1); - - return 0; -} diff --git a/apps/init/procfs.c b/apps/init/procfs.c new file mode 100644 index 0000000..b7581a5 --- /dev/null +++ b/apps/init/procfs.c @@ -0,0 +1,282 @@ +/* + meinOS - A unix-like x86 microkernel operating system + Copyright (C) 2008 Janosch Gräf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "init.h" + +#define PROCFS_NAME "procfs" +#define PROCFS_MOUNTPOINT "/proc" + +typedef struct procfs_path_S procfs_path_t; + +typedef struct { + pid_t pid; + char *exe; + char *name; + uid_t uid; + gid_t gid; +} procfs_proc_t; + +typedef enum { + PROCFS_FILE, + PROCFS_DIR, + PROCFS_SYMLINK +} procfs_ftype_t; + +typedef struct { + const char *name; + procfs_ftype_t ftype; + struct { + int (*cb_read)(procfs_path_t *path,char *buf,size_t size,off_t offset); + int (*cb_write)(procfs_path_t *path,const char *buf,size_t size,off_t offset); + } file; + struct { + int (*cb_readdir)(procfs_path_t *path,void *buf,fuse_fill_dir_t filler,off_t offset); + } dir; + struct { + } symlink; +} procfs_file_t; + +struct procfs_path_S { + pid_t pid; + procfs_proc_t *proc; + procfs_file_t *file; + const char *subfile; + int isdir; +}; + +static int procfs_loginuid_read(procfs_path_t *path,char *buf,size_t size,off_t offset); +static int procfs_mem_read(procfs_path_t *path,char *buf,size_t size,off_t offset); +static int procfs_mem_write(procfs_path_t *path,const char *buf,size_t size,off_t offset); +static procfs_file_t procfs_files[] = { + { .name = "cwd", .ftype = PROCFS_SYMLINK }, + { .name = "exe", .ftype = PROCFS_SYMLINK }, + { .name = "loginuid", .ftype = PROCFS_FILE, .file = { .cb_read = procfs_loginuid_read } }, + { .name = "mem", .ftype = PROCFS_FILE, .file = { .cb_read = procfs_mem_read, .cb_write = procfs_mem_write } }, + { .name = NULL } +}; + +static llist_t procfs_processes; + +static int procfs_loginuid_read(procfs_path_t *path,char *buf,size_t size,off_t offset) { + return 0; +} + +static int procfs_mem_read(procfs_path_t *path,char *buf,size_t size,off_t offset) { + return 0; +} + +static int procfs_mem_write(procfs_path_t *path,const char *buf,size_t size,off_t offset) { + return 0; +} + +static procfs_proc_t *procfs_proc_find(pid_t pid) { + size_t i; + procfs_proc_t *proc; + for (i=0;(proc = llist_get(procfs_processes,i));i++) { + if (proc->pid==pid) return proc; + } + return NULL; +} + +int procfs_proc_new(pid_t pid,const char *name,const char *exe) { + procfs_proc_t *proc = malloc(sizeof(procfs_proc_t)); + proc->pid = pid; + proc->uid = getuidbypid(pid); + proc->gid = getgidbypid(pid); + if (name==NULL) proc->name = getname(pid); + else proc->name = strdup(name); + if (exe==NULL) proc->exe = NULL; + else proc->exe = strdup(exe); + llist_push(procfs_processes,proc); + return 0; +} + +int procfs_proc_update(pid_t pid,const char *name,const char *exe) { + procfs_proc_t *proc = procfs_proc_find(pid); + if (proc!=NULL) { + if (name!=NULL) { + free(proc->name); + proc->name = strdup(name); + } + if (exe!=NULL) { + free(proc->exe); + proc->exe = strdup(exe); + } + return 0; + } + else return -1; +} + +static void procfs_parse_path(const char *strpath,procfs_path_t *path) { + path_t *tpath = path_parse(strpath); + path_reject_dots(tpath); + + memset(path,0,sizeof(procfs_path_t)); + path->isdir = 1; + if (tpath->num_parts>0) { + path->pid = strtoul(tpath->parts[0],NULL,10); + path->proc = procfs_proc_find(path->pid); + //path->isdir = 1; + } + if (tpath->num_parts>1) { + size_t i; + for (i=0;procfs_files[i].name!=NULL;i++) { + if (strcmp(tpath->parts[1],procfs_files[i].name)==0) { + path->file = procfs_files+i; + path->isdir = (path->file->ftype==PROCFS_DIR); + } + } + } + if (tpath->num_parts>2) { + static char subfile_buf[256]; + strncpy(subfile_buf,tpath->parts[2],256); + path->subfile = subfile_buf; + path->isdir = 0; + } + + path_destroy(tpath); +} + +static int procfs_open(const char *strpath,struct fuse_file_info *fi) { + procfs_path_t path; + + if (path.pid!=0 && path.proc!=NULL) return -ENOENT; + else if (path.isdir) return -EISDIR; + else return 0; +} + +static int procfs_close(const char *path,struct fuse_file_info *fi) { + return 0; +} + +static int procfs_read(const char *strpath,char *buf,size_t count,off_t offset,struct fuse_file_info *fi) { + procfs_path_t path; + procfs_parse_path(strpath,&path); + + if (path.pid!=0 && path.proc!=NULL) return -ENOENT; + else if (path.isdir) return -EISDIR; + else { + if (path.file->file.cb_read!=NULL) return path.file->file.cb_read(&path,buf,count,offset); + else return -ENOSYS; + } +} + +static int procfs_write(const char *strpath,const char *buf,size_t count,off_t offset,struct fuse_file_info *fi) { + procfs_path_t path; + procfs_parse_path(strpath,&path); + + if (path.pid!=0 && path.proc!=NULL) return -ENOENT; + else if (path.isdir) return -EISDIR; + else { + if (path.file->file.cb_write!=NULL) return path.file->file.cb_write(&path,buf,count,offset); + else return -ENOSYS; + } +} + +static int procfs_readdir(const char *strpath,void *buf,fuse_fill_dir_t filler,off_t offset,struct fuse_file_info *fi) { + procfs_path_t path; + procfs_parse_path(strpath,&path); + + if (!path.isdir) return -ENOTDIR; + else if (path.pid==0) { + // list all processes + size_t i; + procfs_proc_t *proc; + struct stat stbuf = { + /// @todo correct permissions + .st_mode = S_IFDIR|0777, + }; + for (i=0;(proc = llist_get(procfs_processes,i));i++) { + char str_pid[16]; + snprintf(str_pid,16,"%d",proc->pid); + stbuf.st_uid = proc->uid; + stbuf.st_gid = proc->gid; + filler(buf,str_pid,&stbuf,0); + } + return 0; + } + else if (path.proc!=NULL) return -ENOENT; + else { + if (path.file->dir.cb_readdir!=NULL) return path.file->dir.cb_readdir(&path,buf,filler,offset); + else return -ENOSYS; + } +} + +static int procfs_getattr(const char *strpath,struct stat *stbuf) { + procfs_path_t path; + procfs_parse_path(strpath,&path); + + memset(stbuf,0,sizeof(struct stat)); + + if (path.file!=NULL) { + if (path.file->ftype==PROCFS_DIR) stbuf->st_mode = S_IFDIR; + else if (path.file->ftype==PROCFS_SYMLINK) stbuf->st_mode = S_IFLNK; + else stbuf->st_mode = S_IFREG; + } + else stbuf->st_mode = S_IFDIR; + + /// @todo correct permissions + stbuf->st_mode |= 0777; + + return 0; +} + +int procfs_init(pid_t *grub_modules) { + size_t i; + pid_t pid; + + procfs_processes = llist_create(); + + // put init itself in process list + procfs_proc_new(1,"init",NULL); + + // put GRUB modules in process list + for (i=0;(pid = grub_modules[i])!=0;i++) { + procfs_proc_new(pid,NULL,NULL); + } + + return 0; +} + +int procfs_run(void) { + // start FUSE + struct fuse_operations devfs_oper = { + .open = procfs_open, + .release = procfs_close, + .read = procfs_read, + .write = procfs_write, + .readdir = procfs_readdir, + .getattr = procfs_getattr + }; + + // fake argc/argv + int fake_argc = 2; + char *fake_argv[2] = { PROCFS_NAME,PROCFS_MOUNTPOINT }; + fuse_main(fake_argc,fake_argv,&devfs_oper,NULL); + + return 0; +} diff --git a/apps/lib/crt0/crt0.c b/apps/lib/crt0/crt0.c index ca56ef9..9b14311 100644 --- a/apps/lib/crt0/crt0.c +++ b/apps/lib/crt0/crt0.c @@ -28,50 +28,6 @@ int main(int argc,char *argv[]); void _stdlib_init(); ///< @see apps/lib/stdlibc/stdlib.c void _libmeinos_init(); ///< @see apps/lib/libmeinos/misc.c -/*static int var; - -static void get_cmdline(struct process_data *data,char ***_argv,int *_argc,char **_stdin,char **_stdout,char **_stderr) { - int argc = data->argc; - char **argv = malloc((argc+1)*sizeof(char*)); - size_t i = 0; - size_t j; - - for (j=0;jcmdline+i; - i += strlen(data->cmdline+i)+1; - } - argv[j] = NULL; - - if (data->has_stdin) { - if (_stdin!=NULL) *_stdin = data->stdio+i; - i += strlen(data->stdio+i)+1; - } - else if (_stdin!=NULL) *_stdin = NULL; - - if (data->has_stdout) { - if (_stdout!=NULL) *_stdout = data->stdio+i; - i += strlen(data->stdio+i)+1; - } - else if (_stdout!=NULL) *_stdout = NULL; - - if (data->has_stderr) { - if (_stderr!=NULL) *_stderr = data->stdio+i; - i += strlen(data->stdio+i)+1; - } - else if (_stderr!=NULL) *_stderr = NULL; - - *_argv = argv; - *_argc = argc; -} - -static void crt0_quit() { - if (_process_data!=NULL) { - // remove process data - shmdt(_process_data); - shmctl(var,IPC_RMID,NULL); - } -}*/ - void _start() { char *backup_argv[] = { NULL }; char **argv = backup_argv; diff --git a/apps/lib/libavl/Makefile b/apps/lib/libavl/Makefile dissimilarity index 61% index 2b9802a..3497bc1 100644 --- a/apps/lib/libavl/Makefile +++ b/apps/lib/libavl/Makefile @@ -1,47 +1,25 @@ --include ../../../Makefile.config - -OBJFILES = avl.o \ - bst.o \ - pavl.o \ - pbst.o \ - prb.o \ - rb.o \ - rtavl.o \ - rtbst.o \ - rtrb.o \ - tavl.o \ - tbst.o \ - trb.o - -all: ../libavl.a - -../libavl.a: $(OBJFILES) - $(LIBS_AR) rs $@ $^ - -avl.o: avl.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -bst.o: bst.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -pavl.o: pavl.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -pbst.o: pbst.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -prb.o: prb.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -rb.o: rb.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -rtavl.o: rtavl.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -rtbst.o: rtbst.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -rtrb.o: rtrb.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -tavl.o: tavl.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -tbst.o: tbst.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -trb.o: trb.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ - -clean: - rm -f $(OBJFILES) ../libavl.a +-include ../../../Makefile.config + +CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) + +OBJFILES = avl.o \ + bst.o \ + pavl.o \ + pbst.o \ + prb.o \ + rb.o \ + rtavl.o \ + rtbst.o \ + rtrb.o \ + tavl.o \ + tbst.o \ + trb.o + +all: ../libavl.a + +../libavl.a: $(OBJFILES) + $(LIBS_AR) rs $@ $^ + +clean: + rm -f $(OBJFILES) ../libavl.a diff --git a/apps/lib/libcdi/Makefile b/apps/lib/libcdi/Makefile dissimilarity index 62% index 1a0f349..317edc9 100644 --- a/apps/lib/libcdi/Makefile +++ b/apps/lib/libcdi/Makefile @@ -1,43 +1,23 @@ --include ../../../Makefile.config - -OBJFILES = bios.o \ - cache.o \ - cdi.o \ - dma.o \ - fs.o \ - misc.o \ - net.o \ - scsi.o \ - storage.o \ - video.o - -all: ../libcdi.a - -../libcdi.a: $(OBJFILES) - $(LIBS_AR) rs $@ $^ - -bios.o: bios.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -cache.o: cache.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -cdi.o: cdi.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -dma.o: dma.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fs.o: fs.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -misc.o: misc.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -net.o: net.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -pci.o: pci.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -scsi.o: scsi.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -storage.o: storage.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -video.o: video.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ - -clean: - rm -f $(OBJFILES) ../libcdi.a +-include ../../../Makefile.config + +CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) + +OBJFILES = bios.o \ + cache.o \ + cdi.o \ + dma.o \ + fs.o \ + misc.o \ + net.o \ + scsi.o \ + storage.o \ + video.o + +all: ../libcdi.a + +../libcdi.a: $(OBJFILES) + $(LIBS_AR) rs $@ $^ + +clean: + rm -f $(OBJFILES) ../libcdi.a diff --git a/apps/lib/libcdi/fs.c b/apps/lib/libcdi/fs.c index 4c4cdbb..38d3623 100644 --- a/apps/lib/libcdi/fs.c +++ b/apps/lib/libcdi/fs.c @@ -78,6 +78,7 @@ struct cdi_fs_file { static int cdi_fs_mount(struct cdi_fs_driver *driver,const char *fs_name,const char *mountpoint,const char *dev,int readonly) { CDI_DEBUG("fs_mount(0x%x,%s,%s,%s,%d)\n",driver,fs_name,mountpoint,dev,readonly); int fsid = rpc_call("vfs_regfs",0,fs_name,mountpoint); + if (fsid!=-1) { struct cdi_fs_filesystem *filesystem = malloc(sizeof(struct cdi_fs_filesystem)); filesystem->driver = driver; diff --git a/apps/lib/libcrypt/Makefile b/apps/lib/libcrypt/Makefile index f313ea4..67621cf 100644 --- a/apps/lib/libcrypt/Makefile +++ b/apps/lib/libcrypt/Makefile @@ -1,5 +1,8 @@ -include ../../../Makefile.config +CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) + OBJFILES = crypt.o \ crypt_stub.o \ des.o \ @@ -10,14 +13,5 @@ all: ../libcrypt.a ../libcrypt.a: $(OBJFILES) $(LIBS_AR) rs $@ $^ -crypt.o: crypt.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -crypt_stub.o: crypt_stub.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -des.o: des.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -md5.o: md5.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ - clean: rm -f $(OBJFILES) ../libcrypt.a diff --git a/apps/lib/libfuse/Makefile b/apps/lib/libfuse/Makefile dissimilarity index 62% index f5050fd..a8cc9af 100644 --- a/apps/lib/libfuse/Makefile +++ b/apps/lib/libfuse/Makefile @@ -1,47 +1,25 @@ --include ../../../Makefile.config - -OBJFILES = fuse_daemonize.o \ - fuse_destroy.o \ - fuse_fs_new.o \ - fuse_loop.o \ - fuse_lowlevel.o \ - fuse_main_real.o \ - fuse_mount.o \ - fuse_new.o \ - fuse_parse_cmdline.o \ - fuse_setup.o \ - fuse_teardown.o \ - fuse_unmount.o - -all: ../libfuse.a - -../libfuse.a: $(OBJFILES) - $(LIBS_AR) rs $@ $^ - -fuse_daemonize.o: fuse_daemonize.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_destroy.o: fuse_destroy.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_fs_new.o: fuse_fs_new.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_loop.o: fuse_loop.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_lowlevel.o: fuse_lowlevel.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_main_real.o: fuse_main_real.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_mount.o: fuse_mount.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_new.o: fuse_new.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_parse_cmdline.o: fuse_parse_cmdline.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_setup.o: fuse_setup.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_teardown.o: fuse_teardown.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -fuse_unmount.o: fuse_unmount.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ - -clean: - rm -f $(OBJFILES) ../libfuse.a +-include ../../../Makefile.config + +CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) + +OBJFILES = fuse_daemonize.o \ + fuse_destroy.o \ + fuse_fs_new.o \ + fuse_loop.o \ + fuse_lowlevel.o \ + fuse_main_real.o \ + fuse_mount.o \ + fuse_new.o \ + fuse_parse_cmdline.o \ + fuse_setup.o \ + fuse_teardown.o \ + fuse_unmount.o + +all: ../libfuse.a + +../libfuse.a: $(OBJFILES) + $(LIBS_AR) rs $@ $^ + +clean: + rm -f $(OBJFILES) ../libfuse.a diff --git a/apps/lib/libm/Makefile b/apps/lib/libm/Makefile index 168ba7e..0b97038 100644 --- a/apps/lib/libm/Makefile +++ b/apps/lib/libm/Makefile @@ -6,9 +6,8 @@ # -D_POSIX_MODE - POSIX/ANSI # -D_SVID3_MODE - SVID -CFLAGS = $(LIBS_CFLAGS) -D_IEEE_MODE - CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) -D_IEEE_MODE OBJFILES = \ carg.o i386/fegetround.o s_fpclassify.o s_trunc.o \ diff --git a/apps/lib/libmeinos/Makefile b/apps/lib/libmeinos/Makefile dissimilarity index 68% index 253dc60..413e602 100755 --- a/apps/lib/libmeinos/Makefile +++ b/apps/lib/libmeinos/Makefile @@ -1,64 +1,40 @@ --include ../../../Makefile.config - -OBJFILES = cmos.o \ - devfs.o \ - irq_asm.o \ - irq.o \ - lock.o \ - misc.o \ - path.o \ - pci.o \ - proc.o \ - ringbuf.o \ - rpc.o \ - syscall.o \ - dyncall.o \ - llist.o \ - pack.o \ - perm.o \ - tree.o - -all: ../libmeinos.a - -../libmeinos.a: $(OBJFILES) - $(LIBS_AR) rs $@ $^ - -cmos.o: cmos.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -devfs.o: devfs.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -irq_asm.o: irq.asm - $(LIBS_ASM) -f elf -o $@ $^ -irq.o: irq.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -llist2.o: llist2.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -lock.o: lock.asm - $(LIBS_ASM) -f elf -o $@ $^ -misc.o: misc.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -path.o: path.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -pci.o: pci.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -proc.o: proc.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -ringbuf.o: ringbuf.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -rpc.o: rpc.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -syscall.o: syscall.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -dyncall.o: ../../../lib/libmeinos/dyncall.asm - $(LIBS_ASM) -f elf -o $@ $^ -llist.o: ../../../lib/libmeinos/llist.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -pack.o: ../../../lib/libmeinos/pack.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -perm.o: ../../../lib/libmeinos/perm.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) -tree.o: ../../../lib/libmeinos/tree.c - $(LIBS_CC) -o $@ $^ $(LIBS_CFLAGS) - -clean: - rm -f $(OBJFILES) ../libmeinos.a \ No newline at end of file +-include ../../../Makefile.config + +CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) + +OBJFILES = cmos.o \ + devfs.o \ + irq_asm.o \ + irq.o \ + lock.o \ + misc.o \ + path.o \ + pci.o \ + proc.o \ + ringbuf.o \ + rpc.o \ + syscall.o \ + \ + ../../../lib/libmeinos/dyncall.o \ + ../../../lib/libmeinos/llist.o \ + ../../../lib/libmeinos/pack.o \ + ../../../lib/libmeinos/perm.o \ + ../../../lib/libmeinos/tree.o + +all: ../libmeinos.a + +../libmeinos.a: $(OBJFILES) + $(LIBS_AR) rs $@ $^ + +irq_asm.o: irq.asm + $(LIBS_ASM) -f elf -o $@ $^ +lock.o: lock.asm + $(LIBS_ASM) -f elf -o $@ $^ + +../../../lib/libmeinos/dyncall.o: ../../../lib/libmeinos/dyncall.asm + $(LIBS_ASM) -f elf -o $@ $^ + + +clean: + rm -f $(OBJFILES) ../libmeinos.a \ No newline at end of file diff --git a/apps/lib/libmeinos/rpc.c b/apps/lib/libmeinos/rpc.c index 9778685..1efa861 100644 --- a/apps/lib/libmeinos/rpc.c +++ b/apps/lib/libmeinos/rpc.c @@ -26,6 +26,7 @@ #include #include #include +#include int rpc_func_create(const char *name,void *func,const char *synopsis,size_t paramsz) { int ret = syscall_call(SYSCALL_RPC_CREATE,4,name,func,synopsis,paramsz); @@ -69,9 +70,13 @@ int rpc_vcall(const char *name,int flags,va_list args) { // call function for (try=0;try%d ret=%d error=%d\n",try,name,getpid(),sendto,ret,error); +#if 0 + dbgmsg("rpc[%d]:\t %s %d->%d ret=%d error=%d\n",try,name,getpid(),sendto,ret,error); + if (ret<0) { + dbgmsg("rpc[%d]:\t Possibly error: %s\n",try,strerror(-ret)); + } +#endif } - while (error!=0); if (error==0) { if (ret_params) { diff --git a/apps/lib/readline/Makefile b/apps/lib/readline/Makefile index d1b8ff3..034e034 100644 --- a/apps/lib/readline/Makefile +++ b/apps/lib/readline/Makefile @@ -1,5 +1,8 @@ -include ../../../Makefile.config +CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) + OBJFILES = readline.o all: ../libreadline.a @@ -7,8 +10,5 @@ all: ../libreadline.a ../libreadline.a: $(OBJFILES) $(LIBS_AR) rs $@ $^ -readline.o: readline.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ - clean: rm -f $(OBJFILES) ../libreadline.a diff --git a/apps/lib/zlib/Makefile b/apps/lib/zlib/Makefile dissimilarity index 61% index a345548..1f3c7d3 100644 --- a/apps/lib/zlib/Makefile +++ b/apps/lib/zlib/Makefile @@ -1,46 +1,25 @@ --include ../../../Makefile.config - -OBJFILES = adler32.o \ - compress.o \ - crc32.o \ - deflate.o \ - gzio.o \ - infback.o \ - inffast.o \ - inflate.o \ - inftrees.o \ - trees.o \ - uncompr.o \ - zutil.o - -all: ../libz.a - -../libz.a: $(OBJFILES) - $(LIBS_AR) rs $@ $^ - -adler32.o: adler32.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -compress.o: compress.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -crc32.o: crc32.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -deflate.o: deflate.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -gzio.o: gzio.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -infback.o: infback.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -inffast.o: inffast.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -inflate.o: inflate.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -inftrees.o: inftrees.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -trees.o: trees.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -uncompr.o: uncompr.c - $(LIBS_CC) $(LIBS_CFLAGS) -o $@ $^ -zutil.o: zutil.c - -clean: - rm -f $(OBJFILES) ../libz.a +-include ../../../Makefile.config + +CC = $(LIBS_CC) +CFLAGS = $(LIBS_CFLAGS) + +OBJFILES = adler32.o \ + compress.o \ + crc32.o \ + deflate.o \ + gzio.o \ + infback.o \ + inffast.o \ + inflate.o \ + inftrees.o \ + trees.o \ + uncompr.o \ + zutil.o + +all: ../libz.a + +../libz.a: $(OBJFILES) + $(LIBS_AR) rs $@ $^ + +clean: + rm -f $(OBJFILES) ../libz.a diff --git a/apps/ramdisk/dir.c b/apps/ramdisk/dir.c index 0a104a8..289031b 100755 --- a/apps/ramdisk/dir.c +++ b/apps/ramdisk/dir.c @@ -38,7 +38,6 @@ #include "ramdisk_cdi.h" - cdi_list_t ramdisk_fs_dir_list(struct cdi_fs_stream* stream) { return stream->res->children; diff --git a/apps/ramdisk/init.c b/apps/ramdisk/init.c index 260653e..68aeab1 100755 --- a/apps/ramdisk/init.c +++ b/apps/ramdisk/init.c @@ -35,7 +35,6 @@ #include "ramdisk_cdi.h" #include "cdi/lists.h" -#include int ramdisk_fs_init(struct cdi_fs_filesystem* cdi_fs) { diff --git a/apps/rc/Makefile b/apps/rc/Makefile new file mode 100644 index 0000000..0b6c69b --- /dev/null +++ b/apps/rc/Makefile @@ -0,0 +1,24 @@ +-include ../../Makefile.config + +all: all_rc all_boot + +all_rc: rc rc.objdump + cp $< ../../files/etc/init.d + +rc: rc.c helper.c + $(APPS_CC) -o $@ $^ + +rc.objdump: rc + $(APPS_OBJDUMP) -d -S $^ > $@ + +all_boot: boot boot.objdump + cp $< ../../files/etc/init.d + +boot: boot.c helper.c + $(APPS_CC) -o $@ $^ + +boot.objdump: boot + $(APPS_OBJDUMP) -d -S $^ > $@ + +clean: + rm -f rc boot ../../files/etc/init.d/rc ../../files/etc/init.d/boot *.objdump diff --git a/apps/rc/boot.c b/apps/rc/boot.c new file mode 100644 index 0000000..3982d8d --- /dev/null +++ b/apps/rc/boot.c @@ -0,0 +1,89 @@ +/* + meinOS - A unix-like x86 microkernel operating system + Copyright (C) 2008 Janosch Gräf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include + +#include "helper.h" + +static const char *grub_module_template = +"#!/bin/sh" +"# Copyright (c) 2009 Janosch Graef" +"#" +"### BEGIN INIT INFO" +"# Provides: %s" +"# Required-Start:" +"# Required-Stop:" +"# Should-Start:" +"# Should-Stop:" +"# Default-Start: 1 2 3 5" +"# Default-Stop:" +"# Short-Description: Pseudo RC script for grub module '%s'" +"# Description: Pseudo RC script for grub module '%s'" +"### END INIT INFO" +"" +"case \"$1\" in" +" start)" +" echo \"This is a GRUB module. It should already run.\"" +" ;;" +" stop)" +" echo \"Cannot stop GRUB modules.\" > 2" +" ;;" +" status)" +" echo \"running\"" +" ;;" +" *)" +" echo \"Usage: $0 {start|stop|status}\" > 2" +" ;;" +"esac"; + +static int make_grub_module_script(const char *name) { + char *script; + char *path; + int ret = -1; + + asprintf(&path,"/etc/init.d/%s",name); + asprintf(&script,grub_module_template,name,name,name); + + FILE *fd = fopen(path,"w"); + if (fd!=NULL) { + fputs(script,fd); + fclose(fd); + ret = 0; + } + + free(path); + free(script); + + make_rc_symlink(name,1,1,'S'); + make_rc_symlink(name,2,1,'S'); + make_rc_symlink(name,3,1,'S'); + make_rc_symlink(name,5,1,'S'); + make_rc_symlink(name,1,1,'K'); + make_rc_symlink(name,2,1,'K'); + make_rc_symlink(name,3,1,'K'); + make_rc_symlink(name,5,1,'K'); + + return ret; +} + +int main(int argc,char *argv[]) { + /// @todo get GRUB modules and create module scripts + make_grub_module_script("vfs"); + return 0; +} diff --git a/apps/rc/helper.c b/apps/rc/helper.c new file mode 100644 index 0000000..b5eb182 --- /dev/null +++ b/apps/rc/helper.c @@ -0,0 +1,73 @@ +/* + meinOS - A unix-like x86 microkernel operating system + Copyright (C) 2008 Janosch Gräf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include +#include + +#include "helper.h" + +int get_runlevel(void) { + return rpc_call("init_get_runlevel",0); +} + +int str_to_runlevel(const char *str) { + if (str[0]==0) return -1; + if (str[1]!=0) return -1; + char chr = str[0]; + + if (chr>='0' && chr<'7') return chr-'0'; + else return -1; +} + +char *rcd_path(int runlevel) { + static char *path = "/etc/init.d/rcX.d\n"; + path[14] = '0'+runlevel; + return path; +} + +void parse_rc_script(rc_script_t *script,const char *dir,const char *file) { + char *name; + asprintf(&(script->path),"%s/%s",dir,file); + script->priority = strtoul(file+1,&name,10); + script->name = strdup(name); +} + +int compare_rc_script(const void *vscript1,const void *vscript2) { + const rc_script_t *script1 = vscript1; + const rc_script_t *script2 = vscript2; + + if (script1->name==NULL) return 1; + else if (script2->name==NULL) return -1; + else return script1->priority-script2->priority; +} + +int make_rc_symlink(const char *name,int runlevel,int priority,char prefix) { + char *link; + char *target; + + asprintf(&link,"%s/%c%02d%s",rcd_path(runlevel),prefix,priority,name); + asprintf(&target,"/etc/init.d/%s",name); + + int ret = symlink(target,link); + + free(link); + free(target); + + return ret; +} diff --git a/apps/test/test.c b/apps/rc/helper.h similarity index 54% copy from apps/test/test.c copy to apps/rc/helper.h index a19c2de..c758d47 100644 --- a/apps/test/test.c +++ b/apps/rc/helper.h @@ -16,39 +16,20 @@ along with this program. If not, see . */ -#include -#include -#include -#include -#include - -int main() { - pid_t child; -dbgmsg("test: Hello World\n"); -while (1); - int p[2]; - if (pipe(p)==0) { - dbgmsg("p[0] = %d\n",p[0]); - dbgmsg("p[1] = %d\n",p[1]); - - if ((child = fork())==0) { - dbgmsg("writing to pipe\n"); - //write(p[1],"Hello World\n",16); - dbgmsg("write\n"); - } - else { - char buf[16]; - - dbgmsg("reading from pipe\n"); - read(p[0],buf,16); - buf[15] = 0; - dbgmsg("read: %s\n",buf); - } - - dbgmsg("reached end\n"); - } - else dbgmsg("pipe() failed: (#%d) %s\n",errno,strerror(errno)); - - while (1); - -} +#ifndef _HELPER_H_ +#define _HELPER_H_ + +typedef struct { + char *name; + char *path; + int priority; +} rc_script_t; + +char *rcd_path(int runlevel); +int get_runlevel(void); +int str_to_runlevel(const char *str); +void parse_rc_script(rc_script_t *script,const char *dir,const char *file); +int compare_rc_script(const void *vscript1,const void *vscript2); +int make_rc_symlink(const char *name,int runlevel,int priority,char prefix); + +#endif /* _HELPER_H_ */ diff --git a/apps/rc/rc.c b/apps/rc/rc.c new file mode 100644 index 0000000..301f2a6 --- /dev/null +++ b/apps/rc/rc.c @@ -0,0 +1,112 @@ +/* + meinOS - A unix-like x86 microkernel operating system + Copyright (C) 2008 Janosch Gräf + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include + +#include "helper.h" + +static rc_script_t *get_rc_scripts(int runlevel,char prefix,size_t *size) { + rc_script_t *scripts = NULL; + size_t i; + char *dir_path = rcd_path(runlevel); + DIR *dir = opendir(dir_path); + + if (dir!=NULL) { + while (1) { + struct dirent *dirent = readdir(dir); + if (dirent==NULL) break; + else if (dirent->d_name[0]==prefix) { + scripts = realloc(scripts,(i+1)*sizeof(rc_script_t)); + parse_rc_script(scripts+i,dir_path,dirent->d_name); + i++; + } + } + if (size!=NULL) *size = i; + return scripts; + } + else return NULL; +} + +int main(int argc,char *argv[]) { + size_t i,j,num_kills,num_starts; + + if (argc<2) { + fprintf(stderr,"rc: Runlevel parameter missing.\n"); + return 1; + } + + int newrl = str_to_runlevel(argv[1]); + if (newrl==-1) { + fprintf(stderr,"rc: Invalid runlevel: %s\n",argv[1]); + return 1; + } + + int oldrl = get_runlevel(); + + printf("rc: Switching from runlevel %d to runlevel %d\n",oldrl,newrl); + + // get scripts + rc_script_t *kills = get_rc_scripts(oldrl,'K',&num_kills); + if (kills==NULL) { + fprintf(stderr,"rc: Cannot get kill scripts\n"); + } + + rc_script_t *starts = get_rc_scripts(newrl,'S',&num_starts); + if (starts==NULL) { + fprintf(stderr,"rc: Cannot get start scripts\n"); + } + + // sort out script that are in old and new runlevel + for (i=0;i. */ -#include -#include #include +#include #include -#include int main() { pid_t child; -dbgmsg("test: Hello World\n"); -while (1); + int p[2]; if (pipe(p)==0) { dbgmsg("p[0] = %d\n",p[0]); @@ -50,5 +47,5 @@ while (1); else dbgmsg("pipe() failed: (#%d) %s\n",errno,strerror(errno)); while (1); - + return 0; } diff --git a/files/etc/init.d/com b/files/etc/init.d/com new file mode 100644 index 0000000..79c5e80 --- /dev/null +++ b/files/etc/init.d/com @@ -0,0 +1,10 @@ +#!/bin/sh + +PIDFILE=/var/run/com.pid + +case "$1" in + start) + com + ;; + stop) + kill `cat $PIDFILE` diff --git a/files/etc/init.d/dma b/files/etc/init.d/dma new file mode 100644 index 0000000..9a7a6cf --- /dev/null +++ b/files/etc/init.d/dma @@ -0,0 +1,2 @@ +#!/bin/sh +dma diff --git a/files/etc/init.d/pci b/files/etc/init.d/pci new file mode 100644 index 0000000..935e09e --- /dev/null +++ b/files/etc/init.d/pci @@ -0,0 +1,2 @@ +#!/bin/sh +pci diff --git a/files/etc/init.d/psdev b/files/etc/init.d/psdev new file mode 100644 index 0000000..25d59cf --- /dev/null +++ b/files/etc/init.d/psdev @@ -0,0 +1,2 @@ +#!/bin/sh +psdev diff --git a/files/etc/init.d/ramdisk b/files/etc/init.d/ramdisk new file mode 100644 index 0000000..e9c5375 --- /dev/null +++ b/files/etc/init.d/ramdisk @@ -0,0 +1,4 @@ +#!/bin/sh +# TODO: Has this to be done by fstab? +ramdisk +mount -t ramdisk / diff --git a/files/etc/init.d/vterm b/files/etc/init.d/vterm new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/files/etc/init.d/vterm @@ -0,0 +1 @@ + diff --git a/files/etc/inittab b/files/etc/inittab new file mode 100644 index 0000000..98dab43 --- /dev/null +++ b/files/etc/inittab @@ -0,0 +1,23 @@ +# The default runlevel is defined here +id:2:initdefault: + +# First script to be executed, if not booting in emergency (-b) mode +si::bootwait:/etc/init.d/boot + +# /etc/init.d/rc takes care of runlevel handling +# +# runlevel 0 is System halt (Do not use this for initdefault!) +# runlevel 1 is Single user mode +# runlevel 2 is Local multiuser without remote network (e.g. NFS) +# runlevel 3 is Full multiuser with network +# runlevel 4 is Not used +# runlevel 5 is Full multiuser with network and xdm +# runlevel 6 is System reboot (Do not use this for initdefault!) +# +l0:0:wait:/etc/init.d/rc 0 +l1:1:wait:/etc/init.d/rc 1 +l2:2:wait:/etc/init.d/rc 2 +l3:3:wait:/etc/init.d/rc 3 +#l4:4:wait:/etc/init.d/rc 4 +l5:5:wait:/etc/init.d/rc 5 +l6:6:wait:/etc/init.d/rc 6 diff --git a/files/etc/keyboard_layouts/IGNORE b/files/etc/keyboard_layouts/IGNORE new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/files/etc/keyboard_layouts/IGNORE @@ -0,0 +1 @@ + diff --git a/files/grub/menu.lst b/files/grub/menu.lst index 23ca802..021e242 100755 --- a/files/grub/menu.lst +++ b/files/grub/menu.lst @@ -8,14 +8,12 @@ timeout 5 title meinOS - kernel 2 kernel /kernel2 -# @todo generate this header from some config file in /etc/init.d module /bin/init module /bin/vfs module /bin/devfs module /bin/ata module /bin/cdrom module /bin/iso9660 -#module /bin/console -module /bin/vterm +#module /bin/vterm module /bin/init2 boot diff --git a/files/var/db/IGNORE b/files/var/db/IGNORE new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/files/var/db/IGNORE @@ -0,0 +1 @@ + diff --git a/files/var/run/utmp b/files/var/run/utmp new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/files/var/run/utmp @@ -0,0 +1 @@ + diff --git a/files/var/tmp/IGNORE b/files/var/tmp/IGNORE new file mode 100644 index 0000000..8d1c8b6 --- /dev/null +++ b/files/var/tmp/IGNORE @@ -0,0 +1 @@ + diff --git a/include/syscalls.h b/include/syscalls.h index e4df086..9661361 100755 --- a/include/syscalls.h +++ b/include/syscalls.h @@ -98,32 +98,34 @@ #define SYSCALL_PROC_SYSTEM 64 /* ONLY FOR SYSTEM */ #define SYSCALL_PROC_JUMP 65 /* ONLY FOR SYSTEM */ #define SYSCALL_PROC_CREATESTACK 66 /* ONLY FOR SYSTEM */ -#define SYSCALL_PROC_WAITPID 67 +#define SYSCALL_PROC_GETSTACK 67 /* ONLY FOR SYSTEM */ +#define SYSCALL_PROC_SETSTACK 68 /* ONLY FOR SYSTEM */ +#define SYSCALL_PROC_WAITPID 69 // I/O port -#define SYSCALL_IO_REG 68 /* ONLY FOR ROOT */ -#define SYSCALL_IO_UNREG 69 /* ONLY FOR ROOT */ +#define SYSCALL_IO_REG 70 /* ONLY FOR ROOT */ +#define SYSCALL_IO_UNREG 71 /* ONLY FOR ROOT */ // Timer -#define SYSCALL_TIME_HANDLER 70 -#define SYSCALL_TIME_SLEEP 71 -#define SYSCALL_TIME_USLEEP 72 -#define SYSCALL_TIME_GETTICKS 73 +#define SYSCALL_TIME_HANDLER 72 +#define SYSCALL_TIME_SLEEP 73 +#define SYSCALL_TIME_USLEEP 74 +#define SYSCALL_TIME_GETTICKS 75 // IRQ -#define SYSCALL_IRQ_HANDLER 74 /* ONLY FOR ROOT */ -#define SYSCALL_IRQ_SLEEP 75 /* ONLY FOR ROOT */ +#define SYSCALL_IRQ_HANDLER 76 /* ONLY FOR ROOT */ +#define SYSCALL_IRQ_SLEEP 77 /* ONLY FOR ROOT */ // Signal -#define SYSCALL_SIG_SETUP 76 -#define SYSCALL_SIG_SEND 77 +#define SYSCALL_SIG_SETUP 78 +#define SYSCALL_SIG_SEND 79 // Misc -#define SYSCALL_MISC_BIOSINT 78 /* ONLY FOR ROOT */ +#define SYSCALL_MISC_BIOSINT 80 /* ONLY FOR ROOT */ // Debug /// @deprecated Only for debugging -#define SYSCALL_PUTSN 79 -#define SYSCALL_FOURTYTWO 80 +#define SYSCALL_PUTSN 81 +#define SYSCALL_FOURTYTWO 82 #endif diff --git a/kernel2/Makefile b/kernel2/Makefile dissimilarity index 69% index f6a85c1..5212d29 100644 --- a/kernel2/Makefile +++ b/kernel2/Makefile @@ -1,132 +1,65 @@ --include ../Makefile.config - -OBJFILES = aaacrt0.o \ - biosint.o \ - cpu.o \ - elf.o \ - gdt.o \ - idt.o \ - interrupt.o \ - ioport.o \ - ipc.o \ - isr.o \ - kprint.o \ - lapic.o \ - main.o \ - malloc.o \ - memkernel.o \ - memphys.o \ - memuser.o \ - msg.o \ - multiboot.o \ - paging.o \ - pic.o \ - procm.o \ - rpc.o \ - sem.o \ - shm.o \ - signal.o \ - swap.o \ - syscall.o \ - tss.o \ - vga.o \ - vm86.o \ - dyncall.o \ - llist.o \ - pack.o \ - perm.o \ - tree.o \ - string.o \ - strings.o \ - ctype.o - -all: kernel2 kernel2.objdump - cp $< ../files - -kernel2: $(OBJFILES) libgcc.a - $(KERNEL_LD) -T link.ld -o $@ $(OBJFILES) libgcc.a - -aaacrt0.o: crt0.asm - $(KERNEL_ASM) -f elf -o $@ $^ -biosint.o: biosint.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -cpu.o: cpu.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -elf.o: elf.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -gdt.o: gdt.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -idt.o: idt.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -interrupt.o: interrupt.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -ioport.o: ioport.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -ipc.o: ipc.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -isr.o: isr.asm - $(KERNEL_ASM) -f elf -o $@ $^ -kprint.o: kprint.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -lapic.o: lapic.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -main.o: main.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -malloc.o: malloc.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -memkernel.o: memkernel.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -memphys.o: memphys.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -memuser.o: memuser.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -msg.o: msg.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -multiboot.o: multiboot.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -paging.o: paging.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -pic.o: pic.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -procm.o: procm.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -rpc.o: rpc.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -sem.o: sem.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -shm.o: shm.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -signal.o: signal.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -swap.o: swap.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -syscall.o: syscall.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -tss.o: tss.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -vga.o: vga.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -vm86.o: vm86.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -dyncall.o: ../lib/libmeinos/dyncall.asm - $(KERNEL_ASM) -f elf -o $@ $^ -llist.o: ../lib/libmeinos/llist.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -pack.o: ../lib/libmeinos/pack.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -perm.o: ../lib/libmeinos/perm.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -tree.o: ../lib/libmeinos/tree.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -string.o: ../lib/stdlibc/string.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -strings.o: ../lib/stdlibc/strings.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ -ctype.o: ../lib/stdlibc/ctype.c - $(KERNEL_CC) $(KERNEL_CFLAGS) -o $@ $^ - -kernel2.objdump: kernel2 - $(KERNEL_OBJDUMP) -d -S $^ > $@ - -clean: - rm -f $(OBJFILES) kernel2 *.objdump +-include ../Makefile.config + +CC = $(KERNEL_CC) +CFLAGS = $(KERNEL_CFLAGS) + +OBJFILES = aaacrt0.o \ + biosint.o \ + cpu.o \ + elf.o \ + gdt.o \ + idt.o \ + interrupt.o \ + ioport.o \ + ipc.o \ + isr.o \ + kprint.o \ + lapic.o \ + main.o \ + malloc.o \ + memkernel.o \ + memphys.o \ + memuser.o \ + msg.o \ + multiboot.o \ + paging.o \ + pic.o \ + procm.o \ + rpc.o \ + sem.o \ + shm.o \ + signal.o \ + swap.o \ + syscall.o \ + tss.o \ + vga.o \ + vm86.o \ + \ + ../lib/libmeinos/dyncall.o \ + ../lib/libmeinos/llist.o \ + ../lib/libmeinos/pack.o \ + ../lib/libmeinos/perm.o \ + ../lib/libmeinos/tree.o \ + ../lib/stdlibc/string.o \ + ../lib/stdlibc/strings.o \ + ../lib/stdlibc/ctype.o + +all: kernel2 kernel2.objdump + cp $< ../files + +kernel2: $(OBJFILES) libgcc.a + $(KERNEL_LD) -T link.ld -o $@ $(OBJFILES) libgcc.a + +aaacrt0.o: crt0.asm + $(KERNEL_ASM) -f elf -o $@ $^ +isr.o: isr.asm + $(KERNEL_ASM) -f elf -o $@ $^ + +../lib/libmeinos/dyncall.o: ../lib/libmeinos/dyncall.asm + $(KERNEL_ASM) -f elf -o $@ $^ + +kernel2.objdump: kernel2 + $(KERNEL_OBJDUMP) -d -S $^ > $@ + +clean: + rm -f $(OBJFILES) kernel2 *.objdump diff --git a/kernel2/include/memmap.h b/kernel2/include/memmap.h index a20601c..f555a8f 100644 --- a/kernel2/include/memmap.h +++ b/kernel2/include/memmap.h @@ -56,6 +56,9 @@ #define FREEPHYS_ADDRESS (KERNELPD_ADDRESS+KERNELPD_SIZE) ///< phys address of free (phys) pages #define FREEPHYS_SIZE (PHYS_MEMORY-FREEPHYS_ADDRESS) ///< phys size of free (phys) pages +#define USERSTACK_END BUFPAGE_ADDRESS ///< virt end of user stack +#define USERSTACK_MAXSIZE (1024*PAGE_SIZE) ///< virt max size of user stack + #define BUFPAGE_ADDRESS (4092*MBYTES-4*KBYTES) ///< Buffer page for writing/reading physical memory #define PAGETABLES_ADDRESS (4092*MBYTES) ///< loaded Pagetables #define PAGEDIR_ADDRESS (4*GBYTES-4*KBYTES) ///< loaded Pagedir diff --git a/kernel2/include/memuser.h b/kernel2/include/memuser.h index b3bac4b..859a067 100644 --- a/kernel2/include/memuser.h +++ b/kernel2/include/memuser.h @@ -53,6 +53,7 @@ int memuser_free_syscall(void *page); void *memuser_getphysaddr(addrspace_t *addrspace,void *virt); void *memuser_getphysaddr_syscall(void *virt); void *memuser_create_stack(addrspace_t *addrspace); +int memuser_expand_stack(addrspace_t *addrspace); int memuser_destroy_stack(addrspace_t *addrspace); int memuser_pagefault(void *addr); int memuser_alloc_at(addrspace_t *addrspace,void *addr,void *phys,int writable); diff --git a/kernel2/include/procm.h b/kernel2/include/procm.h index aabfa7e..f5c5077 100644 --- a/kernel2/include/procm.h +++ b/kernel2/include/procm.h @@ -166,5 +166,7 @@ int proc_memalloc(pid_t proc_pid,void *virt,int writable,int swappable); int proc_system(pid_t proc_pid,int system); int proc_jump(pid_t proc_pid,void *dest); int *proc_createstack(pid_t proc_pid); +int *proc_getstack(pid_t proc_pid); +int proc_setstack(pid_t proc_pid,int *stack); #endif diff --git a/kernel2/memuser.c b/kernel2/memuser.c index b0b0f31..1ded995 100644 --- a/kernel2/memuser.c +++ b/kernel2/memuser.c @@ -187,7 +187,9 @@ void *memuser_alloc(addrspace_t *addrspace,size_t count,int swappable) { size_t i; for (i=0;ipagedir).exists) memuser_create_pagetable(addrspace->pagedir,virt); + if (!paging_getpde_pd(virt,addrspace->pagedir).exists) { + memuser_create_pagetable(addrspace->pagedir,virt); + } pte_t pte; memset(&pte,0,sizeof(pte)); pte.exists = 1; @@ -277,9 +279,19 @@ void *memuser_getphysaddr_syscall(void *virt) { * @return Stack address */ void *memuser_create_stack(addrspace_t *addrspace) { - addrspace->stack = memuser_alloc(addrspace,PAGE_SIZE,0); - if (addrspace->stack!=NULL) return addrspace->stack+PAGE_SIZE-4; - else return NULL; + addrspace->stack = (void*)USERSTACK_END; + memuser_expand_stack(addrspace); + return addrspace->stack+PAGE_SIZE-4; +} + +/** + * Expands stack + * @param addrspace Address space of stack to expand + * @return Success? + */ +int memuser_expand_stack(addrspace_t *addrspace) { + addrspace->stack -= PAGE_SIZE; + return memuser_alloc_at(addrspace,addrspace->stack,NULL,1); } /** @@ -294,42 +306,51 @@ int memuser_destroy_stack(addrspace_t *addrspace) { /** * User memory pagefault handler * @param addr Address - * @return If Pagefault is a "real" Pagefault + * @return -1 If Pagefault is a "real" Pagefault, else 0 */ int memuser_pagefault(void *addr) { addrspace_t *addrspace = proc_current->addrspace; void *page = PAGEDOWN(addr); pte_t pte = paging_getpte(page); - if (!pte.exists) return -1; - else if (pte.swapped && pte.in_memory==0) { - kprintf("kernel: Catched access to out-swapped memory\n"); - if (swap_in(proc_current,page)!=-1) { - llist_remove(addrspace->pages_swapped,llist_find(addrspace->pages_swapped,page)); - llist_push(addrspace->pages_loaded,page); - swap_remove(proc_current,page); + + if (!pte.exists) { + if (addrstack && addr>(void*)(USERSTACK_END-USERSTACK_MAXSIZE)) { // expand stack + memuser_expand_stack(addrspace); return 0; } - else return -1; + else return -1; // pagefault } - else if (pte.cow && pte.in_memory==1) { - void *old = PAGE2ADDR(pte.page); - void *new = memphys_alloc(); - pte.page = ADDR2PAGE(new); - pte.cow = 0; - pte.writable = 1; - paging_setpte(page,pte); - paging_physread(page,old,PAGE_SIZE); - return 0; - } - else if (pte.in_memory==0) { - pte.page = ADDR2PAGE(memphys_alloc()); - pte.in_memory = 1; - paging_setpte(page,pte); - llist_remove(addrspace->pages_imaginary,llist_find(addrspace->pages_imaginary,page)); - llist_push(addrspace->pages_loaded,page); - return 0; + else { + if (pte.swapped && pte.in_memory==0) { // swap + kprintf("kernel: Catched access to out-swapped memory\n"); + if (swap_in(proc_current,page)!=-1) { + llist_remove(addrspace->pages_swapped,llist_find(addrspace->pages_swapped,page)); + llist_push(addrspace->pages_loaded,page); + swap_remove(proc_current,page); + return 0; + } + else return -1; + } + else if (pte.cow && pte.in_memory==1) { // copy on write FIXME + void *old = PAGE2ADDR(pte.page); + void *new = memphys_alloc(); + pte.page = ADDR2PAGE(new); + pte.cow = 0; + pte.writable = 1; + paging_setpte(page,pte); + paging_physread(page,old,PAGE_SIZE); + return 0; + } + else if (pte.in_memory==0) { // imaginary page + pte.page = ADDR2PAGE(memphys_alloc()); + pte.in_memory = 1; + paging_setpte(page,pte); + llist_remove(addrspace->pages_imaginary,llist_find(addrspace->pages_imaginary,page)); + llist_push(addrspace->pages_loaded,page); + return 0; + } + else return -1; // pagefault } - else return -1; } /** @@ -343,7 +364,6 @@ int memuser_alloc_at(addrspace_t *addrspace,void *addr,void *phys,int writable) if (!paging_getpde_pd(addr,addrspace->pagedir).exists) { memuser_create_pagetable(addrspace->pagedir,addr); } - pte_t pte = paging_getpte_pd(addr,addrspace->pagedir); memset(&pte,0,sizeof(pte)); pte.exists = 1; @@ -355,6 +375,7 @@ int memuser_alloc_at(addrspace_t *addrspace,void *addr,void *phys,int writable) pte.page = ADDR2PAGE(phys); paging_setpte_pd(addr,pte,addrspace->pagedir); llist_push(addrspace->pages_loaded,addr); + return 0; } diff --git a/kernel2/procm.c b/kernel2/procm.c index b678f98..cbb0372 100644 --- a/kernel2/procm.c +++ b/kernel2/procm.c @@ -67,6 +67,8 @@ int proc_init() { if (syscall_create(SYSCALL_PROC_SYSTEM,proc_system,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_JUMP,proc_jump,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_CREATESTACK,proc_createstack,1)==-1) return -1; + if (syscall_create(SYSCALL_PROC_GETSTACK,proc_getstack,1)==-1) return -1; + if (syscall_create(SYSCALL_PROC_SETSTACK,proc_setstack,2)==-1) return -1; if (syscall_create(SYSCALL_PROC_WAITPID,proc_waitpid,3)==-1) return -1; return 0; } @@ -326,11 +328,9 @@ pid_t proc_getparent(pid_t pid) { pid_t proc_getchild(pid_t pid,size_t i) { proc_t *proc = proc_find(pid); if (proc!=NULL) { - if (proc->parent!=NULL) { - proc_t *child = llist_get(proc->parent->children,i); - if (child==NULL) return -1; - else return child->pid; - } + proc_t *child = llist_get(proc->children,i); + if (child==NULL) return -1; + else return child->pid; } return 0; } @@ -820,7 +820,13 @@ int proc_jump(pid_t proc_pid,void *dest) { int *proc_createstack(pid_t proc_pid) { if (proc_current->system) { proc_t *proc = proc_find(proc_pid); - if (proc!=NULL && proc->addrspace->stack==NULL) { + if (proc!=NULL) { + if (proc->addrspace->stack!=NULL) { + /// @todo IMPORTANT! memuser_destroy_stack() seems to free stack of proc_current. See memuser_free. Something is weird there. + /*memuser_load_addrspace(proc->addrspace); + memuser_destroy_stack(proc->addrspace); + memuser_load_addrspace(proc_current->addrspace);*/ + } int *stack = memuser_create_stack(proc->addrspace); proc->registers.esp = (uint32_t)stack; return stack; @@ -828,3 +834,24 @@ int *proc_createstack(pid_t proc_pid) { } return NULL; } + +int *proc_getstack(pid_t proc_pid) { + if (proc_current->system) { + proc_t *proc = proc_find(proc_pid); + if (proc!=NULL) { + return proc->addrspace->stack; + } + } + return NULL; +} + +int proc_setstack(pid_t proc_pid,int *stack) { + if (proc_current->system) { + proc_t *proc = proc_find(proc_pid); + if (proc!=NULL) { + proc->addrspace->stack = stack; + return 0; + } + } + return -1; +} diff --git a/run_stacktrace.sh b/run_stacktrace.sh index dddf0e2..7577dae 100755 --- a/run_stacktrace.sh +++ b/run_stacktrace.sh @@ -4,5 +4,4 @@ make && \ mkisofs -R -b grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o cdrom.iso files/ && \ ./run_vm.sh | tee /tmp/meinos.output && \ cat /tmp/meinos.output | ./stacktrace && \ -rm -f /tmp/meinos.output && \ -make clean \ No newline at end of file +rm -f /tmp/meinos.output -- 2.11.4.GIT