#include #include #include #include "fpu.h" #include "gdt.h" #include "gfx.h" #include "gfx_font.h" #include "idt.h" #include "initrd.h" #include "isr.h" #include "irq.h" #include "log.h" #include "multiboot.h" #include "paging.h" #include "panic.h" #include "pcspkr.h" #include "ps2kbd.h" #include "fpu.h" #include "timer.h" #include "version.h" #include "vfs.h" #include "vgatext.h" void gpf(struct regs_t *regs) { gfx_reset(); printf("General protection fault!\n"); printf("EIP before fault: 0x%x\n", regs->eip); printf("Error code: 0x%x\n", regs->err_code); panic("GPF!"); } void int80(struct regs_t *regs) { switch(regs->eax) { case 0: panic((const char*)regs->ebx); break; case 1: puts((const char*)regs->ebx); break; } } void div0(struct regs_t *regs) { (void) regs; panic("Divide by zero!\n"); } void nothin(struct regs_t* regs) { (void) regs; } void flash_leds(void) { printf("Testing keyboard LED's"); int n = 0; int s = 1; while(1) { ps2kbd_set_leds(PS2_NUM_LOCK); timer_delay(HZ/4); if(s < 0) putchar('\b'); else putchar('.'); n+=s; if(n<=0 || n>=3) s=-s; ps2kbd_set_leds(PS2_CAPS_LOCK); timer_delay(HZ/4); if(s < 0) putchar('\b'); else putchar('.'); n+=s; if(n<=0 || n>=3) s=-s; ps2kbd_set_leds(PS2_SCROLL_LOCK); timer_delay(HZ/4); if(s < 0) putchar('\b'); else putchar('.'); n+=s; if(n<=0 || n>=3) s=-s; ps2kbd_set_leds(PS2_CAPS_LOCK); timer_delay(HZ/4); if(s < 0) putchar('\b'); else putchar('.'); n+=s; if(n<=0 || n>=3) s=-s; } } bool boot(struct multiboot_info_t *hdr, uint32_t magic) { fpu_enable(); /* load initrd if any, this will also prevent modules from being clobbered by kmalloc */ initrd_init(hdr); /* this should go to port e9, which is the Bochs debug port */ printf("Testing early I/O\n"); printf("GFX init\n"); bool gfx_status = gfx_init((struct vbe_info_t*)hdr->vbe_mode_info); //bool gfx_status = false; printf("GFX init done.\n"); /* if graphical initialization fails, fall back to text mode */ if(!gfx_status) { vgatext_init(); printf("Graphics init failed, fell back to VGA text mode.\n"); } if(magic != 0x2BADB002) { panic("Multiboot magic invalid"); } /* then the descriptor tables so we can do more useful stuff */ gdt_init(); idt_init(); /* install all the interrupt stubs */ isr_init(); irq_init(); /* initialize other drivers */ timer_init(HZ); ps2kbd_init(); set_interrupt_handler(0, div0); set_interrupt_handler(0xd, gpf); set_interrupt_handler(0x80, int80); set_interrupt_handler(6, nothin); paging_init(); printf("Paging enabled.\n"); asm("sti"); printf("Boot finished.\n"); printf("Kernel version %s: \"%s\"\n", KAPPA_KERNEL_VERSION, KAPPA_KERNEL_CODENAME); return gfx_status; } void run_gfx_benchmark(void) { const int width = *gfx_width; const int height = *gfx_height; gfx_reset(); int startpix = *current_tick; for(int i=0;i<1000000;++i) { int rx = rand() % width; int ry = rand() % height; gfx_set_foreground(rand() % 0x1000000); gfx_drawpixel(rx, ry); } int endpix = *current_tick; gfx_reset(); int startfill = *current_tick; for(int i=0;i<1000;++i) { gfx_set_background(rand() % 0x1000000); gfx_clear(); } int endfill = *current_tick; gfx_reset(); int starttext = *current_tick; for(int i=0;i<1000000;++i) { int rx = rand() % width; int ry = rand() % height; gfx_set_foreground(rand() % 0x1000000); gfx_drawchar(rx, ry, rand()%127+1); } int endtext = *current_tick; gfx_reset(); int starthline = *current_tick; for(int i=0;i<1000000;++i) { gfx_set_foreground(rand() % 0x1000000); gfx_hline(rand() % width, rand() % width, rand() % height); } int endhline = *current_tick; gfx_reset(); int startvline = *current_tick; for(int i=0;i<1000000;++i) { gfx_set_foreground(rand() % 0x1000000); gfx_vline(rand() % height, rand() % height, rand() % width); } int endvline = *current_tick; gfx_reset(); int startrect = *current_tick; for(int i=0;i<10000;++i) { int x = rand() % width; int y = rand() % height; int w = rand() % (width - x); int h = rand() % (height - y); gfx_set_foreground(rand() % 0x1000000); gfx_fillrect(x, y, w, h); } int endrect = *current_tick; gfx_reset(); int startline = *current_tick; for(int i=0;i<1000000;++i) { int x1= rand() % width; int x2= rand() % width; int y1= rand() % height; int y2= rand() % height; gfx_set_foreground(rand() % 0x1000000); gfx_drawline(x1, y1, x2, y2); } int endline = *current_tick; gfx_reset(); printf("--- Graphics benchmark results ---\n"); printf("Ticks for 1,000,000 random pixels: %d\n", endpix-startpix); printf("Ticks for 1,000 random fills: %d\n", endfill-startfill); printf("Ticks for 1,000,000 random chars: %d\n", endtext-starttext); printf("Ticks for 1,000,000 random hlines: %d\n", endhline-starthline); printf("Ticks for 1,000,000 random vlines: %d\n", endvline-startvline); printf("Ticks for 10,000 random rects: %d\n", endrect-startrect); printf("Ticks for 1,000,000 random lines: %d\n", endline-startline); printf("Ticks per second: %d\n", HZ); printf("Resolution: %dx%dx%d\n", *gfx_width, *gfx_height, *gfx_bpp * 8); } static void keyhandler(const struct ps2_keyevent *ev) { if(ev->ascii) { if(ev->special_keys->ctrl) { putchar('^'); putchar(toupper(ev->ascii)); } else { putchar(ev->ascii); } } } void fs_test(void) { struct vfs_node *fs = vfs_init(); vfs_mkdir(fs, "bin"); vfs_mkdir(fs, "etc"); vfs_mkdir(fs, "bin"); vfs_creat(fs, "file1.txt"); vfs_creat(fs, "file2.txt"); vfs_creat(fs, "file3.txt"); vfs_creat(fs, "file4.txt"); vfs_creat(fs, "main.c"); DIR *file = vfs_opendir(fs); struct dirent *dir; printf("=== File listing of / ===\n"); do { dir = vfs_readdir(file); if(!dir) break; printf("%s", dir->d_name); if(dir->d_type == DT_DIR) putchar('/'); putchar('\n'); } while(dir); } void main(struct multiboot_info_t *hdr, uint32_t magic) { bool gfx_status = boot(hdr, magic); fs_test(); gfx_set_foreground(0x80FF80); printf("Hello, world!\n"); gfx_set_foreground(GFX_WHITE); ps2kbd_set_handler(keyhandler); while(1)asm("hlt"); //char *ptr = 0xA00000; //putchar(*ptr); printf("Starting linked-in application XRacer...\n"); //printf("Running graphics benchmark...\n"); srand(42); gfx_reset(); enum plugin_status; struct plugin_api; extern enum plugin_status xracer_main(const struct plugin_api*); extern void plugin_load(enum plugin_status (*func)(const struct plugin_api*)); //plugin_load(xracer_main); if(gfx_status) { run_gfx_benchmark(); } flash_leds(); }