diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | README.md | 15 | ||||
| -rw-r--r-- | driver/screen.c | 2 | ||||
| -rw-r--r-- | driver/screen.h | 2 | ||||
| -rw-r--r-- | fs/elf.c | 2 | ||||
| -rw-r--r-- | fs/fs.c | 37 | ||||
| -rw-r--r-- | fs/fs.h | 1 | ||||
| -rw-r--r-- | kernel/kernel.c | 31 | ||||
| -rw-r--r-- | kernel/kernel.h | 18 | ||||
| -rw-r--r-- | kernel/mem.c | 3 | ||||
| -rw-r--r-- | kernel/scheduler.c | 1 | ||||
| -rw-r--r-- | kernel/smp.c | 69 | ||||
| -rw-r--r-- | kernel/smp.h | 2 | ||||
| -rw-r--r-- | kernel/vmem.c | 143 | ||||
| -rw-r--r-- | kernel/vmem.h | 2 | ||||
| -rw-r--r-- | test/selftest.c | 13 | ||||
| -rw-r--r-- | test/selftest.h | 1 |
17 files changed, 181 insertions, 163 deletions
@@ -49,6 +49,7 @@ CFLAGS+= -Wno-int-conversion CFLAGS+= -Wno-implicit-int CFLAGS+= -Wno-incompatible-pointer-types CFLAGS+= -Wno-discarded-qualifiers +CFLAGS+= -Wno-unused-but-set-variable #CFLAGS+ = -Wall -Wextra -std=c89 -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition @@ -76,6 +77,7 @@ SOURCES+=$(wildcard ./fs/*.c) SOURCES+=$(wildcard ./driver/*.c) SOURCES+=$(wildcard ./terminal/*.c) SOURCES+=$(wildcard ./lib/*/*.c) +SOURCES+=$(wildcard ./test/*.c) #derive kernel object files OBJECTS=$(patsubst %.c, %.o, $(SOURCES)) @@ -86,17 +86,20 @@ FoolOS is tested/developed on the following emulators/machines Todos ----- -* Unit Testing +* Cleanup Virtual Memory Manager / Flush TLB (?) * Mouse & KB processing in seperate task. * Kernel Stuff Reentrancy & Newlib Reeentrancy Struct -* Ethernet driver E1000 / NS2000 & Networking stack (ipxe network drivers?) -* Porting (ncurses, gcc, binutils, vim, apache...) -* Posix getdents -* GCC optimizations (break kernel?) +* Posix getdents and cleanup syscalls * Writing to ext2 RAM-image * Mutexes -* Flush TLB + +* GCC optimizations (break kernel?) + +* Ethernet driver E1000 / NS2000 & Networking stack (ipxe network drivers?) + +* Unit Testing * GUI / Window Manager (update\_rect, etc..) +* Porting (ncurses, gcc, binutils, vim, apache...) Disclaimer ---------- diff --git a/driver/screen.c b/driver/screen.c index 4d39b77..49fe694 100644 --- a/driver/screen.c +++ b/driver/screen.c @@ -27,7 +27,7 @@ void update_cursor(uint32_t col,uint32_t row) static void print_char_col(int x, int y, char c, char col_fg, char col_bg) { uint16_t attrib = (col_bg << 4) | (col_fg & 0x0F); - uint16_t* video_mem=(uint16_t *)SCR_VIDEOMEM+(x+y*SCR_REAL_WIDTH); + uint16_t* video_mem=(uint16_t *)VMEM_FRAMEBUFFER+(x+y*SCR_REAL_WIDTH); *video_mem=c | (attrib << 8) ; } diff --git a/driver/screen.h b/driver/screen.h index bcf55e9..e3370cb 100644 --- a/driver/screen.h +++ b/driver/screen.h @@ -5,8 +5,6 @@ #include <stdint.h> -#define SCR_VIDEOMEM 0xb8000 - #define SCR_REAL_WIDTH 80 #define SCR_WIDTH 78 @@ -87,7 +87,7 @@ void elf_multiboot_read(multiboot_information *info) // returns elf entry point uint32_t load_elf(char *name, uint32_t *alloc) { - uint32_t ext2_ramimage=fs_get_root_ext2_ramimage(); + uint32_t ext2_ramimage=VMEM_EXT2_RAMIMAGE; int inode_nr=ext2_filename_to_inode(ext2_ramimage,name); if(inode_nr<1)return 0; @@ -4,46 +4,17 @@ #include "fs.h" #include "ext2.h" - -static uint32_t root_ext2_ramimage=0; - -// // 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(root_ext2_ramimage,name); + int inode_nr=ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE,name); if(inode_nr<1)return -1; - return ext2_read_dir(root_ext2_ramimage, inode_nr,dirs,max); // TODO: hardcoded, fix this -} - -void fs_mount(multiboot_information *info) -{ - // TODO: deinit modules memory: what??? why? then it will be gone right!? - if(info->flags&&1<<3) - { - multiboot_mod *mod=info->mods_addr; - for(int i=0;i<info->mods_count;i++) - { - klog("mounting mod from 0x%08X-0x%08X : %s", - mod->mod_start,mod->mod_end, mod->string); - - //pmmngr_deinit_region(mod->mod_start,((uint32_t)mod->mod_end-(uint32_t)mod->mod_start)+1); - root_ext2_ramimage=mod->mod_start; - - mod++; - } - } + return ext2_read_dir(VMEM_EXT2_RAMIMAGE, inode_nr,dirs,max); // TODO: hardcoded, fix this } void fs_content(char *path, uint32_t dest, uint32_t max_bytes) { - int inode= ext2_filename_to_inode(root_ext2_ramimage, path); - ext2_inode_content(root_ext2_ramimage,inode,dest,max_bytes); -} - -uint32_t fs_get_root_ext2_ramimage() -{ - return root_ext2_ramimage; + int inode= ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE, path); + ext2_inode_content(VMEM_EXT2_RAMIMAGE,inode,dest,max_bytes); } @@ -22,6 +22,5 @@ typedef struct fs_dirent_struct int fs_readdir(const char *name,fs_dirent *dirs,int max); void fs_content(char *path, uint32_t dest, uint32_t max_bytes); void fs_mount(multiboot_information *info); // mounts ext2 ramimage from module as root -uint32_t fs_get_root_ext2_ramimage(); #endif diff --git a/kernel/kernel.c b/kernel/kernel.c index 6a77fd5..8680e7d 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -32,6 +32,8 @@ #include "driver/vesa.h" #include "asm_pit.h" +#include "test/selftest.h" + /* F00L 0S Entry point (called directly from asm/multiboot.asm */ void kernel_main(uint32_t eax,uint32_t ebx) { @@ -93,12 +95,6 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Advanced Programmable Interrupt Controller (APIC) config ..."); apic_init(&cfg_acpi); ioapic_config(); - apic_enable(); - apic_init_timer(3);// freq in HZ - - // -- RAM IMAGE -- // - klog("Ram Filesystem init ... "); - fs_mount(cfg_multiboot); // -- VESA -- // fixme("tell terminal syscall somehow if we are vga or textmode"); @@ -108,9 +104,9 @@ void kernel_main(uint32_t eax,uint32_t ebx) vesa_init(cfg_multiboot->vbe_control_info,cfg_multiboot->vbe_mode_info,addr); // -- STDIN/STDOUT -- // + fixme("do not force order"); // now needed since ids are allocated 0,1,2... klog("stdin/stdout init ..."); uint32_t sstderr = syscall_open("stderr",0,0); // stderr 2 - uint32_t sstdin = syscall_open("stdin",0,0); // stdin 0 uint32_t sstdout; if(cfg_multiboot->framebuffer_type==2) // EGA-standard text mode { @@ -120,6 +116,7 @@ void kernel_main(uint32_t eax,uint32_t ebx) { sstdout = syscall_open("xterm",0,0); // stdout 1 } + uint32_t sstdin = syscall_open("stdin",0,0); // stdin 0 klog("Keyboard init ..."); keyboard_init(0); @@ -127,24 +124,12 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Mouse init ..."); mouse_init(); - klog("Symmetric Multi Processing (SMP) start ... "); - smp_start_aps(&cfg_acpi); - + // we wait till almost the end since the time will only start ticking after we + // enable interrupts klog("Programmable Interval Timer (PIT) init ..."); uint64_t unixtime=timer_init(); klog("Unix Time = %u seconds",unixtime); - klog("Unlock application processors ... "); - asm_smp_unlock(); - - //PutFont('X', 100,200, 0x00ffff,0xff00ff); // TODO temporary! - - klog("Enable Interrupts ... "); - x86_sti(); // this will start processing hardware interrupts - - // now just wait until our scheduler kicks in. - while(1){ - syscall_write(sstdout,"dupa",4); - asm("hlt"); - } + klog("Symmetric Multi Processing (SMP) start ... "); + smp_start_aps(&cfg_acpi); } diff --git a/kernel/kernel.h b/kernel/kernel.h index a99a089..e5c75f8 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -43,10 +43,20 @@ REFERENCES #define SMP_MAX_PROC 16 // 16 (together with bsp) We can currently only address a maximum of 16 cpus via ipis! -#define VMEM_LAPIC 0xE0000000 -#define VMEM_IOAPIC 0xE0001000 -#define VMEM_FRAMEBUFFER 0xF0000000 -#define VMEM_CPU_PRIVATE 0x08000000 +// Virtual Memory Locations // +// NOTE THAT THE STACKS GROWN DOWNWARDS // +#define VMEM_KERNEL 0x00000000 // 8192 pages (32megs) / identity mapped + +#define VMEM_USER_ENV 0x07000000 // 4 pages / per user process +#define VMEM_USER_PROG 0x08000000 // ? pages / per user process (usual entry: 0x8048080) +#define VMEM_USER_STACK_TOP 0xE0000000 // ? pages / per thread + +#define VMEM_LAPIC 0xE0000000 // 1 pages / identity mapped +#define VMEM_IOAPIC 0xE0001000 // 1 pages / identity mapped +#define VMEM_CPU_PRIVATE 0xE0002000 // 4 pages / per cpu +#define VMEM_CPU_STACK_TOP 0xE000A000 // 4 pages / per cpu +#define VMEM_FRAMEBUFFER 0xF0000000 // 8192 pages (32megs) / identity mapped +#define VMEM_EXT2_RAMIMAGE 0xF2000000 // 8192 pages (32megs) / identity mapped // __FUNCTION__ ? #ifndef FOOLOS_LOG_OFF diff --git a/kernel/mem.c b/kernel/mem.c index 1c4c32a..098515b 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -212,8 +212,7 @@ uint32_t mem_init(multiboot_information *info) } // deinitialize kernel simply with this: - //pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)+1); - pmmngr_deinit_region(0,((uint32_t)kernel_end-(uint32_t)kernel_start)+1); + pmmngr_deinit_region(kernel_start,((uint32_t)kernel_end-(uint32_t)kernel_start)); // or better via ELF symbols: (TODO!) if(info->flags&&1<<5) diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 751cff9..cac5ba7 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -18,6 +18,7 @@ static volatile uint32_t current_task=NO_TASK; +// TODO: per cpu! static volatile struct task_list_struct { volatile bool active; // is this slot used (Y/N) diff --git a/kernel/smp.c b/kernel/smp.c index b385681..d22fff0 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -13,50 +13,70 @@ #include "asm_smp.h" #include "apic.h" #include "vesa.h" +#include "syscalls.h" +#include "test/selftest.h" +// set cpu private value +void smp_set(uint32_t offset, uint32_t value) +{ + uint32_t *cpu_mem=VMEM_CPU_PRIVATE; + cpu_mem[offset]=value; +} -void smp_main() +// get cpu private value +uint32_t smp_get(uint32_t offset) { + uint32_t *cpu_mem=VMEM_CPU_PRIVATE; + return cpu_mem[offset]; +} + +void smp_main_generic(bool bsp) +{ + if(!bsp) // for the bsp this was already done beforehand + { + klog("Install Interrupt Vector Table (IVT) on CPU with lapic_id=0x%x ...",apic_id()); + interrupts_install(); + + klog("Install Global Descriptor Table (GDT) on CPU with lapic_id=0x%x ...",apic_id()); + gdt_init(); + + klog("Setup Paging on CPU with lapic_id=0x%x ...",apic_id()); + struct pdirectory_struct *dir=vmem_kernel_dir(); + x86_set_page_directory(dir); + x86_paging_enable(); + } + // setup stack and jump to kernel_ap(); - uint32_t ebp=kballoc(1); + uint32_t ebp=VMEM_CPU_STACK_TOP; asm volatile("mov %0, %%ebp"::"r"(ebp)); asm volatile("mov %ebp, %esp"); - asm volatile("jmp kernel_ap"); + asm volatile("jmp run_smp"); } -void kernel_ap() +void smp_main() { + smp_main_generic(false); +} - klog("Install Interrupt Vector Table (IVT) on CPU with lapic_id=0x%x ...",apic_id()); - interrupts_install(); - - klog("Install Global Descriptor Table (GDT) on CPU with lapic_id=0x%x ...",apic_id()); - gdt_init(); - - klog("Setup Paging on CPU with lapic_id=0x%x ...",apic_id()); - struct pdirectory_struct *dir=vmem_kernel_dir(); - x86_set_page_directory(dir); - x86_paging_enable(); - +static void run_smp() +{ apic_enable(); - - //1024 pages from here on are mapped per cpu for testing! TODO: dynamic. - uint32_t *cpu_mem=VMEM_CPU_PRIVATE; - cpu_mem[0]=apic_id(); klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id()); apic_init_timer(1);// freq 1HZ klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id()); - x86_sti(); asm_smp_unlock(); - cpu_mem[1]=0; + smp_set(0,apic_id()); + smp_set(1,'a'+apic_id()); + + x86_sti(); while(1){ - PutString("cpu cnt: %d",10,10+apic_id()*20,0xff0000,cpu_mem[1]++); - asm("hlt"); + syscall_write(1, VMEM_CPU_PRIVATE+4,1); // stdout + asm("hlt"); // wait for scheduler to kick in } } @@ -71,5 +91,6 @@ void smp_start_aps(acpi_information *pros) klog("starting cpu %d (destination apic id: 0x%x) ",i,dest); apic_sipi(dest,0x7); // start on 0x7000 } + + smp_main_generic(true); } - diff --git a/kernel/smp.h b/kernel/smp.h index 94f0d3e..a14f45c 100644 --- a/kernel/smp.h +++ b/kernel/smp.h @@ -15,5 +15,7 @@ #include "acpi.h" void smp_start_aps(acpi_information *); +void smp_set(uint32_t offset, uint32_t value); +uint32_t smp_get(uint32_t offset); #endif diff --git a/kernel/vmem.c b/kernel/vmem.c index 3cbda9a..3da35ce 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -45,6 +45,8 @@ static uint32_t kernel_pages; static uint32_t fb_addr; static uint32_t local_apic_addr; static uint32_t io_apic_addr; +static uint32_t mod_start; +static uint32_t mod_end; // TODO : why is the frame not 0xfffff?? enum PAGE_PTE_FLAGS @@ -195,61 +197,6 @@ static pt_entry* vmmngr_ptable_lookup_entry (ptable* p, virtual_addr addr) return 0; } -/// SHIT BELOW THIs LINE -void vmem_free_dir(pdirectory *dir) -{ - x86_paging_disable(); //TODO : do not disable this! - - uint32_t virt_addr=0; - - // first pages are identity mapped (kernel space) just remove links - for(int j=0;j<3;j++) - { - pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ]; - virt_addr+=1024*4096; - } - - // programm space - virt_addr=0x8000000; - for(int j=0;j<2;j++) - { - - pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ]; - ptable *table=pd_entry_get_frame(entry); - - for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096) - { - pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ]; - mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager - } - - mem_free_block(pd_entry_get_frame (entry)); - virt_addr+=1024*4096; - - } - - // stack - virt_addr=0x8c00000; - for(int j=0;j<1;j++) - { - - pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ]; - ptable *table=pd_entry_get_frame(entry); - - for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096) - { - pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ]; - mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager - } - - mem_free_block(pd_entry_get_frame (entry)); - virt_addr+=1024*4096; - - } - mem_free_block(dir); - - x86_paging_enable(); -} static pdirectory* vmem_clean_dir() { @@ -308,7 +255,7 @@ static void vmem_add_generic(pdirectory* dir,uint32_t phys,uint32_t virt,uint32_ //and add it to the page table uint32_t old=table->m_entries [PAGE_TABLE_INDEX (virt) ]; - if(old!=0&&old!=page)kpanic("overwriting existing page data!"); + if(old!=0&&old!=page)kpanic("overwriting existing page data! virt=0x%08X phys=0x%08X",virt,phys); table->m_entries [PAGE_TABLE_INDEX (virt) ] = page; virt+=4096; @@ -337,7 +284,8 @@ pdirectory* vmem_kernel_dir() fixme("do not waste soo many pages/page tables!"); fixme("align properly!! / merge page tables if required!"); fixme("Is ioapic/lapic really on one page?"); - fixme("kernelspace: kernel/lapic/framebuffer/ext2-ramimage"); + fixme("kernelspace: kernel/lapic/ioapic/framebuffer/ext2-ramimage/stack/cpu private"); + fixme("check ext2 and kernel and framebufffer do not exceen the 32megs)"); pdirectory* dir = vmem_clean_dir(); @@ -346,12 +294,84 @@ pdirectory* vmem_kernel_dir() vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,1024*8);//32megs should be enough for 4k (think about pitch) vmem_add_remap(dir,local_apic_addr,VMEM_LAPIC,1); //apic addr should be at pagestart, right? TODO: check. vmem_add_remap(dir,io_apic_addr,VMEM_IOAPIC,1); + vmem_add_remap(dir,mod_start,VMEM_EXT2_RAMIMAGE,1024*8);//32megs for ramimage: TODO: check if enough? + + vmem_add_alloc(dir,VMEM_CPU_PRIVATE,4); - vmem_add_alloc(dir,VMEM_CPU_PRIVATE,2); + vmem_add_alloc(dir,VMEM_CPU_STACK_TOP-4096*4,4); return dir; } +void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi) +{ + fixme("do not share fb_addr with syscalls like that!"); + fb_addr=cfg_multiboot->framebuffer_addr; + local_apic_addr=cfg_acpi->local_apic_address; + io_apic_addr=cfg_acpi->io_apic_address; + multiboot_mod *mod=(multiboot_mod *)cfg_multiboot->mods_addr; + mod_start=mod->mod_start; + mod_end=mod->mod_end; + +} + +/////////////////////////////////////////////////////////////////////// + +/// SHIT BELOW THIs LINE +void vmem_free_dir(pdirectory *dir) +{ + x86_paging_disable(); //TODO : do not disable this! + + uint32_t virt_addr=0; + + // first pages are identity mapped (kernel space) just remove links + for(int j=0;j<3;j++) + { + pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ]; + virt_addr+=1024*4096; + } + + // programm space + virt_addr=0x8000000; + for(int j=0;j<2;j++) + { + + pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ]; + ptable *table=pd_entry_get_frame(entry); + + for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096) + { + pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ]; + mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager + } + + mem_free_block(pd_entry_get_frame (entry)); + virt_addr+=1024*4096; + + } + + // stack + virt_addr=0x8c00000; + for(int j=0;j<1;j++) + { + + pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (virt_addr) ]; + ptable *table=pd_entry_get_frame(entry); + + for (int i=0, virt=virt_addr; i<1024; i++, virt+=4096) + { + pt_entry pte=&table->m_entries [PAGE_TABLE_INDEX (virt) ]; + mem_free_block(pt_entry_get_frame(pte)); // get free space from the memory manager + } + + mem_free_block(pd_entry_get_frame (entry)); + virt_addr+=1024*4096; + + } + mem_free_block(dir); + + x86_paging_enable(); +} // // vmem init / also copies all the shit over for FORK // if copy_dir==NULL creates brandnew dir @@ -711,10 +731,3 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) return dir; } -void vmem_init(multiboot_information *cfg_multiboot, acpi_information *cfg_acpi) -{ - fixme("do not share fb_addr with syscalls like that!"); - fb_addr=cfg_multiboot->framebuffer_addr; - local_apic_addr=cfg_acpi->local_apic_address; - io_apic_addr=cfg_acpi->io_apic_address; -} diff --git a/kernel/vmem.h b/kernel/vmem.h index 6bc1394..767d7c5 100644 --- a/kernel/vmem.h +++ b/kernel/vmem.h @@ -18,7 +18,7 @@ * ====== * * We are aiming for the following layout: - * + * TODO: update, this is not true anumore! * 0xFFFFFFFF * 0xC0000000 RESERVED * diff --git a/test/selftest.c b/test/selftest.c new file mode 100644 index 0000000..e95b320 --- /dev/null +++ b/test/selftest.c @@ -0,0 +1,13 @@ +#include "kernel.h" + +void selftest_stack_overflow() +{ + klog("recurse.."); + selftest_stack_overflow(); +} + +void selftest_run() +{ + klog ("RUNNING SOME IN-KERNEL SELFTESTS"); + selftest_stack_overflow(); +} diff --git a/test/selftest.h b/test/selftest.h new file mode 100644 index 0000000..f95ebda --- /dev/null +++ b/test/selftest.h @@ -0,0 +1 @@ +void selftest_run(); |
