static void tasking_critical_fail() { Deprecated(); char* msg = "One or more critical tasks died. axle has died.\n"; printf("%s\n", msg); //turn off interrupts kernel_begin_critical(); //sleep until next interrupt (infinite loop) asm("hlt"); //in case that ever finishes, infinite loop again while (1) {} }
Screen* switch_to_vga() { kernel_begin_critical(); int width = 320; int height = 200; Screen* screen = (Screen*)kmalloc(sizeof(Screen)); screen->window = create_window(rect_make(point_make(0, 0), size_make(width, height))); screen->depth = VGA_DEPTH; screen->vmem = kmalloc(width * height * sizeof(uint8_t)); screen->physbase = VRAM_START; screen->font = setup_font(); regs16_t regs; regs.ax = 0x0013; int32(0x10, ®s); //start refresh loop setup_vga_screen_refresh(screen, 33); kernel_end_critical(); return screen; }
//sets up VESA for mode Screen* switch_to_vesa() { kernel_begin_critical(); vesa_info info; vbe_mode_info mode_info; regs16_t regs; //get VESA information //buffer stores info before being copied into structure uint32_t buffer = (uint32_t)kmalloc(sizeof(vesa_info)) & 0xFFFFF; memcpy(buffer, "VBE2", 4); memset(®s, 0, sizeof(regs)); regs.ax = 0x4F00; //00 gets VESA information regs.di = buffer & 0xF; regs.es = (buffer >> 4) & 0xFFFF; int32(0x10, ®s); //copy info from buffer into struct memcpy(&info, buffer, sizeof(vesa_info)); //get VESA mode information //buffer to store mode info before copying into structure uint32_t mode_buffer = (uint32_t)kmalloc(sizeof(vbe_mode_info)) & 0xFFFFF; memset(®s, 0, sizeof(regs)); uint32_t vesa_mode = 0x118; //1024x768x24 regs.ax = 0x4F01; //01 gets VBE mode information regs.di = mode_buffer & 0xF; regs.es = (mode_buffer >> 4) & 0xFFFF; regs.cx = vesa_mode; //mode to get info for int32(0x10, ®s); //copy mode info from buffer into struct memcpy(&mode_info, mode_buffer, sizeof(vbe_mode_info)); regs.ax = 0x4F02; //02 sets graphics mode //sets up mode with linear frame buffer instead of bank switching //or 0x4000 turns on linear frame buffer regs.bx = (vesa_mode | 0x4000); int32(0x10, ®s); Screen* screen = (Screen*)kmalloc(sizeof(Screen)); screen->vmem = kmalloc(mode_info.x_res * mode_info.y_res * (mode_info.bpp / 8)); screen->depth = mode_info.bpp; //linear frame buffer (LFB) address screen->physbase = (uint8_t*)mode_info.physbase; screen->font = setup_font(); screen->window = create_window(rect_make(point_make(0, 0), size_make(mode_info.x_res, mode_info.y_res))); set_frame(screen->window->title_view, rect_make(point_make(0, 0), size_make(0, 0))); set_frame(screen->window->content_view, screen->window->frame); set_border_width(screen->window, 0); desktop_setup(screen); //start refresh loop //screen->finished_drawing = 0; setup_vesa_screen_refresh(screen, 83); //refresh once now so we don't wait for the first tick vesa_screen_refresh(screen); kernel_end_critical(); return screen; }
void elf_load_file(char* name, FILE* elf, char** argv) { //find file size fseek(elf, 0, SEEK_END); uint32_t binary_size = ftell(elf); fseek(elf, 0, SEEK_SET); char* filebuf = kmalloc(binary_size); for (uint32_t i = 0; i < binary_size; i++) { filebuf[i] = fgetc(elf); } elf_header* hdr = (elf_header*)filebuf; if (!elf_validate_header(hdr)) { return; } uint32_t new_dir_phys = 0; page_directory_t* new_dir = kmalloc_ap(sizeof(page_directory_t), &new_dir_phys); memset((uint8_t*)new_dir, 0, sizeof(page_directory_t)); //get offset of tablesPhysical from start of page_directory_t uint32_t offset = (uint32_t)new_dir->tablesPhysical - (uint32_t)new_dir; new_dir->physicalAddr = new_dir_phys + offset; for (int i = 0; i < 1024; i++) { new_dir->tables[i] = page_dir_kern()->tables[i]; new_dir->tablesPhysical[i] = page_dir_kern()->tablesPhysical[i] & ~4; } char* string_table = elf_get_string_table(hdr, binary_size); uint32_t prog_break = 0; uint32_t bss_loc = 0; for (int x = 0; x < hdr->shentsize * hdr->shnum; x += hdr->shentsize) { if (hdr->shoff + x > binary_size) { printf("Tried to read beyond the end of the file.\n"); return; } elf_s_header* shdr = (elf_s_header*)((uintptr_t)filebuf + (hdr->shoff + x)); char* section_name = (char*)((uintptr_t)string_table + shdr->name); //alloc memory for .bss segment if (!strcmp(section_name, ".bss")) { alloc_bss(new_dir, shdr, (int*)&prog_break, (int*)&bss_loc); } } uint32_t entry = elf_load_small(new_dir, (unsigned char*)filebuf); kfree(filebuf); //alloc stack space uint32_t stack_addr = 0x10000000; //give user program a 128kb stack for (int i = 0; i < 32; i++) { page_t* stacktop = get_page(stack_addr, 1, new_dir); //user, writeable alloc_frame(stacktop, 0, 1); stack_addr += PAGE_SIZE; } stack_addr -= PAGE_SIZE; //calculate argc count int argc = 0; while (argv[argc] != NULL) { argc++; } if (entry) { become_first_responder(); kernel_begin_critical(); task_t* elf = task_with_pid(getpid()); elf->prog_break = prog_break; elf->bss_loc = bss_loc; elf->name = strdup(name); elf->esp = elf->ebp = stack_addr; elf->eip = entry; elf->page_dir = new_dir; void goto_pid(int id, bool x); goto_pid(elf->id, false); /* int(*elf_main)(int, char**) = (int(*)(int, char**))entry; become_first_responder(); //calculate argc count int argc = 0; char* tmp = argv[argc]; while (argv[argc] != NULL) { argc++; } //jump to ELF entry point! int ret = elf_main(argc, argv); */ //binary should have called _exit() //if we got to this point, something went catastrophically wrong ASSERT(0, "ELF binary returned execution to loader!"); } else { printf_err("ELF wasn't loadable!"); return; } }