diff options
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | README.md | 11 | ||||
| -rw-r--r-- | fs/elf.c | 13 | ||||
| -rw-r--r-- | fs/ext2.c | 302 | ||||
| -rw-r--r-- | fs/ext2.h | 33 | ||||
| -rw-r--r-- | fs/fs.c | 5 | ||||
| -rw-r--r-- | fs/fs.h | 6 | ||||
| -rw-r--r-- | interface/syscalls.c | 4 | ||||
| -rw-r--r-- | kernel/interrupts.c | 5 | ||||
| -rw-r--r-- | kernel/kernel.c | 13 | ||||
| -rw-r--r-- | kernel/kernel.h | 2 | ||||
| -rw-r--r-- | kernel/scheduler.c | 182 | ||||
| -rw-r--r-- | kernel/scheduler.h | 15 | ||||
| -rw-r--r-- | kernel/syscalls.c | 73 | ||||
| -rw-r--r-- | kernel/syscalls.h | 1 | ||||
| -rw-r--r-- | kernel/vmem.c | 58 | ||||
| -rw-r--r-- | kernel/vmem.h | 1 | ||||
| -rw-r--r-- | userspace/Makefile | 2 | ||||
| -rw-r--r-- | userspace/foolshell.c | 26 | ||||
| -rw-r--r-- | userspace/init.c | 10 | ||||
| -rw-r--r-- | userspace/test.txt | 5 |
21 files changed, 431 insertions, 337 deletions
@@ -29,6 +29,7 @@ CFLAGS+=-I/home/miguel/temp/foolos/usr/i686-foolos/include/ CFLAGS+=-I./asm CFLAGS+=-I./kernel CFLAGS+=-I./driver +CFLAGS+=-I./fs CFLAGS+=-gstabs #CFLAGS+=-fstack-protector-all @@ -86,16 +86,17 @@ FoolOS is tested/developed on the following emulators/machines Todos ----- -* pipe\_syscall * Newlib errno / return value / argv / env -* Cleanup Virtual Memory Manager / Flush TLB (?) +* pipe\_syscall +* DMA where possible! * Mouse & KB processing in seperate task. -* Kernel Stuff Reent? -* Posix getdents and cleanup syscalls +* Kernel Stuff Reentrancy? +* Cleanup syscalls * Writing to ext2 RAM-image * Mutexes +* create/remove pages on demand (sbrk, stack, load prog) -* GCC optimizations (break kernel?) +* GCC optimizations (break kernel?) / volatile?? * Ethernet driver E1000 / NS2000 & Networking stack (ipxe network drivers?) @@ -80,12 +80,10 @@ void elf_multiboot_read(multiboot_information *info) uint32_t nameidx=shdr[i].sh_name; char *name=shdr[stridx].sh_addr+nameidx; klog("section %d: %s addr: 0x%08X offset: 0x%08X size: 0x%08X",i,name,shdr[i].sh_addr,shdr[i].sh_offset,shdr[i].sh_size); - - } } -// returns elf entry point +/** returns elf entry point ans et breakpoint to alloc */ uint32_t load_elf(char *name, uint32_t *alloc) { uint32_t ext2_ramimage=VMEM_EXT2_RAMIMAGE; @@ -96,18 +94,17 @@ uint32_t load_elf(char *name, uint32_t *alloc) //TODO: load ELF binary and move this to own compilation unit //load binary - //uint32_t vaddr=0x08000000; uint32_t vaddr=0x08048000; + uint32_t pos=0; klog("loading %s",name); - ext2_check(ext2_ramimage); - ext2_inode_content(ext2_ramimage,inode_nr,vaddr,0x100000); // max ignored?? + ext2_read_inode(ext2_ramimage,inode_nr,vaddr,&pos,4096*64); // max ignored?? klog("ELF File loaded to final destination."); - Elf32_Ehdr *elf; elf=vaddr; + if(elf->e_ident[0]!=0x7f||elf->e_ident[1]!='E'||elf->e_ident[2]!='L'||elf->e_ident[3]!='F') kpanic("ELF mismatch!?"); @@ -159,7 +156,6 @@ uint32_t load_elf(char *name, uint32_t *alloc) klog("p-memsz: 0x%08X",phdr->p_memsz); */ - klog("data: 0x%08X-0x%08X",phdr->p_vaddr,phdr->p_vaddr+phdr->p_filesz); klog("bss: 0x%08X-0x%08X",phdr->p_vaddr+phdr->p_filesz,phdr->p_vaddr+phdr->p_memsz); @@ -185,7 +181,6 @@ uint32_t load_elf(char *name, uint32_t *alloc) *alloc=phdr->p_vaddr+phdr->p_memsz; } - } klog("heap starts at: 0x%08X",*alloc); @@ -10,6 +10,7 @@ #include "fs.h" +// THE SUPERBLOCK typedef struct ext2_superblock_struct { uint32_t inodes_count; @@ -35,7 +36,7 @@ typedef struct ext2_superblock_struct uint16_t gid_reserved; }ext2_superblock; -/* we dont use this yet +/* we dont use this typedef struct ext2_superblock_ext_struct { uint32_t first_inode; @@ -61,6 +62,7 @@ typedef struct ext2_superblock_ext_struct }ext2_superblock_ext; */ +// BLOCKGROUP DESCRIPTOR TABLE typedef struct ext2_blockgroup_desc_struct { uint32_t addr_block_bitmap; @@ -97,271 +99,207 @@ typedef struct ext2_inode_struct uint32_t indirect2; uint32_t indirect3; uint32_t gen_num; - uint32_t later1; // will be implemented later by the fooldriver + uint32_t acl; uint32_t size_high; uint32_t frag; uint32_t os_spec2[3]; }ext2_inode; - -void ram_read(char *in,char *out,int size, int count) +static ext2_superblock *ext2_check(uint32_t ext2_start_addr) { - for(int i=0;i<size*count;i++) - { - out[i]=in[i]; + ext2_superblock *super=ext2_start_addr+1024; + if(super->ext2_sig!=0xef53){ + kpanic("no ext2 signature found, where ram-image expected at addr: 8X%08X",ext2_start_addr+1024); } + return super; } -int ext2_check(uint8_t *ram) +void ext2_dump_info(uint32_t ext2_start_addr) { - ext2_superblock super; -// ext2_superblock_ext super_ext; - uint8_t *ptr=ram+1024; - ram_read((char*)ptr,&super,sizeof(super),1); - - if(super.ext2_sig!=0xef53){ - klog("addr: 0x%08X",ram); - kpanic("no ext2 signature found, where ram-image expected"); - } - return 1; + ext2_superblock *super=ext2_check(ext2_start_addr); + klog("ext2 fs version %d.%d found",super->version_major, super->version_minor); + klog("block_size %d",1024<<super->block_size); + klog("blocks per group %d",super->blocks_per_group); + klog("inodes per group %d",super->inodes_per_group); + klog("free inodes: %d / %d",super->inodes_unalloc_count,super->inodes_count+super->inodes_unalloc_count); + klog("free blocks: %d / %d (%d reserved)",super->blocks_unalloc_count,super->blocks_count+super->blocks_unalloc_count,super->blocks_reserved_count); } -ext2_inode ext2_get_inode(uint8_t *ram,int inode_num) +// inode numbers start a 1! +ext2_inode *ext2_get_inode(uint32_t ext2_start_addr,uint32_t inode_num) { + uint32_t ptr; //will temporarily hold adress of some structs - // get basic shit from superblock! - ext2_superblock super; - ext2_blockgroup_desc desc; - ext2_inode inode; - - uint8_t *ptr=ram+1024; - ram_read((char*)ptr,&super,sizeof(super),1); - if(super.ext2_sig!=0xef53) - { - klog("addr: 0x%08X",ram); - kpanic("no ext2 signature found, where ram-image expected!"); - } - - int block_group=(inode_num-1)/super.inodes_per_group; + // check signature and get pointer to superblock. + ext2_superblock *super=ext2_check(ext2_start_addr); - // get descrtptor for our blockgroup! - //TODO: only correct for 1024bytes/block. read more than one!!! - int block_size=1024; - int descriptor_start_block=2; + // get blockgroup descriptor for the block group containing + // our inode. + int block_group=(inode_num-1)/super->inodes_per_group; + int descriptor_start_block=1024<<super->block_size==1024?2:1; - ptr=ram+block_size*descriptor_start_block; - ptr+=sizeof(desc)*block_group; // skip to our descriptor; + ptr=ext2_start_addr+(1024<<super->block_size)*descriptor_start_block; + ptr+=sizeof(ext2_blockgroup_desc)*block_group; // skip to descriptor for our inode's block + ext2_blockgroup_desc *desc=ptr; - ram_read((char*)ptr,&desc,sizeof(desc),1); // read descriptor - - // read our inode; - ptr=ram+block_size*desc.addr_inode_table; - ptr+=128*((inode_num-1)%super.inodes_per_group); - - ram_read((char*)ptr,&inode,sizeof(inode),1); //get inode 2 (rood-directory) + // read the inode + ptr=ext2_start_addr+(1024<<super->block_size)*desc->addr_inode_table; + ptr+=128*((inode_num-1)%super->inodes_per_group); + ext2_inode *inode=ptr; return inode; - } -void* ext2_get_blockstart(void* start, uint32_t block_size, uint32_t block_idx) +static void* ext2_get_blockstart(void* start, uint32_t block_size, uint32_t block_idx) { return (start+block_size*block_idx); } -void* ext2_get_indirectstart(void *start, uint32_t block_size, uint32_t indirect1_idx, uint32_t block_idx) +static void* ext2_get_indirectstart(void *start, uint32_t block_size, uint32_t indirect1_idx, uint32_t block_idx) { uint32_t *indirect_ptr=ext2_get_blockstart(start,block_size,indirect1_idx); void *ptr=ext2_get_blockstart(start,block_size,indirect_ptr[block_idx]); return ptr; } -void* ext2_get_indirectstart_double(void *start, uint32_t block_size, uint32_t indirect2_idx, uint32_t block_idx) +static void* ext2_get_indirectstart_double(void *start, uint32_t block_size, uint32_t indirect2_idx, uint32_t block_idx) { - //doubly indirect list uint32_t *dil=ext2_get_blockstart(start,block_size,indirect2_idx); int indirect1_idx=block_idx/(block_size/4); int idx=block_idx%(block_size/4); - //klog("bl: %d : %d / %d",block_idx,indirect1_idx, idx); return ext2_get_indirectstart(start,block_size,dil[indirect1_idx],idx); } -int ext2_inode_content(char *ram,int inode_nr,uint8_t *ramdest,int max) +// +uint32_t ext2_inode_blockstart(uint32_t ext2_start_addr,uint32_t inode_nr,uint32_t block) { - ext2_check((uint8_t *)ram); - ext2_inode inode=ext2_get_inode((uint8_t*)ram,inode_nr); - - int pos=0; - int block=0; - int block_size=1024; - int block_counter=0; - uint8_t *ptr=ext2_get_blockstart(ram,block_size,inode.direct_pointer[0]); - int sum=0; - int count=0; + ext2_superblock *super=ext2_check(ext2_start_addr); + int block_size=1024<<super->block_size; - klog("Loading %d.%d bytes",inode.size_high, inode.size_low); + ext2_inode *inode=ext2_get_inode(ext2_start_addr,inode_nr); - if(inode.size_high>0)kpanic("inode with high.size unsupported, i am sorry."); + uint8_t *ptr=0; - while(pos<inode.size_low) // TODO: use size high! + if(block<12) { - ramdest[pos]=*ptr; - - sum = (sum >> 1) + ((sum & 1) << 15); - sum+=(int)*ptr; - sum&=0xffff; - count++; - - ptr++; - block_counter++; - pos++; - - if(block_counter>=block_size) - { - block++; - - if(block<12) - { - ptr=ext2_get_blockstart(ram,block_size,inode.direct_pointer[block]); - - } - else if(block-12<block_size/4) - { - ptr=ext2_get_indirectstart(ram,block_size,inode.indirect1,block-12); - } - - else if(block-12-block_size/4<1024/4*1024/4) - { - ptr=ext2_get_indirectstart_double(ram,block_size,inode.indirect2,block-12-block_size/4); - } - else - { - kpanic("Triple Indirect Block Pointers not supported yet, file is too big to load, sorry!"); - } - - - block_counter=0; - } - - + ptr=ext2_get_blockstart(ext2_start_addr,block_size,inode->direct_pointer[block]); } - klog("Fool Check Sum: 0x%08X for %d bytes",sum,count); - return 1; + else if(block-12<block_size/4) + { + ptr=ext2_get_indirectstart(ext2_start_addr,block_size,inode->indirect1,block-12); + } + + else if(block-12-block_size/4<1024/4*1024/4) + { + ptr=ext2_get_indirectstart_double(ext2_start_addr,block_size,inode->indirect2,block-12-block_size/4); + } + + return ptr; } -int ext2_filename_to_inode_traverse(uint8_t *ram, char *path,int inode_start) +static uint32_t ext2_filename_to_inode_traverse(uint32_t ext2_start_addr, char *path,uint32_t inode_start) { + uint32_t len=0; + // true if final filename bool final=false; // skip leading slashes while(*path=='/')path++; char *first=path; - while(*path!='/'&&*path!=0)path++; - char *last=path; + // find end of dir or file name + while(path[len]!='/'&&path[len]!=0)len++; - if(*path==0)final=true; - else(*path=0); + // no more slashes + if(path[len]==0)final=true; - klog("looking for %s '%s' in inode: %d",final?"file":"dir",first,inode_start); + //klog("looking for %s '%s' in inode: %d",final?"file":"dir",first,inode_start); - fs_dirent dirs[25]; - int count= ext2_read_dir(ram, inode_start,dirs,25); // get dir - - for(int i=0;i<count;i++) + uint32_t pos=0; + while(1) { - if(!strcmp_l(first,dirs[i].name,0)) + fs_dirent dirs; + uint32_t ret=ext2_read_dir(VMEM_EXT2_RAMIMAGE,inode_start, &dirs,&pos); + if(!ret)break; + + if(!strcmp_l(first,dirs.name,len)) { - klog("found: %s (%s)",first,dirs[i].type==FS_FILE_TYPE_DIR?"dir":"file"); - if(final)return dirs[i].inode; - return ext2_filename_to_inode_traverse(ram,last+1,dirs[i].inode); + klog("found inode %d %s%s (in inode %d)",dirs.inode,dirs.name,dirs.type==FS_FILE_TYPE_DIR?"/ ":" ",inode_start); + if(final)return dirs.inode; + return ext2_filename_to_inode_traverse(ext2_start_addr,&path[len]+1,dirs.inode); } - //klog("no match: %s",dirs[i].name); } - klog("file not found!"); - return -1; - - - + return 0; } -int ext2_filename_to_inode(uint8_t *ram, char *path) -{ +uint32_t ext2_filename_to_inode(uint32_t ext2_start_addr, char *path) +{ if(!strcmp_l(path,"/",0))return 2; // root is inode 2 by definition - - char buf[256]; - for(int i=0;i<256;i++) - { - buf[i]=path[i]; - if(buf[i]==0)break; - } - - return ext2_filename_to_inode_traverse(ram,buf,2); + return ext2_filename_to_inode_traverse(ext2_start_addr,path,2); } -int ext2_read_dir(uint8_t *ram, int inode_nr,fs_dirent *dirs,int max) +uint32_t ext2_read_inode(uint32_t ext2_start_addr, int inode_nr, char *buf, uint32_t *pos, uint32_t max_size) { + uint32_t count=0; - klog("read_dir : max: %d",max); - ext2_inode inode=ext2_get_inode(ram,inode_nr); - - char buf[256]; - int block_size=1024; - uint8_t *ptr=ram+block_size*inode.direct_pointer[0]; //TODO: use other pointers in future! - - int pos=0; - int c=0; + ext2_superblock *super=ext2_check(ext2_start_addr); + ext2_inode *inode=ext2_get_inode(ext2_start_addr,inode_nr); + uint32_t block_size=1024<<super->block_size; - while(pos<inode.size_low) // use size high? + while((*pos)<inode->size_low) { - if(c==max)break; + if(count==max_size)return count; - // read dir data - ext2_dir dir; - ram_read((char*)ptr,&dir,sizeof(dir),1); + // get ptr to pos + uint32_t block=(*pos)/block_size; + uint32_t ptr = ext2_inode_blockstart(ext2_start_addr,inode_nr,block)+((*pos)%block_size); - // read name - ptr+=sizeof(dir); - ram_read((char*)ptr,&buf,sizeof(char),dir.name_length_low); - ptr+=dir.name_length_low; - buf[dir.name_length_low]=0; + buf[count]=*((char *)ptr); - // increment memory pointer and position - ptr+=dir.size-8-dir.name_length_low; - pos+=dir.size; + *pos+=1; + count++; + } - // copy data over to dirs - dirs[c].inode=dir.inode; + return count; - ext2_inode inode_current=ext2_get_inode(ram,dir.inode); +} - if(inode_current.permissions&0x4000) - { - dirs[c].type=FS_FILE_TYPE_DIR; - } - else - { - dirs[c].type=FS_FILE_TYPE_FILE; - } +int ext2_read_dir(uint32_t ext2_start_addr, int inode_nr, fs_dirent *dirs, uint32_t *pos) +{ + ext2_superblock *super=ext2_check(ext2_start_addr); + ext2_inode *inode=ext2_get_inode(ext2_start_addr,inode_nr); + uint32_t block_size=1024<<super->block_size; - int i=0; - do{ - dirs[c].name[i]=buf[i]; - i++; - }while(buf[i-1]!=0); + while(*pos<inode->size_low) + { + // get ptr to pos + uint32_t block=(*pos)/block_size; + uint32_t ptr = ext2_inode_blockstart(ext2_start_addr,inode_nr,block)+((*pos)%block_size); -// klog("name: %s\n",dirs[c].name); + //dir data + ext2_dir *dir=ptr; - c++; + if(dir->inode) //otherwise skip + { + dirs->type=FS_FILE_TYPE_FILE; + ext2_inode *inode_current=ext2_get_inode(ext2_start_addr,dir->inode); + if(inode_current->permissions&0x4000)dirs->type=FS_FILE_TYPE_DIR; + memcpy(dirs->name,ptr+8,dir->name_length_low); + if(dir->name_length_low>255)dirs->name[255]=0; + dirs->name[dir->name_length_low]=0; // null temrinate + dirs->inode=dir->inode; + + *pos+=dir->size; + return 1; + } + *pos+=dir->size; } - - return c; - + return 0; } @@ -1,14 +1,35 @@ /** * @file -// ext2 minidriver +// ext2 in-ram minidriver +// ======================= +// // based on osdev wiki article: http://wiki.osdev.org/Ext2 +// root directory is inode 2 per definition! +// we do not care about files >4gb (no triply linked lists and no size_high) +// we also use only name_length_low so max length is 255 chars +// +// The ext2 data needs to be mapped to a continues ram area (possibly via paging) +// The __ramext2_start_addr__ determines the start of the area in each of the provided +// functions. */ #include <stdint.h> -#include "fs.h" +#include "fs.h" -int ext2_check(uint8_t *ram); -int ext2_inode_content(char *ram,int inode_nr,uint8_t *ramdest,int max); -int ext2_read_dir(uint8_t *ram, int inode_nr,fs_dirent *dirs,int max); -int ext2_filename_to_inode(uint8_t *ram, char *path); +/** klog some basic info about the ext2 fs */ +void ext2_dump_info(uint32_t ext2_start_addr); +/** read up to max characters into buffer from given inode and set __pos__ */ +uint32_t ext2_read_inode(uint32_t ext2_start_addr, int inode_nr, char *buf, uint32_t *pos, uint32_t max_size); + +/** Simiilar to ext2_read_inode but for directory inodes. + * the inode number needs to point to a directory inode + * fills on fs_dirent and sets _pos_ to the position of the next + */ +int ext2_read_dir(uint32_t ext2_start_addr, int inode_nr, fs_dirent *dirs, uint32_t *pos); + +/** get inode number from file path / if not found return 0 */ +uint32_t ext2_filename_to_inode(uint32_t ext2_start_addr, char *path); + +/** get address of first byte of given block for given inode number */ +uint32_t ext2_inode_blockstart(uint32_t ext2_start_addr,uint32_t inode_nr,uint32_t block); @@ -6,15 +6,16 @@ // returns number of entries in the directory specified by name. // fills 0-max into *dirs + int fs_readdir(const char *name,fs_dirent *dirs,int max) { int inode_nr=ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE,name); if(inode_nr<1)return -1; - return ext2_read_dir(VMEM_EXT2_RAMIMAGE, inode_nr,dirs,max); // TODO: hardcoded, fix this + return ext2_read_dir(VMEM_EXT2_RAMIMAGE, inode_nr,dirs,0); // TODO: hardcoded, fix this } void fs_content(char *path, uint32_t dest, uint32_t max_bytes) { int inode= ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE, path); - ext2_inode_content(VMEM_EXT2_RAMIMAGE,inode,dest,max_bytes); +// ext2_inode_content(VMEM_EXT2_RAMIMAGE,inode,dest,max_bytes); } @@ -5,7 +5,6 @@ #include "kernel/multiboot.h" enum FS_FILE_TYPE{ - FS_FILE_TYPE_DIR = 1, FS_FILE_TYPE_FILE = 2 }; @@ -13,10 +12,9 @@ enum FS_FILE_TYPE{ typedef struct fs_dirent_struct { uint32_t inode; - uint32_t offset; - uint16_t length; uint8_t type; - char name[256]; + char name[255]; + }fs_dirent; int fs_readdir(const char *name,fs_dirent *dirs,int max); diff --git a/interface/syscalls.c b/interface/syscalls.c index 11304a8..4acbba5 100644 --- a/interface/syscalls.c +++ b/interface/syscalls.c @@ -105,9 +105,9 @@ int _times(struct tms *buf) return syscall(SYSCALL_TIMES,buf,0,0); } -int _wait(int *status) +int _wait(uint32_t pid) { - return syscall(SYSCALL_WAIT,status,0,0); + return syscall(SYSCALL_WAIT,pid,0,0); } int _stat(const char *file, struct stat *st) diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 5e67105..9e12555 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -56,7 +56,10 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) // mouse and kb if(irq==INTERRUPT_KEYBOARD || irq==INTERRUPT_MOUSE){ uint32_t in=x86_inb(0x60); - if(irq==INTERRUPT_KEYBOARD)keyboard_handle(in); // do this in separate thread! + if(irq==INTERRUPT_KEYBOARD){ + keyboard_handle(in); // do this in separate thread via syscalls? + task_wake_all(); + } // TODO: mouse // test ipi diff --git a/kernel/kernel.c b/kernel/kernel.c index cf9fef9..6f04454 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -12,6 +12,7 @@ #include "vmem.h" //-- clean below headers --// +#include "ext2.h" #include "apic.h" #include "kernel/scheduler.h" @@ -33,7 +34,6 @@ #include "driver/vesa.h" #include "asm_pit.h" - /* F00L 0S Entry point (called directly from asm/multiboot.asm */ void kernel_main(uint32_t eax,uint32_t ebx) { @@ -91,6 +91,10 @@ void kernel_main(uint32_t eax,uint32_t ebx) x86_set_page_directory(dir); x86_paging_enable(); + // -- EXT2 RAM IMAGE -- // + klog("Check ext2 ram image ... "); + ext2_dump_info(VMEM_EXT2_RAMIMAGE); + // -- APIC -- // klog("Advanced Programmable Interrupt Controller (APIC) config ..."); apic_init(&cfg_acpi); @@ -99,8 +103,11 @@ void kernel_main(uint32_t eax,uint32_t ebx) // -- VESA -- // fixme("tell terminal syscall somehow if we are vga or textmode"); klog("Video Electronics Standards Association (VESA) init ... "); // TODO check if text or fb? - uint32_t addr=kballoc(1); - fs_content("/binfont.bin",addr,0x100); // copy font (0x100 bytes) to memory. + + // binfont has to fit in ONE ext2 block // + fixme("support binfonts spanning multiple blocks?"); + uint32_t inode= ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE,"/binfont.bin"); + uint32_t addr= ext2_inode_blockstart( VMEM_EXT2_RAMIMAGE,inode,0); vesa_init(cfg_multiboot->vbe_control_info,cfg_multiboot->vbe_mode_info,addr); // -- STDIN/STDOUT -- // diff --git a/kernel/kernel.h b/kernel/kernel.h index 3baef97..27798cf 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -54,6 +54,8 @@ REFERENCES #define VMEM_KERNEL_END 0x02000000 #define VMEM_USER_ENV 0x07000000 // ? pages / per user process + +#define VMEM_USER_PROG_PAGES 256 #define VMEM_USER_PROG 0x08048000 // ? pages / per user process (usual entry: 0x8048080) #define VMEM_USER_STACK_PAGES 4 // 4 pages / per thread diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 541eb15..3b50259 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -19,13 +19,13 @@ #define NO_TASK 0xffffffff -static volatile uint32_t pid=1; +static volatile uint32_t pid=1000; -uint32_t nextPID() +static uint32_t nextPID() { spinlock_spin(SPINLOCK_PID); - uint32_t ret=pid; pid++; + uint32_t ret=pid; spinlock_release(SPINLOCK_PID); return ret; } @@ -37,7 +37,7 @@ static volatile uint32_t current_task[SMP_MAX_PROC]; static volatile struct task_list_struct { volatile bool active; // is this slot used (Y/N) - volatile uint32_t pid; // process id (TODO) + volatile uint32_t pid; // process id volatile uint32_t parent; // parent process id volatile uint32_t esp; // stack pointer of the task @@ -46,11 +46,14 @@ static volatile struct task_list_struct volatile uint32_t brk; // memory brk pos - volatile bool wait; // waiting for syscall to be processed. + volatile bool try; // waiting coz syscall not processed yet + volatile bool syscall; // syscall in progress volatile uint32_t eax; volatile uint32_t ebx; volatile uint32_t ecx; volatile uint32_t edx; + + volatile bool thread; // is this a light thread? }task_list[SMP_MAX_PROC][MAX_TASKS]; @@ -70,7 +73,8 @@ volatile void scheduler_init(uint32_t cpu, void *dir) task_list[cpu][0].parent=0; task_list[cpu][0].pid=nextPID(); task_list[cpu][0].active=true; - task_list[cpu][0].wait=false; + task_list[cpu][0].syscall=false; + task_list[cpu][0].thread=false; task_list[cpu][0].vmem=dir; task_list[cpu][0].esp = VMEM_CPU_STACK_TOP-0x200; task_list[cpu][0].esp0 = 0; // esp0 not needed by kernel space tasks @@ -81,7 +85,8 @@ volatile void scheduler_init(uint32_t cpu, void *dir) task_list[cpu][1].parent=0; task_list[cpu][1].pid=nextPID(); task_list[cpu][1].active=true; - task_list[cpu][1].wait=false; + task_list[cpu][0].thread=false; + task_list[cpu][1].syscall=false; task_list[cpu][1].vmem=dir; task_list[cpu][1].esp = kballoc(4)+4*4096-0x200; // 4 pages stack task_list[cpu][1].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks @@ -114,7 +119,7 @@ volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t force_pid) { int idx=(current_task[cpu]+1+i)%MAX_TASKS; // schedule round robin style - if(task_list[cpu][idx].active && !task_list[cpu][idx].wait) // find active non-blocked task + if(task_list[cpu][idx].active && !task_list[cpu][idx].syscall) // find active non-blocked task { //TODO: do NOT do this! deadlock imminent! //if(cpu==0)klog("schedule %d->%d on cpu %d",current_task[cpu],idx,cpu ); @@ -136,13 +141,13 @@ void scheduler_func() uint32_t cpu=smp_get(SMP_APIC_ID); - if(task_get_current_pid()==0) + if(current_task[cpu]==0) while(1) { task_syscall_worker(); } - if(task_get_current_pid()==1) + if(current_task[cpu]==1) while(1) { @@ -150,38 +155,36 @@ void scheduler_func() { uint32_t alloc; uint32_t entry_global=load_elf(BIN_INIT,&alloc); - task_set_brk(alloc); + task_set_brk(task_get_current_pid(),alloc); asm_usermode(entry_global); while(1); } } } -volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack) +volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread) { + uint32_t parent=task_runs(parent_pid); uint32_t cpu=smp_get(SMP_APIC_ID); - uint32_t *stk=task_list[cpu][pid].esp; - stk[14]=entry; - stk[17]=stack; - return 1; -} -volatile int add_task(uint32_t parent,uint32_t vmem) -{ - uint32_t cpu=smp_get(SMP_APIC_ID); for(int i=0;i<MAX_TASKS;i++) { - if(task_list[cpu][i].active!=true) + if(task_list[cpu][i].active!=true) // find a free slot. { task_list[cpu][i].pid=nextPID(); + task_list[cpu][i].parent=parent_pid; + task_list[cpu][i].thread=thread; - task_list[cpu][i].parent=task_list[cpu][parent].pid; task_list[cpu][i].vmem=vmem; - task_list[cpu][i].esp = kballoc(4)+2*4096; // center + task_list[cpu][i].esp = kballoc(4)+2*4096; // center task_list[cpu][i].esp0 = kballoc(4)+4*4096; - task_list[cpu][i].wait=false; - task_list[cpu][i].brk=task_list[cpu][current_task[cpu]].brk; + + task_list[cpu][i].active=true; //TODO: LOCK! (also other similar) + task_list[cpu][i].syscall=false; + task_list[cpu][i].try=false; + + task_list[cpu][i].brk=task_list[cpu][parent].brk; uint32_t *source=(uint32_t *)task_list[cpu][parent].esp; uint32_t *dst=(uint32_t *)task_list[cpu][i].esp; @@ -197,13 +200,22 @@ volatile int add_task(uint32_t parent,uint32_t vmem) stack[12]=0x1; stack[13]=0; // this task returns pid=0 to the caller - task_list[cpu][i].active=true; //TODO: LOCK! (also other similar) - return i; + return task_list[cpu][i].pid; } } kpanic("out of task slots!"); } +void task_wake_all() +{ + uint32_t cpu=smp_get(SMP_APIC_ID); + // simple approach, any syscall might unblock any other syscall // TODO: better! TODO: all cpus! + for(int i=0;i<MAX_TASKS;i++) + { + task_list[cpu][i].try=true; + } +} + /** * kernel space worker thread @@ -211,40 +223,49 @@ volatile int add_task(uint32_t parent,uint32_t vmem) * we can get interrupted by an interrupt ANYTIME! * */ - void task_syscall_worker() { + /// TODO: cross check all cpus! uint32_t cpu=smp_get(SMP_APIC_ID); + while(1) { - bool nowork=true; for(int i=0;i<MAX_TASKS;i++) { - if(task_list[cpu][i].wait) + if(task_list[cpu][i].active,task_list[cpu][i].try&&task_list[cpu][i].syscall) { + uint32_t syscall=task_list[cpu][i].eax; - klog("task %d waiting on syscall %d/%s. processing...",i,syscall,syscall_get_name(syscall)); + klog("task pid=%d waiting on syscall %d/%s on cpu %d slot %d.",task_list[cpu][i].pid,syscall,syscall_get_name(syscall),cpu,i); + task_list[cpu][0].vmem=task_list[cpu][i].vmem; // switch syscall worker to pagedir of calling userprog x86_set_page_directory(task_list[cpu][0].vmem); - nowork=false; - - uint32_t ret = syscall_generic(task_list[cpu][i].eax, + uint32_t ok = syscall_generic_test(task_list[cpu][i].eax, task_list[cpu][i].edx, task_list[cpu][i].ecx, task_list[cpu][i].ebx, - i); + task_list[cpu][i].pid); - if(task_list[cpu][i].eax==SYSCALL_WAIT) + if(!ok) { + task_list[cpu][i].try=false; continue; } + uint32_t ret = syscall_generic(task_list[cpu][i].eax, + task_list[cpu][i].edx, + task_list[cpu][i].ecx, + task_list[cpu][i].ebx, + task_list[cpu][i].pid); + + task_wake_all(); + uint32_t *stack=task_list[cpu][i].esp; stack[12]=0x1; stack[13]=ret; - task_list[cpu][i].wait=false; + task_list[cpu][i].syscall=false; } } @@ -254,48 +275,109 @@ void task_syscall_worker() } } - volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t edx) { uint32_t cpu=smp_get(SMP_APIC_ID); - task_list[cpu][current_task[cpu]].wait=true; + task_list[cpu][current_task[cpu]].syscall=true; + task_list[cpu][current_task[cpu]].try=true; task_list[cpu][current_task[cpu]].eax=eax; task_list[cpu][current_task[cpu]].ebx=ebx; task_list[cpu][current_task[cpu]].ecx=ecx; task_list[cpu][current_task[cpu]].edx=edx; - task_list[cpu][0].wait=false; return 1; } volatile uint32_t task_fork(uint32_t pid) { + uint32_t idx=task_runs(pid); uint32_t cpu=smp_get(SMP_APIC_ID); - int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][pid].vmem,false)); - klog("[%d] forked -> [%d] (free blocks remaining: %d )", pid, ret,0); + int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,false),false); + klog("[%d] forked -> [%d]", pid, ret); return ret; } + volatile uint32_t task_clone(uint32_t pid) { + uint32_t idx=task_runs(pid); uint32_t cpu=smp_get(SMP_APIC_ID); - int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][pid].vmem,true)); - klog("[%d] cloned -> [%d] (free blocks remaining: %d )", pid, ret,0); + int ret=add_task(pid,vmem_new_space_dir(task_list[cpu][idx].vmem,true),true); + klog("[%d] cloned -> [%d]", pid, ret); return ret; } -volatile int task_get_current_pid() +volatile uint32_t task_get_brk(uint32_t pid) { uint32_t cpu=smp_get(SMP_APIC_ID); - return current_task[cpu]; + uint32_t idx=task_idx(pid); + return task_list[cpu][idx].brk; } -volatile uint32_t task_get_brk() +volatile void task_set_brk(uint32_t pid, uint32_t brk) { uint32_t cpu=smp_get(SMP_APIC_ID); - return task_list[cpu][current_task[cpu]].brk; + uint32_t idx=task_idx(pid); + task_list[cpu][idx].brk=brk; } -volatile void task_set_brk(uint32_t brk) +volatile uint32_t task_get_current_pid() { uint32_t cpu=smp_get(SMP_APIC_ID); - task_list[cpu][current_task[cpu]].brk=brk; + return task_list[cpu][current_task[cpu]].pid; +} + +volatile uint32_t task_get_parent(uint32_t pid) +{ + uint32_t idx=task_idx(pid); + uint32_t cpu=smp_get(SMP_APIC_ID); + return task_list[cpu][idx].parent; +} + +volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack,uint32_t brk) +{ + uint32_t cpu=smp_get(SMP_APIC_ID); + uint32_t idx=task_idx(pid); + uint32_t *stk=task_list[cpu][idx].esp; + task_list[cpu][idx].brk=brk; + + stk[14]=entry; + stk[17]=stack; + return 1; +} + +uint32_t task_idx(uint32_t pid) +{ + uint32_t cpu=smp_get(SMP_APIC_ID); + + for(int i=0;i<MAX_TASKS;i++) + { + if(task_list[cpu][i].pid==pid)return i; + } + + return 0; +} + +uint32_t task_runs(uint32_t pid) +{ + uint32_t cpu=smp_get(SMP_APIC_ID); + + for(int i=0;i<MAX_TASKS;i++) + { + if(task_list[cpu][i].active==true&& task_list[cpu][i].pid==pid)return i; + } + + return 0; +} + +void task_exit(uint32_t pid) +{ + uint32_t cpu=smp_get(SMP_APIC_ID); + uint32_t idx=task_runs(pid); + + for(int i=0;i<MAX_TASKS;i++) + { + if(task_list[cpu][i].active==true&& task_list[cpu][i].pid==pid) + task_list[cpu][i].active=false; + } + + vmem_free_space_dir(task_list[cpu][idx].vmem,false); } diff --git a/kernel/scheduler.h b/kernel/scheduler.h index 18002da..f77912d 100644 --- a/kernel/scheduler.h +++ b/kernel/scheduler.h @@ -1,15 +1,20 @@ #include <stdint.h> +#include <stdbool.h> // http://hosted.cjmovie.net/TutMultitask.htm volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t force_pid); -volatile int task_get_current_pid(); -volatile void task_set_brk(uint32_t brk); +void task_wake_all(); +volatile uint32_t task_get_current_pid(); +volatile uint32_t task_get_parent(uint32_t pid); +volatile void task_set_brk(uint32_t pid,uint32_t brk); void task_syscall_worker(); -volatile uint32_t task_get_brk(); -volatile uint32_t task_exit(uint32_t pid); +volatile uint32_t task_get_brk(uint32_t pid); volatile uint32_t task_fork(uint32_t pid); volatile uint32_t task_clone(uint32_t pid); volatile uint32_t task_wait(uint32_t pid); -volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack); +volatile int task_reset(uint32_t pid, uint32_t entry, uint32_t stack, uint32_t brk); volatile uint32_t task_syscall(uint32_t eax,uint32_t ebx, uint32_t ecx, uint32_t edx); +uint32_t task_runs(uint32_t pid); +uint32_t task_idx(uint32_t pid); +void task_exit(uint32_t pid); diff --git a/kernel/syscalls.c b/kernel/syscalls.c index 6707ec3..3fb813e 100644 --- a/kernel/syscalls.c +++ b/kernel/syscalls.c @@ -17,7 +17,6 @@ #include "scheduler.h" #include "log.h" - // TODO: use includes!!! uint64_t timer_get_ms(); @@ -134,20 +133,19 @@ int syscall_write(int file, char *buf, int len) */ int syscall_read(int file, char *buf, int len) { - //file 0 = stdin , file 1 = stdout , file 2 = stderr - char c; - int l=0; - - c=fd_read(&fds[file]); - fifo_data_len[file]--; - *buf=c; - buf++; - l++; - - return l; - if(l==len)return l; - if(c=='\n')return l; - + //file 0 = stdin , file 1 = stdout , file 2 = stderr + char c; + int l=0; + + c=fd_read(&fds[file]); + fifo_data_len[file]--; + *buf=c; + buf++; + l++; + + return l; + if(l==len)return l; + if(c=='\n')return l; } //TODO: replace with dirent! @@ -217,7 +215,6 @@ int copy_args(char **in, char **out) int syscall_execve(char *name, char **argv, char **env,int pid) { - //TODO copy environment to target pages somehow// int arg_count=0; while(argv[arg_count]!=NULL)arg_count++; @@ -225,26 +222,23 @@ int syscall_execve(char *name, char **argv, char **env,int pid) char **argv1=VMEM_USER_ENV; if(argv!=NULL) { -// copy_args(argv,argv1); + copy_args(argv,argv1); } - else{ argv1=NULL; } - char **env1=VMEM_USER_ENV+1024; + char **env1=VMEM_USER_ENV+1024*2; if(env!=NULL) { -// copy_args(env,env1); + copy_args(env,env1); } - else{ env1=NULL; } uint32_t alloc; uint32_t entry_global=load_elf(name,&alloc); - task_set_brk(alloc); if(!entry_global) { @@ -255,7 +249,7 @@ int syscall_execve(char *name, char **argv, char **env,int pid) *++stack=argv1; *++stack=arg_count; *++stack=env1; - task_reset(pid,entry_global,stack); + task_reset(pid,entry_global,stack,alloc); return 0; /* try to move this to asm */ @@ -341,13 +335,13 @@ uint32_t syscall_clone(int pid) uint32_t syscall_wait(int pid) { - fixme("implement syscall_wait"); return 0; } uint32_t syscall_exit(int pid) { fixme("free allll mem"); + task_exit(pid); return 0; } @@ -368,20 +362,15 @@ int syscall_isatty(int file,int none1,int none2) return 1; } -uint32_t fuckalloc=0x8500000; // TODO: per process basis! -uint32_t syscall_sbrk(uint32_t incr, int none1, int none2) +uint32_t syscall_sbrk(uint32_t incr, int none1, int none2, uint32_t pid) { - fixme("fake syscall_sbrk! 0x%08X",incr); - uint32_t alloc=task_get_brk(); - - uint32_t oldalloc=fuckalloc; - fuckalloc+=incr; - - task_set_brk(alloc); - - + uint32_t alloc=task_get_brk(pid); + uint32_t oldalloc=alloc; + alloc+=incr; + task_set_brk(pid,alloc); + fixme("fake syscall_sbrk(0x%08X) return %08X",incr,oldalloc); return oldalloc; } @@ -394,6 +383,18 @@ int syscall_stat(const char *path, struct stat *st,int none) /// there also is task_fork, task_wait, task_exit.. which is in scheduler.c //////////////////////////////////////// +uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) +{ + switch(nr){ + case SYSCALL_WAIT : + return !task_runs(p1); + case SYSCALL_READ : + return p3 <= fifo_data_len[p1]; + case SYSCALL_EXIT : + return 1; + } + return 1; +} uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid) { @@ -423,7 +424,7 @@ uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint case SYSCALL_READ : return syscall_read(p1,p2,p3); case SYSCALL_SBRK : - return syscall_sbrk(p1,p2,p3); + return syscall_sbrk(p1,p2,p3,pid); case SYSCALL_STAT : return syscall_stat(p1,p2,p3); case SYSCALL_FSTAT : diff --git a/kernel/syscalls.h b/kernel/syscalls.h index b31d32c..b736519 100644 --- a/kernel/syscalls.h +++ b/kernel/syscalls.h @@ -27,6 +27,7 @@ char* syscall_get_name(uint32_t num); uint32_t syscall_generic(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid); +uint32_t syscall_generic_test(uint32_t nr,uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid); int syscall_open(char *name, int flags, int mode); int syscall_write(int file, char *buf, int len); diff --git a/kernel/vmem.c b/kernel/vmem.c index 4faf93e..129ddb5 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -305,14 +305,46 @@ pdirectory* vmem_kernel_dir() vmem_add_alloc(dir,VMEM_CPU_PRIVATE,4,false); vmem_add_alloc(dir,VMEM_CPU_STACK_TOP-4096*VMEM_CPU_STACK_PAGES,VMEM_CPU_STACK_PAGES,false); - vmem_add_alloc(dir,VMEM_USER_PROG,1024*2,true); - vmem_add_alloc(dir,VMEM_USER_ENV,2,true); - vmem_add_alloc(dir,VMEM_USER_NEWLIB,2,true); + vmem_add_alloc(dir,VMEM_USER_PROG,VMEM_USER_PROG_PAGES,true); + vmem_add_alloc(dir,VMEM_USER_ENV,1,true); + vmem_add_alloc(dir,VMEM_USER_NEWLIB,1,true); vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*VMEM_USER_STACK_PAGES,VMEM_USER_STACK_PAGES,true); return dir; } +void vmem_free_space_dir(pdirectory *dir,bool stack_only) +{ + fixme("free kmalloc too!"); + fixme("stack_only version too!"); + + //free user pages + uint32_t virt=0; + for(int i=0;i<1024;i++) + { + uint32_t src_pt=dir->m_entries [i]; + + if(pt_entry_is_user(src_pt)) + { + ptable *src_table=pt_entry_get_frame(&src_pt); + + for(int j=0;j<1024;j++) + { + uint32_t src_pd=src_table->m_entries[j]; + uint32_t src_phys=pd_entry_get_frame(&src_pd); + + if(src_pd) + { + mem_free_block(src_phys); + } + virt+=4096; + } + } + else virt+=4096*1024; + } + +} + pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) { pdirectory* dir = vmem_clean_dir(); //let's start with a fresh page directory @@ -324,14 +356,25 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) if(!pt_entry_is_user(src_pt))dir->m_entries [i]=src_pt; } - vmem_add_alloc(dir,VMEM_USER_PROG,1024*4,true); - vmem_add_alloc(dir,VMEM_USER_ENV,2,true); - vmem_add_alloc(dir,VMEM_USER_NEWLIB,2,true); + // threads share this // + if(stack_only) + { + // TODO + kpanic("not impl!"); + } + else + { + vmem_add_alloc(dir,VMEM_USER_PROG,VMEM_USER_PROG_PAGES,true); + vmem_add_alloc(dir,VMEM_USER_ENV,1,true); + } + + // threads need own // + vmem_add_alloc(dir,VMEM_USER_NEWLIB,1,true); vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*VMEM_USER_STACK_PAGES,VMEM_USER_STACK_PAGES,true); pdirectory* mydir=x86_get_page_directory(); - //copy user pages (TODO: stack only version for cloning!) + //copy user pages uint32_t virt=0; for(int i=0;i<1024;i++) { @@ -383,6 +426,5 @@ void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi) multiboot_mod *mod=(multiboot_mod *)cfg_multiboot->mods_addr; mod_start=mod->mod_start; mod_end=mod->mod_end; - } diff --git a/kernel/vmem.h b/kernel/vmem.h index 767d7c5..c85d36b 100644 --- a/kernel/vmem.h +++ b/kernel/vmem.h @@ -56,5 +56,6 @@ struct pdirectory_struct; void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi); void vmem_free_dir(struct pdirectory_struct *dir); struct pdirectory_struct* vmem_new_space_dir(struct pdirectory_struct *copy_dir,bool stack_only); +void vmem_free_space_dir(struct pdirectory_struct *dir,bool stack_only); struct pdirectory_struct* vmem_kernel_dir(); diff --git a/userspace/Makefile b/userspace/Makefile index 74e0943..dbc2d0f 100644 --- a/userspace/Makefile +++ b/userspace/Makefile @@ -39,6 +39,8 @@ ext2.img: $(PROGS) @mkdir -p mnt/boot @echo "Welcome to FoolOs\nWe hope you will enjoy your stay." > mnt/home/miguel/hello.txt @mkdir -p mnt/bin + @mkdir -p mnt/doc/test + @cp test.txt mnt/doc/test/ @cp $(PROGS) mnt/bin @cp fonts/binfont.bin mnt/ @echo "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++." > mnt/home/miguel/hello.brain diff --git a/userspace/foolshell.c b/userspace/foolshell.c index 984cc4f..3c1fb50 100644 --- a/userspace/foolshell.c +++ b/userspace/foolshell.c @@ -52,15 +52,9 @@ void prompt() int main(int argc, char **argv) { -/* - printf("_impure_ptr: 0x%08x\n",_impure_ptr); - printf("argv= 0x%08x \n",argv); - printf("environ= 0x%08x \n",environ); -*/ bool silent=false; for(int i=0;i<argc;i++) { -// printf("%i:%s\n",i+1,argv[i]); if(!strcmp(argv[i],"--silent"))silent=true; } @@ -69,6 +63,7 @@ int main(int argc, char **argv) char *buf=calloc(sizeof(char),256); setvbuf(stdin,NULL,_IONBF,0); + setvbuf(stdout,NULL,_IONBF,0); while(1) { @@ -217,12 +212,10 @@ int process(char *buf) // printf("adjusted: '%s'\n",buf); if(buf[0]==0)setenv("PWD","/",1); else setenv("PWD",buf,1); - } else if(!strcmp(command,"exit")) { - exit(1); - + _exit(1); } else if(!strcmp(command,"echo")) { @@ -253,23 +246,18 @@ int process(char *buf) else { int pid=_fork(); - if(pid!=0) - { - // printf("new task pid: %i \n",pid); - } + if(pid==0) { - char buf[256]; sprintf(buf,"%s",token[0]); _execve(buf,token,environ); - //sprintf(buf,"%s/%s",getenv("PATH"),token[0]); - sprintf(buf,"%s/%s","/bin",token[0]); + sprintf(buf,"%s/%s",getenv("PATH"),token[0]); _execve(buf,token,environ); puts("foolshell: command not found"); - exit(1); + exit(0); } - int status; - if(strcmp(token[1],"branch"))_wait(&status); + + if(token[1]!=NULL&&strcmp(token[1],"branch"))_wait(pid); } return 0; diff --git a/userspace/init.c b/userspace/init.c index e04e7ce..a367fd9 100644 --- a/userspace/init.c +++ b/userspace/init.c @@ -7,28 +7,28 @@ int main(int argc, char **argv) char *argv1[]={"/bin/foolshell",0}; char *env1[]={"PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0}; + printf("fool-init\n"); time_t ltime; time(<ime); - printf("fool-init: current time: %s", ctime(<ime)); + printf("fool-init: current time: %s\n", ctime(<ime)); // loop forever and spawn shells if the top-shell exits while(1) { int pid=_fork(); + printf("fool-init: forked pid=%d\n", pid); - int status; if(pid==0) { _execve("/bin/foolshell",argv1,env1); // replace process with our foolshell :) - puts("FATAL ERROR: Something terrible happened. Unable to Execute SHELL!"); - while(1);// hang + while(1) puts("FATAL ERROR: Something terrible happened. Unable to Execute SHELL!\n"); } // wait until our child process state changes (exits) // and respawn SHELL - _wait(&status); + _wait(pid); printf("fool-init: catched exit of process %d.\n",pid); printf("fool-init: respawning a Fools Shell\n"); diff --git a/userspace/test.txt b/userspace/test.txt new file mode 100644 index 0000000..d44e39c --- /dev/null +++ b/userspace/test.txt @@ -0,0 +1,5 @@ +HELLO THIS IS A TEXTFILE +USED FOR TESTING THE FOOL OS EXT2 RAM IMAGE +TRY TO READ ME! + +BYE |
