#define FOOLOS_MODULE_NAME "kernel" #include "x86.h" #include "../lib/logger/log.h" // logger facilities // TODO: WHHYY can i compile it without the includes!??? /////// // interrupt handler prototypes // todo: move somewhere else!? void int_def_handler(); void int_clock_handler(); void int_kb_handler(); void int_floppy_handler(); uint32_t read_eip(); void int_irq0(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Divide by 0"); X86_IRQ_END } void int_irq1(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Single step (debugger)"); X86_IRQ_END } void int_irq2(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Non Maskable Interrupt"); X86_IRQ_END } void int_irq3(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Breakpoint (debugger)"); X86_IRQ_END } void int_irq4(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Overflow"); X86_IRQ_END } void int_irq5(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Bounds check"); X86_IRQ_END } void int_irq6(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Undefined OP Code"); X86_IRQ_END } void int_irq7(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"No coprocessor"); X86_IRQ_END } void int_irq8(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Double Fault"); X86_IRQ_END } void int_irq9(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Coprocessor Segment Overrun"); X86_IRQ_END } void int_irq10(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Invalid TSS"); X86_IRQ_END } void int_irq11(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Segment Not Present"); X86_IRQ_END } void int_irq12(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Stack Segment Overrun"); X86_IRQ_END } void show_error(uint32_t err) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"interrupt error code: 0x%08x",err); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"External Event: %x",err&0b001); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Location: %x",err&0b110); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"Selector: %x",err&0b1111111111111000); } void int_irq13() { X86_IRQ_BEGIN uint32_t err; asm("pop %eax"); // get Error Code asm ("mov %%eax, %0":"=r"(err)); show_error(err); panic(FOOLOS_MODULE_NAME,"General Protection Fault"); X86_IRQ_END } void int_irq14(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Page Fault"); X86_IRQ_END } void int_irq15(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Unassigned"); X86_IRQ_END } void int_irq16(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Coprocessor error"); X86_IRQ_END } void int_irq17(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Alignment Check"); X86_IRQ_END } void int_irq18(){ X86_IRQ_BEGIN panic(FOOLOS_MODULE_NAME,"Machine Check"); X86_IRQ_END } // enable A20 // http://www.brokenthorn.com/Resources/OSDev9.html // Method 3.1: Enables A20 through keyboard controller /* void enable_a20() { // Not all keyboard controllers support this asm("mov $0xdd, %al");// ; command 0xdd: enable a20 // asm("mov $0xdf, %al");// ; command 0xdd: disable a20 asm("outb %al, $0x64");// ; send command to controller } */ /* void test_a20() { uint16_t *test=0x7dfe; test+=1024*1024; // *test=0x69; // test=0x8abcd; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"A20 test: 0x%02X ",*test); } */ ////////// KERNEL MAIN///// ///// // this is the very heart of our operating system! void kernel_main(uint32_t initial_stack) { // // We want to get output to the screen as fast as possible! // // Our Fool-Boot-Loader did set up VESA already for us. // The desired VESA mode is hardcoded in [boot/mbr.asm]. // // The [vesa_init(...)] function requires: // // * the addresses of the vbeinfo struct // * the address of the vbemodeinfo struct (for selected mode). // * the address of our Fool-Font binary data. // // The first two paramters are hardcoded in [boot/mbr.asm], // while the last one is set in the Makefile. The font binary // is integrated in the kernel image. // // this function returns the physical base address of // our video memory // uint32_t vesa_physbase=vesa_init(0x8300,0x8400,0x7200); // initial stack log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"initial esp: 0x%08X",initial_stack); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"setup PIC"); pic_setup(); // PIT config (timer) timer_init(); // we know that here, the bootloader placed the mamory map! mem_init(0x7c00+0x400,*((uint16_t *)(0x7c00+0x600))); // paging (pass the vesa physbase address for identity mapping) vmem_init(vesa_physbase); // // init and interrupt decriptor table int_init(0x08); int_install(); // setup custom interrupts // remember that we shifted all interrupts with the pic by 32 // so clock = 32 (irq 0) // keyboard = 33 (irq 1) // floppy = 38 (irq 6) // etc.. // install PIT interrupt handler int_install_ir(32, 0b10001110, 0x08,&int_clock_handler); // install keyboard interrupt handler int_install_ir(33, 0b10001110, 0x08,&int_kb_handler); // install floppy interrupt handler int_install_ir(38, 0b10001110, 0x08,&int_floppy_handler); // exceptions int_install_ir(0, 0b10001110, 0x08,&int_irq0); int_install_ir(1, 0b10001110, 0x08,&int_irq1); int_install_ir(2, 0b10001110, 0x08,&int_irq2); int_install_ir(3, 0b10001110, 0x08,&int_irq3); int_install_ir(4, 0b10001110, 0x08,&int_irq4); int_install_ir(5, 0b10001110, 0x08,&int_irq5); int_install_ir(6, 0b10001110, 0x08,&int_irq6); int_install_ir(7, 0b10001110, 0x08,&int_irq7); int_install_ir(8, 0b10001110, 0x08,&int_irq8); int_install_ir(9, 0b10001110, 0x08,&int_irq9); int_install_ir(10, 0b10001110, 0x08,&int_irq10); int_install_ir(11, 0b10001110, 0x08,&int_irq11); int_install_ir(12, 0b10001110, 0x08,&int_irq12); int_install_ir(13, 0b10001110, 0x08,&int_irq13); int_install_ir(14, 0b10001110, 0x08,&int_irq14); int_install_ir(15, 0b10001110, 0x08,&int_irq15); int_install_ir(16, 0b10001110, 0x08,&int_irq16); int_install_ir(17, 0b10001110, 0x08,&int_irq17); int_install_ir(18, 0b10001110, 0x08,&int_irq18); // now we can enable interrupts back again int_enable(); // int x=10/0; // pci pci_init(); // floppy // floppy_init(); //init shell shell_init(); // multitasking task_init(); /* log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test mem"); // test a20 disabled / wrap uint8_t *memtest=0x0; uint8_t *memtest2=0b10000000000000000000; *memtest=0xaf; log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test mem %x",*(memtest2-1)); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test mem %x",*memtest2); log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"test mem %x",*(memtest2+1)); */ /* stack pointer test? uint32_t *esp=0x90000; for(int i=0;i<10;i++) { log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"esp: %x",*esp); esp--; } */ while(1) { } }