summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--README.md11
-rw-r--r--fs/elf.c13
-rw-r--r--fs/ext2.c302
-rw-r--r--fs/ext2.h33
-rw-r--r--fs/fs.c5
-rw-r--r--fs/fs.h6
-rw-r--r--interface/syscalls.c4
-rw-r--r--kernel/interrupts.c5
-rw-r--r--kernel/kernel.c13
-rw-r--r--kernel/kernel.h2
-rw-r--r--kernel/scheduler.c182
-rw-r--r--kernel/scheduler.h15
-rw-r--r--kernel/syscalls.c73
-rw-r--r--kernel/syscalls.h1
-rw-r--r--kernel/vmem.c58
-rw-r--r--kernel/vmem.h1
-rw-r--r--userspace/Makefile2
-rw-r--r--userspace/foolshell.c26
-rw-r--r--userspace/init.c10
-rw-r--r--userspace/test.txt5
21 files changed, 431 insertions, 337 deletions
diff --git a/Makefile b/Makefile
index d164775..b92c68f 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/README.md b/README.md
index ac12421..b78b139 100644
--- a/README.md
+++ b/README.md
@@ -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?)
diff --git a/fs/elf.c b/fs/elf.c
index 851c7e8..4f040cd 100644
--- a/fs/elf.c
+++ b/fs/elf.c
@@ -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);
diff --git a/fs/ext2.c b/fs/ext2.c
index d99fba7..a167213 100644
--- a/fs/ext2.c
+++ b/fs/ext2.c
@@ -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;
}
diff --git a/fs/ext2.h b/fs/ext2.h
index 8b9b76b..9c8a8f2 100644
--- a/fs/ext2.h
+++ b/fs/ext2.h
@@ -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);
diff --git a/fs/fs.c b/fs/fs.c
index 357a441..a9cf5f6 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -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);
}
diff --git a/fs/fs.h b/fs/fs.h
index 7d51e86..f5c9a6e 100644
--- a/fs/fs.h
+++ b/fs/fs.h
@@ -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(&ltime);
- printf("fool-init: current time: %s", ctime(&ltime));
+ printf("fool-init: current time: %s\n", ctime(&ltime));
// 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