diff options
| author | Miguel <m.i@gmx.at> | 2018-10-04 00:53:30 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-10-04 00:53:30 +0200 |
| commit | ce16fe524c14ccaae67fb634105da5aef08ead48 (patch) | |
| tree | 03990f29389bd4c55f40b804b809c7060c24c739 | |
| parent | a455cd5af26bf8731e7c981a9421b16ab34dae6f (diff) | |
moving framebuffer access completely to userspace
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | README.md | 5 | ||||
| -rw-r--r-- | driver/keyboard.c | 9 | ||||
| -rw-r--r-- | driver/keyboard.h | 2 | ||||
| -rw-r--r-- | driver/mouse.c | 3 | ||||
| -rw-r--r-- | driver/serial.c | 4 | ||||
| -rw-r--r-- | driver/timer.c | 8 | ||||
| -rw-r--r-- | driver/vesa.c | 1 | ||||
| -rw-r--r-- | grubiso/boot/grub/grub.cfg | 2 | ||||
| -rw-r--r-- | interface/crt0.s | 4 | ||||
| -rw-r--r-- | kernel/apic.c | 1 | ||||
| -rw-r--r-- | kernel/interrupts.c | 27 | ||||
| -rw-r--r-- | kernel/kernel.c | 58 | ||||
| -rw-r--r-- | kernel/kernel.h | 7 | ||||
| -rw-r--r-- | kernel/kmalloc.c | 2 | ||||
| -rw-r--r-- | kernel/log.c | 14 | ||||
| -rw-r--r-- | kernel/log.h | 10 | ||||
| -rw-r--r-- | kernel/ringbuffer.c | 58 | ||||
| -rw-r--r-- | kernel/ringbuffer.h | 2 | ||||
| -rw-r--r-- | kernel/scheduler.c | 151 | ||||
| -rw-r--r-- | kernel/smp.c | 20 | ||||
| -rw-r--r-- | kernel/vmem.c | 11 | ||||
| -rw-r--r-- | kernel/vmem.h | 1 | ||||
| -rw-r--r-- | userspace/crt0.s | 4 | ||||
| -rw-r--r-- | userspace/init.c | 11 |
25 files changed, 250 insertions, 167 deletions
@@ -206,7 +206,7 @@ qemu-debug: all -net nic,model=e1000 \ -net tap,ifname=tap0,script=no,downscript=no \ -vga virtio \ - -m 1024 -s #-S + -m 1024 -s -S # qemu -enable-kvm -s -S ~/temp/FoolOs/disk.img # qemu -enable-kvm -s -singlestep disk.img # qemu-system-i386 -enable-kvm -s -S -kernel foolos.img -smp 4 -initrd userspace/ext2.img @@ -92,6 +92,8 @@ Todos * PRIO: ringbuffers (spinlock on/off, interrupts on/off, read/write blocks of data); * PRIO: Writing to ext2 RAM-image!!!! * PRIO: Fix scheduler. use all cpus! / accounting/bookkeppiung x86: tsc /rdtscp? / load bareer / queues? +* PRIO: gcc toolchain + * PRIO: semaphores/ mutexes * PRIO: return value / argv / env * PRIO: create/remove pages on demand (sbrk, stack, load prog) @@ -106,6 +108,8 @@ Todos * TODO: GCC optimizations (break kernel?) / volatile keyword etc? * TODO: gcc-foolos (Porting (ncurses, gcc, binutils, vim, apache...) +* EXTRA: fallback to pic/pit + * EXTRA: switch to DMA where possible!? * EXTRA: Unit Testing * EXTRA: GUI / Window Manager (update\_rect, etc..) / double buffering / physical, virtual sizE? virtio ? / Cairo library @@ -113,6 +117,7 @@ Todos * EXTRA: qemu tcg , slower other cpus * EXTRA: Crazy & Funny terminal effects while typing (idea) * EXTRA: port to arm and berryboot / minicom? +* EXTRA: port doom/quake/mesa 3d Disclaimer ---------- diff --git a/driver/keyboard.c b/driver/keyboard.c index cc060c7..2be9c12 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -17,7 +17,6 @@ static bool shift_l=false; static bool shift_r=false; static bool capslock=false; -static uint32_t kb_stream; static char num_syms[]={')','!','@','#','$','%','^','&','*','('}; int hex_to_dec(char c) @@ -30,13 +29,12 @@ int hex_to_dec(char c) extern struct netdev e1000_dev; static void put(uint8_t c) { - syscall_generic(SYSCALL_WRITE,kb_stream, (char *)&c , 1, 0); +// syscall_generic(SYSCALL_WRITE,kb_stream, (char *)&c , 1, 0); } uint32_t keyboard_interrupt(uint32_t esp) { - - ringbuffer_put(&kb_in,x86_inb(0x60)); + if(!ringbuffer_put(&kb_in,x86_inb(0x60))) kpanic("full"); return esp; } @@ -51,11 +49,10 @@ bool keyboard_worker() } -void keyboard_init(uint32_t s) +void keyboard_init() { kb_in=ringbuffer_init(1);// 4096 bytes ringbuffer; interrupt_register(INTERRUPT_KEYBOARD,&keyboard_interrupt); - kb_stream=s; } void keyboard_handle(uint8_t in) diff --git a/driver/keyboard.h b/driver/keyboard.h index 98f1f4e..007f1d1 100644 --- a/driver/keyboard.h +++ b/driver/keyboard.h @@ -8,6 +8,6 @@ #include <stdbool.h> -void keyboard_init(uint32_t s); +void keyboard_init(); void keyboard_handle(uint8_t in); bool keyboard_worker(); diff --git a/driver/mouse.c b/driver/mouse.c index 810cb83..274c9a5 100644 --- a/driver/mouse.c +++ b/driver/mouse.c @@ -81,8 +81,7 @@ static void mouse_write(uint8_t a_write) uint32_t mouse_interrupt(uint32_t esp) { - uint8_t b=x86_inb(0x60); - ringbuffer_put(&mouse_in,b); + if(!ringbuffer_put(&mouse_in,x86_inb(0x60)))kpanic("full"); return esp; } diff --git a/driver/serial.c b/driver/serial.c index 16b3b6c..4e43251 100644 --- a/driver/serial.c +++ b/driver/serial.c @@ -1,5 +1,3 @@ -#ifndef FOOLOS_LOG_OFF - #include "serial.h" #include "asm_x86.h" // provides x86_inb() and x86_outb() @@ -38,5 +36,3 @@ void serial_write(uint8_t a) while (is_transmit_empty() == 0); x86_outb(PORT,a); } - -#endif diff --git a/driver/timer.c b/driver/timer.c index 1a97ad8..0d9b11e 100644 --- a/driver/timer.c +++ b/driver/timer.c @@ -160,8 +160,8 @@ uint64_t timer_init() { uint64_t epoch_time=get_rtc_time(); - task_system_clock_start=epoch_time*100; // since pit ticks 100 times a second - asm_pit_rate_50ms(); //tick at 100hz + task_system_clock_start=epoch_time*20; // clock ticks 20 times a second + asm_pit_rate_50ms(); //tick at 20hz interrupt_register(INTERRUPT_PIT_TIMER,&timer_interrupt); @@ -170,10 +170,10 @@ uint64_t timer_init() uint64_t timer_get_ms() { - return (asm_pit_get_ticks()+task_system_clock_start)*50; + return (asm_pit_get_ticks()+task_system_clock_start)*50; // 50ms passed on each tick } uint64_t timer_get_uptime_ms() { - return asm_pit_get_ticks()*50; + return asm_pit_get_ticks()*50; // 50ms passed on each tick } diff --git a/driver/vesa.c b/driver/vesa.c index 7405422..bd5c53d 100644 --- a/driver/vesa.c +++ b/driver/vesa.c @@ -152,6 +152,7 @@ uint32_t vesa_init(multiboot_information *inf, foolfont *rawfont) int line_height=12; int col_width=10; + console_lines=vesaYres/line_height; console_cols=vesaXres/col_width; diff --git a/grubiso/boot/grub/grub.cfg b/grubiso/boot/grub/grub.cfg index ad49f88..f16c3a0 100644 --- a/grubiso/boot/grub/grub.cfg +++ b/grubiso/boot/grub/grub.cfg @@ -1,4 +1,4 @@ -set timeout=0 //seconds +set timeout=1 //seconds if loadfont ${prefix}/fonts/unicode.pf2 diff --git a/interface/crt0.s b/interface/crt0.s index 26ad47c..dedc86c 100644 --- a/interface/crt0.s +++ b/interface/crt0.s @@ -19,10 +19,10 @@ jne copy pop %ecx pop %ebx -# environment adress was passed on stack - movl $0xf5000000, _impure_ptr +# environment adress was passed on stack + pop %eax mov %eax, environ diff --git a/kernel/apic.c b/kernel/apic.c index 75837f7..509fd3b 100644 --- a/kernel/apic.c +++ b/kernel/apic.c @@ -71,6 +71,7 @@ static uint32_t apic_read(uint32_t offset) uint32_t apic_id() { + if(local_apic_addr==0)return 0; return apic_read(APIC_APICID)>>24; } diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 49c0191..4aa9db3 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -64,13 +64,32 @@ void interrupt_register(uint32_t irq, uint32_t func_addr) */ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) { - uint32_t *stack; - if(handlers[irq]!=0) { uint32_t (*f)(uint32_t esp)=handlers[irq]; esp=f(esp); apic_eoi(); + return esp; + } + + if(irq==INTERRUPT_APIC_TIMER) + { + klog ("tick"); + esp=scheduler_run(esp,-1); + apic_eoi(); + return esp; + } + + kpanic("unhandled interrupt %d",irq); + + + uint32_t *stack; + + if(handlers[irq]!=0) + { + //uint32_t (*f)(uint32_t esp)=handlers[irq]; + //esp=f(esp); + apic_eoi(); } else if(irq!=INTERRUPT_SYSCALL&&irq!=INTERRUPT_IPI&&irq!=INTERRUPT_APIC_TIMER) @@ -83,7 +102,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) { case INTERRUPT_SYSCALL: stack=esp; - task_syscall(stack[11],stack[8],stack[10],stack[9]); //eax,ebx,ecx,edx + // task_syscall(stack[11],stack[8],stack[10],stack[9]); //eax,ebx,ecx,edx break; @@ -105,7 +124,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) // reschedule to kernel worker on these if(irq==INTERRUPT_SYSCALL||irq==INTERRUPT_KEYBOARD||irq==INTERRUPT_MOUSE) { - scheduler_wake_worker(esp); + // scheduler_wake_worker(esp); esp=scheduler_run(esp,-1); } diff --git a/kernel/kernel.c b/kernel/kernel.c index 70b1913..3e07fde 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -41,7 +41,32 @@ #include "driver/vesa.h" #include "asm_pit.h" -/* F00L 0S Entry point (called directly from asm/multiboot.asm */ +/** F00L 0S Entry point (called directly from asm/multiboot.asm) + * + * After this procedure completes we are in a well defined state. + * + * * All Processors are up and running in 32bit protected mode. + * * Interrupts are installed and enabled: + * + * - PS/2 Keyboard CPU0 + * - PS/2 Mouse CPU0 + * - PIT Timer (20Hz) (DISABLED in apic.c) CPU0 + * - APIC Timer (Frequency defined in kernel.h) ALL CPUS + * - E1000 CPU0 + * + * * Software Interrupts: + * + * - Syscalls + * - IPI + * + * * Framebuffer is in a known state. + * * Paging is enabled. + * * Each CPU runs on its own stack at VMEM_CPU_STACK + * * Each CPU has its own private page at VMEM_CPU_PRIVATE + * * We are ready to start scheduling on the next interrupt. + * + */ + void kernel_main(uint32_t eax,uint32_t ebx) { // -- COM1 -- // @@ -60,7 +85,7 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("The Kernel was loaded at: 0x%08X - 0x%08X",get_kernel_start(),get_kernel_end()); klog("0x00000000 - 0x%08X will get identity mapped", VMEM_KERNEL_PAGES*4096); if(kernel_end>=top_kernel_vmem)kpanic("kernel to big. increase VMEM_KERNEL_PAGES"); - fixme("fear overrun of the initial buffer!"); + fixme("still fear overrun of stack"); // -- DISABLE LEGACY PIC -- // klog("Remapping & Disabling Programmable Interrupt Controller (PIC) ..."); @@ -87,7 +112,6 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Interrupt Vector Table (IVT) init ..."); interrupts_init(0x08); interrupts_install(); - fixme("register interrupt callback funcs (instead hardcoded dispatcher)"); // -- PCI SCAN --/ klog("PCI init ..."); @@ -120,14 +144,16 @@ void kernel_main(uint32_t eax,uint32_t ebx) ioapic_config(); // -- VESA -- // + /* fixme("tell terminal syscall somehow if we are vga or textmode"); klog("Video Electronics Standards Association (VESA) init ... "); // binfont has to fit in ONE ext2 block // + fixme("support binfonts spanning multiple blocks?"); uint32_t inode= ext2_filename_to_inode(VMEM_EXT2_RAMIMAGE,VESA_FONT_PATH); uint32_t addr= ext2_inode_blockstart( VMEM_EXT2_RAMIMAGE,inode,0); - vesa_init(cfg_multiboot,addr); + vesa_init(cfg_multiboot,addr); // this only sets some internal static variables klog("Compositor init ..."); compositor_init(cfg_multiboot->framebuffer_width,cfg_multiboot->framebuffer_height,cfg_multiboot->framebuffer_pitch); @@ -136,29 +162,35 @@ void kernel_main(uint32_t eax,uint32_t ebx) // -- STD STREAMS -- // klog("Standard Streams init ..."); fd_init_std_streams(0,cfg_multiboot->framebuffer_type!=2); + */ // -- KB -- // klog("Keyboard init ..."); - keyboard_init(0); + keyboard_init(); // -- MOUSE -- // klog("Mouse init ..."); mouse_init(); - // 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); - // -- E1000 INIT (TODO: only if present!) --/ if(e1000_addr) { + #ifndef DISABLE_E1000 klog("E1000 init ..."); - // e1000_init(e1000_addr); + e1000_init(e1000_addr); + #endif } + // we wait until the end since the time will only start ticking once + // we enable interrupts. + klog("Programmable Interval Timer (PIT) init ..."); + klog("Reading CMOS Clock ..."); + uint64_t unixtime=timer_init(); + klog("Unix Time = %u seconds",unixtime); + klog("Symmetric Multi Processing (SMP) start ... "); // for(int i=1;i<cfg_acpi.processors;i++)apic_sipi(i,0x7); - smp_bsp(); + + + smp_bsp(); // start base processor } diff --git a/kernel/kernel.h b/kernel/kernel.h index 8ec8852..03429f4 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -25,11 +25,14 @@ REFERENCES #define VESA_MAX_WIDTH 1920 #define VESA_MAX_HEIGHT 1080 +#define DISABLE_E1000 //#define FOOLOS_UNIT_TESTING // Run Unit Tests -#define FOOLOS_LOG_OFF // Turn off logging (disables serial port alltogether) +//#define FOOLOS_LOG_OFF // Turn off logging (disables serial port alltogether) //#define FOOLOS_COLORLESS // Turn off colors in log #define HIDE_FIXME +#define FOOLOS_APIC_FREQ 3 // how many apic ticks per second + #define MAX_MOUNTS 10 #define BIN_INIT "/bin/init" @@ -65,7 +68,7 @@ REFERENCES #define VMEM_USER_ENV 0x07000000 // 1 page / per user process -#define VMEM_USER_PROG_PAGES 256*16 +#define VMEM_USER_PROG_PAGES (256*16) #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/kmalloc.c b/kernel/kmalloc.c index 38db6fc..b677559 100644 --- a/kernel/kmalloc.c +++ b/kernel/kmalloc.c @@ -99,7 +99,7 @@ uint32_t kballoc(uint32_t size) mark_used(blk,size); spinlock_release(SPINLOCK_ALLOC); - klog("allocated %d blocks at 0x%08X",size,data_addr+blk*4096); + //klog("allocated %d blocks at 0x%08X",size,data_addr+blk*4096); return data_addr+blk*4096; } diff --git a/kernel/log.c b/kernel/log.c index af6ebac..179f9a8 100644 --- a/kernel/log.c +++ b/kernel/log.c @@ -6,6 +6,8 @@ #include <stdbool.h> #include "spinlock.h" +#include "smp.h" +#include "apic.h" #include "kernel/kernel.h" #include "driver/serial.h" @@ -23,8 +25,10 @@ static void log_string(char *str) } } -void log(bool color,char *module_name, int prio, char *format_string, ...) +void log(char *module_name, int prio, char *format_string, ...) { + uint32_t cpu=apic_id(); + #ifdef FOOLOS_LOG_OFF return; #endif @@ -44,10 +48,10 @@ void log(bool color,char *module_name, int prio, char *format_string, ...) tfp_vsprintf(buf_info,format_string,va); va_end(va); - if(color) tfp_sprintf(buf_log,"\033[36;40m%s\033[31;40m %s:\033[37;40m %s\n",buf_time,module_name,buf_info); - else tfp_sprintf(buf_log,"%s %s: %s\n",buf_time,module_name,buf_info); + tfp_sprintf(buf_log,"\033[36;40m%s\033[33;40mCPU %02d:\033[31;40m%s:\033[37;40m %s\n",buf_time,cpu,module_name,buf_info); +// tfp_sprintf(buf_log,"%sCPU %02d:%s: %s\n",buf_time,cpu,module_name,buf_info); -// spinlock_spin(SPINLOCK_LOG); + spinlock_spin(SPINLOCK_LOG); log_string(buf_log); -// spinlock_release(SPINLOCK_LOG); + spinlock_release(SPINLOCK_LOG); } diff --git a/kernel/log.h b/kernel/log.h index 4e25bef..d834efd 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -11,7 +11,7 @@ #define FOOLOS_LOG_DEBUG 2 #define FOOLOS_LOG_FINE 1 -void log(bool color,char *module_name, int prio, char *format_string, ...); +void log(char *module_name, int prio, char *format_string, ...); // __FUNCTION__ ? #ifndef FOOLOS_LOG_OFF @@ -35,16 +35,16 @@ void log(bool color,char *module_name, int prio, char *format_string, ...); #define S1(x) #x #define S2(x) S1(x) -#define klog(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__), 10, LOG_LABEL_INFO __VA_ARGS__) -#define kpanic(...) {log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__) ,0, LOG_LABEL_PANIC __VA_ARGS__ ); while(1);} +#define klog(...) log(__FILE__ ":" S2(__LINE__), 10, LOG_LABEL_INFO __VA_ARGS__) +#define kpanic(...) {log(__FILE__ ":" S2(__LINE__) ,0, LOG_LABEL_PANIC __VA_ARGS__ ); while(1);} #ifdef HIDE_FIXME #define fixme(...) {} #else -#define fixme(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__) , 10, LOG_LABEL_FIX __VA_ARGS__) +#define fixme(...) log(__FILE__ ":" S2(__LINE__) , 10, LOG_LABEL_FIX __VA_ARGS__) #endif -#define testlog(...) log(FOOLOS_LOG_COLOR,__FILE__ ":" S2(__LINE__) , 10,LOG_LABEL_TEST __VA_ARGS__) +#define testlog(...) log(__FILE__ ":" S2(__LINE__) , 10,LOG_LABEL_TEST __VA_ARGS__) #endif diff --git a/kernel/ringbuffer.c b/kernel/ringbuffer.c index 43d0e33..3886340 100644 --- a/kernel/ringbuffer.c +++ b/kernel/ringbuffer.c @@ -16,48 +16,58 @@ void ringbuffer_free(ringbuffer *f) kbfree(f->data); } -bool ringbuffer_put(ringbuffer* f,uint8_t c) +bool ringbuffer_full(ringbuffer* f) { - if(ringbuffer_full(f))return false; - - f->data[f->back]=c; - f->back--; - f->back+=f->size; - f->back%=f->size; - return true; + if((f->back-1+f->size)%f->size==f->front)return true; + return false; } -bool ringbuffer_full(ringbuffer* f) +bool ringbuffer_empty(ringbuffer* f) { - if((f->back-1+f->size)%f->size==f->front) - { - return true; - } + if(f->front==f->back)return true; return false; } bool ringbuffer_has(ringbuffer* f) { - bool res=true; + return !ringbuffer_empty(f); +} + +// + +bool ringbuffer_put(ringbuffer* f,uint8_t c) +{ + if(ringbuffer_full(f))return false; + + f->data[f->back]=c; + f->back--; + f->back+=f->size; + f->back%=f->size; - if(f->front==f->back) - res=false; - return res; + return true; } uint8_t ringbuffer_get(ringbuffer* f) { - char c; - - if(f->front==f->back) - { - return 0; - } + if(ringbuffer_empty(f))return 0; // indistinguishable from value 0 :( // TODO - c=f->data[f->front]; + uint8_t c = f->data[f->front]; f->front--; f->front+=f->size; f->front%=f->size; + return c; } + +// TODO // + +uint32_t ringbuffer_write(ringbuffer* f, uint8_t *buf, uint32_t size) +{ + return 0; +} + +uint32_t ringbuffer_read(ringbuffer* f, uint8_t *buf, uint32_t size) +{ + return 0; +} diff --git a/kernel/ringbuffer.h b/kernel/ringbuffer.h index 6ad9537..f68f766 100644 --- a/kernel/ringbuffer.h +++ b/kernel/ringbuffer.h @@ -27,7 +27,7 @@ #include <stdbool.h> /** Ringbuffer sturcutre */ -typedef volatile struct ringbuffer_struct +typedef struct ringbuffer_struct { uint32_t size; uint32_t front; diff --git a/kernel/scheduler.c b/kernel/scheduler.c index a4e3743..9fdff7d 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -74,10 +74,10 @@ volatile void scheduler_init(uint32_t cpu, void *dir) } current_task[cpu]=0; - last_task[cpu]=0; +// last_task[cpu]=0; // need to make space on the esp stacks for pushing vals vias task_pusha - + // this is our main kernel task at slot 0 (per cpu) task_list[cpu][0].parent=0; task_list[cpu][0].pid=nextPID(); @@ -85,10 +85,10 @@ volatile void scheduler_init(uint32_t cpu, void *dir) 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-8; - task_list[cpu][0].esp0 = 0; // esp0 not needed by kernel space tasks - strcpy(task_list[cpu][0].name,"kernel_worker"); - fd_init_std_streams(task_list[cpu][0].pid,0); + task_list[cpu][0].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign + task_list[cpu][0].esp0 = 0; // esp0 not required by kernel space tasks + strcpy(task_list[cpu][0].name,"kernel worker"); + //fd_init_std_streams(task_list[cpu][0].pid,0); // this will go to userspace task_list[cpu][1].parent=0; @@ -97,11 +97,11 @@ volatile void scheduler_init(uint32_t cpu, void *dir) task_list[cpu][1].thread=false; task_list[cpu][1].syscall=false; task_list[cpu][1].vmem=dir; - task_list[cpu][1].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign - task_list[cpu][1].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks - strcpy(task_list[cpu][1].name,"init"); - fd_init_std_streams(task_list[cpu][1].pid,0); - + task_list[cpu][1].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign + task_list[cpu][1].esp = VMEM_USER_STACK_TOP-0x200-8; + task_list[cpu][1].esp0 = kballoc(4)+4*4096; // esp0 needed by user space tasks + strcpy(task_list[cpu][1].name,"userspace init"); + //fd_init_std_streams(task_list[cpu][1].pid,0); // sleeper task_list[cpu][2].parent=0; @@ -111,9 +111,9 @@ volatile void scheduler_init(uint32_t cpu, void *dir) task_list[cpu][2].syscall=false; task_list[cpu][2].vmem=dir; task_list[cpu][2].esp = kballoc(4)+4*4096-0x200-8; // 4 pages stack & prealign - task_list[cpu][2].esp0 =kballoc(4)+4*4096; // esp0 not needed by kernel space tasks + task_list[cpu][2].esp0 =0; // esp0 not needed by kernel space tasks strcpy(task_list[cpu][2].name,"idle process"); - fd_init_std_streams(task_list[cpu][2].pid,0); + //fd_init_std_streams(task_list[cpu][2].pid,0); // stacks task_pusha(task_list[cpu][0].esp); @@ -128,8 +128,8 @@ static uint32_t scheduler_schedule(uint32_t idx) if(task_list[cpu][idx].active && !task_list[cpu][idx].syscall) { - if(current_task[cpu]!=0)last_task[cpu]=current_task[cpu]; - if(current_task[cpu]==idx)return task_list[cpu][idx].esp; + //if(current_task[cpu]!=0)last_task[cpu]=current_task[cpu]; + //if(current_task[cpu]==idx)return task_list[cpu][idx].esp; current_task[cpu]=idx; @@ -162,49 +162,26 @@ volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t preference) uint32_t cpu=smp_get(SMP_APIC_ID); uint32_t init=smp_get(SMP_SCHEDULER_INIT); - if(init){ + if(init) + { scheduler_init(cpu,x86_get_page_directory()); smp_set(SMP_SCHEDULER_INIT,0); + klog("Scheduler initialized for cpu %d",cpu); + return task_list[cpu][current_task[cpu]].esp; } - else task_list[cpu][current_task[cpu]].esp=oldesp; - uint32_t esp; - - if(preference!=-1) - { - esp=scheduler_schedule(preference); // try preference - if(esp)return esp; - - if(current_task[cpu]==0)// we have interrupted a task with ring1 work - { - esp=scheduler_schedule(last_task[cpu]); // try preference - if(esp)return esp; - } - } - else - { - //klog("preempt %d", last_task[cpu]); - } - for(int i=0;i<MAX_TASKS;i++) { - int idx=(last_task[cpu]+1+i)%MAX_TASKS; // schedule round robin style -// if(preference==-1&&idx==0)continue; - - if(idx==preference||idx==2)continue;// skip sleeper and preferred tasks here. - - esp=scheduler_schedule(idx); - - if(esp){ - //klog("%d",idx); - return esp; - } + int idx=(current_task[cpu]+1+i)%MAX_TASKS; // schedule round robin style +// if(idx==2)continue;// skip sleeper here + uint32_t esp=scheduler_schedule(idx); + if(esp)return esp; } + kpanic("nothing left to schedule"); - // force the sleeper task... + // force the sleeper task here ... return scheduler_schedule(2); - } @@ -213,35 +190,60 @@ void scheduler_func() // we need enable here again (since the pushed eflags have it disabled)? TODO: why they disabled it!??? x86_sti(); + uint32_t cpu=smp_get(SMP_APIC_ID); + fixme("this will dadlock on context switch during log if never switched back before finish"); + if(current_task[cpu]==0) - while(1) { - task_syscall_worker(); + while(1) + { + uint64_t t0=x86_rdtscp(); + asm("hlt"); // sleeper task + uint64_t t1=x86_rdtscp(); + klog("task 0 / slept cycles: l:%d h:%d",(t1-t0)); + } + +// task_syscall_worker(); + //task_list[cpu][0].syscall=true; // sleep + //__asm__("int $0x81"); // wake scheduler! with IPI + } - if(current_task[cpu]==2) - while(1) + if(current_task[cpu]==1) { - uint64_t t0=x86_rdtscp(); - asm("hlt"); // sleeper task - uint64_t t1=x86_rdtscp(); - klog("slept: l:%d h:%d",(t1-t0)); + if(cpu==0) + { + uint32_t alloc; + uint32_t entry_global=load_elf(BIN_INIT,&alloc); + task_set_brk(task_get_current_pid(),alloc); + asm_usermode(entry_global); + kpanic("init died on cpu %d",cpu); + } + + while(1) + { + uint64_t t0=x86_rdtscp(); + asm("hlt"); // sleeper task + uint64_t t1=x86_rdtscp(); + klog("task 1 / slept cycles: l:%d h:%d",(t1-t0)); + } } - if(current_task[cpu]==1) - while(1) + if(current_task[cpu]==2) { - if(cpu==0) - { - uint32_t alloc; - uint32_t entry_global=load_elf(BIN_INIT,&alloc); - task_set_brk(task_get_current_pid(),alloc); - asm_usermode(entry_global); - while(1); - } + while(1) + { + uint64_t t0=x86_rdtscp(); + asm("hlt"); // sleeper task + uint64_t t1=x86_rdtscp(); + klog("task 2 (sleeper) / slept cycles: l:%d h:%d",(t1-t0)); + } } + + kpanic("unknwon task"); + } volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread, char *name) @@ -324,9 +326,10 @@ void scheduler_wake_all() */ void task_syscall_worker() { - static uint32_t c=0; - /// TODO: cross check all cpus! uint32_t cpu=smp_get(SMP_APIC_ID); + task_list[cpu][0].syscall=true; // sleep (syscall misused) + return; + /// TODO: cross check all cpus! while(1) { @@ -335,14 +338,14 @@ void task_syscall_worker() //TODO: would be enough only to lock during ringbuffer acces!? - x86_cli(); // disable temporarily mouse/kb/timer interrupts. - wake|=keyboard_worker(); - wake_mouse|=mouse_worker(); - x86_sti(); + //x86_cli(); // disable temporarily mouse/kb/timer interrupts. + //wake|=keyboard_worker(); + //wake_mouse|=mouse_worker(); + //x86_sti(); - if(wake_mouse)compositor_swap_buffers(); + //if(wake_mouse)compositor_swap_buffers(); - if(wake)scheduler_wake_all(); + //if(wake)scheduler_wake_all(); //if(cpu==0)compositor_swap_buffers(); diff --git a/kernel/smp.c b/kernel/smp.c index 01230cf..a57b4b9 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -34,19 +34,22 @@ void smp_main_generic(bool bsp) { if(!bsp) // for the bsp this was already done beforehand { + struct pdirectory_struct *dir=vmem_kernel_dir(); + x86_set_page_directory(dir); + x86_paging_enable(); + + klog("Just setup Paging on CPU with lapic_id=0x%x",apic_id()); + 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(); + fixme("we hate iniline assembly!"); uint32_t ebp=VMEM_CPU_STACK_TOP; asm volatile("mov %0, %%ebp"::"r"(ebp)); asm volatile("mov %ebp, %esp"); @@ -58,7 +61,7 @@ void run_smp() apic_enable(); klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id()); - apic_init_timer(3);// freq x HZ + apic_init_timer(FOOLOS_APIC_FREQ);// freq x HZ klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id()); asm_smp_unlock(); @@ -67,13 +70,6 @@ void run_smp() smp_set(1000,'a'+apic_id()); smp_set(SMP_SCHEDULER_INIT,1); - if(apic_id()==0) - { -// apic_sipi(1,0x7); -// apic_sipi(2,0x7); -// apic_sipi(3,0x7); - } - x86_sti(); while(1)asm("hlt"); // wait for scheduler to kick in diff --git a/kernel/vmem.c b/kernel/vmem.c index d99f6fd..a388535 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -346,7 +346,7 @@ pdirectory* vmem_kernel_dir() vmem_add_identity(dir,VMEM_KERNEL,VMEM_KERNEL_PAGES,false);//identity map first 32 megs... vmem_add_identity(dir,e1000_addr,32,false);//identity map 32 pages for e1000 - vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,false);//32megs should be enough for 4k (think about pitch) + vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,true);//32megs should be enough for 4k (think about pitch) vmem_add_remap(dir,local_apic_addr,VMEM_LAPIC,1,false); //apic addr should be at pagestart, right? TODO: check. vmem_add_remap(dir,io_apic_addr,VMEM_IOAPIC,1,false); @@ -359,17 +359,22 @@ pdirectory* vmem_kernel_dir() 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); - vmem_add_alloc(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area +// vmem_add_alloc(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area return dir; } void vmem_add_framebuffer(pdirectory *dir) { - vmem_del_generic(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,false, true); + //vmem_del_generic(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,false, true); vmem_add_alloc(dir, VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area } +void vmem_add_total_framebuffer(pdirectory *dir) +{ + vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,true);//32megs should be enough for 4k (think about pitch) +} + void vmem_free_space_dir(pdirectory *dir,bool stack_only) { diff --git a/kernel/vmem.h b/kernel/vmem.h index 73f9ce6..7573dc3 100644 --- a/kernel/vmem.h +++ b/kernel/vmem.h @@ -58,5 +58,6 @@ 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); void vmem_add_framebuffer(struct pdirectory_struct *dir); +void vmem_add_total_framebuffer(struct pdirectory_struct *dir); struct pdirectory_struct* vmem_kernel_dir(); diff --git a/userspace/crt0.s b/userspace/crt0.s index 26ad47c..dedc86c 100644 --- a/userspace/crt0.s +++ b/userspace/crt0.s @@ -19,10 +19,10 @@ jne copy pop %ecx pop %ebx -# environment adress was passed on stack - movl $0xf5000000, _impure_ptr +# environment adress was passed on stack + pop %eax mov %eax, environ diff --git a/userspace/init.c b/userspace/init.c index 0a3b870..d130bc8 100644 --- a/userspace/init.c +++ b/userspace/init.c @@ -1,11 +1,22 @@ #include <stdio.h> #include <time.h> +#include "put_pixel.h" int main(int argc, char **argv) { + + // int x=10/0; // provoke divide by zero + + uint8_t *mem=0xf6000000; + *mem='a'; + while(1); + char *argv1[]={"/bin/fsh",0}; char *env1[]={"HOME=/home/miguel","PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0}; + + + // loop forever and spawn shells if the top-shell exits while(1) { |
