void initialize_paging(uint32_t memsize) { nframes = memsize / 4; frames = (uint32_t *)kmalloc(INDEX_FROM_BIT(nframes)); uintptr_t pg; assert(frames != NULL); memset(frames, 0, INDEX_FROM_BIT(nframes)); uintptr_t physical; kernel_directory = (page_directory_t *)kmalloc_ap(sizeof(page_directory_t), &physical); memset(kernel_directory, 0, sizeof(page_directory_t)); current_directory = kernel_directory; #if 1 get_page(0,1,kernel_directory)->present = 0; set_frame(0); for(uintptr_t i = 0x1000; i < placement_address+0x3000; i += 0x1000) #else for(uintptr_t i = 0x0; i < placement_address+0x3000; i += 0x1000) #endif { direct_frame( get_page(i, 1, kernel_directory), 1, 0, i); } kernel_directory->physical_addr = (uintptr_t)kernel_directory->tables_physical; uintptr_t heap_start = KERNEL_HEAP_START; if(heap_start <= placement_address + 0x3000) { heap_start = placement_address + 0x100000; } for (uintptr_t i = placement_address + 0x3000; i < heap_start; i += 0x1000) { alloc_frame(get_page(i, 1, kernel_directory), 1, 0); } for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000) { get_page(i, 1, kernel_directory); } for(uintptr_t i = heap_start; i < heap_start + KERNEL_HEAP_INIT; i += 0x1000) { alloc_frame(get_page(i, 1, kernel_directory), 0, 0); } register_isr_handler(13, general_protection_fault); register_isr_handler(14, page_fault); switch_page_directory(kernel_directory); kernel_heap = create_heap(heap_start, heap_start + KERNEL_HEAP_INIT, KERNEL_HEAP_END, 0, 0); //kernel_heap = create_heap(heap_start, KERNEL_HEAP_END, KERNEL_HEAP_END, 0, 0); }
void load_flat ( char* name, u32int loc) { FILE *bin; bin = ( FILE* ) f_open ( name, fs_root, "r" ); serialf ( "[FLATBIN] Opening \"%s\". ", name ); char *buf = ( char* ) kmalloc ( sizeof ( char ) * 1024 ); f_read ( bin, 0, 1024, buf ); virtual_map_pages ( loc, 0x1000, 1, 0 ); kmalloc_ap ( 1024, loc ); memset ( loc, 0, 1024 ); memcpy ( loc, buf, 1024 ); asm volatile ( "call *%0"::"r"(loc) ); serialf( "Executed.\n" ); }
struct page *get_page(uint32_t address, int creat, struct page_directory *dir) { uint32_t temp; uint32_t table_idx; address /= PAGE_SIZ; table_idx = address / 1024; if (dir->tables[table_idx]) return &dir->tables[table_idx]->pages[address%1024]; else if(creat) { dir->tables[table_idx] = (struct page_table *)kmalloc_ap(sizeof(struct page_table), &temp); memset(dir->tables[table_idx], 0, PAGE_SIZ); dir->tables_physical[table_idx] = temp | 0x7; return &dir->tables[table_idx]->pages[address%1024]; } return NULL; }
page_entry_t *get_page(uintptr_t address, int32_t make, page_directory_t *dir) { address /= 0x1000; uint32_t table_idx = address / 1024; if(dir->tables[table_idx]) { return &dir->tables[table_idx]->pages[address % 1024]; } else if(make) { uint32_t tmp; dir->tables[table_idx] = (page_table_t*)kmalloc_ap(sizeof(page_table_t), (uintptr_t*)(&tmp)); memset(dir->tables[table_idx], 0, sizeof(page_table_t)); dir->tables_physical[table_idx] = tmp | 0x7; return &dir->tables[table_idx]->pages[address % 1024]; } else { return NULL; } }
void main(uint32_t magic, struct multiboot_info *mbi, uintptr_t esp, uintptr_t stack_end) { stack_start = esp; stack_size = stack_end - stack_start; vga_driver = vga_init(); com_driver = serial_init(); logging_init(vga_driver, com_driver); assert(magic == MULTIBOOT_MAGIC); assert(mbi->flags & MULTIBOOT_LOADER); kprintf(INFO, "\033\012Toutatis kernel booting from %s\033\017\n", (char *)(mbi->boot_loader_name + (uint32_t)&kernel_voffset)); arch_init(); initrd_init(mbi); assert(mbi->flags & MULTIBOOT_MEMINFO); paging_init((mbi->mem_lower + mbi->mem_upper) * 1024); paging_mark_reserved((uint32_t)mbi - (uint32_t)&kernel_voffset); assert(mbi->flags & MULTIBOOT_MMAP); for (mmap_entry_t *mmap = (mmap_entry_t *)(mbi->mmap_addr + (uint32_t)&kernel_voffset); (uint32_t)mmap < mbi->mmap_addr + (uint32_t)&kernel_voffset + mbi->mmap_length; mmap = (mmap_entry_t *)((uint32_t)mmap + mmap->size + sizeof(mmap->size))) { if (mmap->type == 2) { for (uint64_t i = 0; i < mmap->length; i += FRAME_SIZE) { paging_mark_reserved((mmap->addr + i) & 0xfffff000); } } } paging_finalize(); void *p1 = kmalloc(8); void *p2 = kmalloc(8); *((char *)p1) = 'a'; kprintf(INFO, "p1 @ 0x%x\n", (uint32_t)p1); kprintf(INFO, "p2 @ 0x%x\n", (uint32_t)p2); kfree(p2); kfree(p1); void *p3 = kmalloc(16); kprintf(INFO, "p3 @ 0x%x\n", (uint32_t)p3); uintptr_t phys; void *p4 = kmalloc_ap(0x1a0000, &phys); memset(p4, 0, 0x1a0000); *((char *)p4) = 'z'; kprintf(INFO, "p4 @ 0x%x phys = %x\n", (uint32_t)p4, phys); void *p5 = kmalloc(0x02); kprintf(INFO, "p5 @ 0x%x\n", (uint32_t)p5); kfree(p5); kfree(p4); kfree(p3); print_mmap(mbi); syscall_init(); scheduling_init(); keyboard_init(); process_t *proc1 = create_process("Process 1", 1); process_t *proc2 = create_process("Process 2", 1); process_t *proc3 = create_process("Process 3", 1); process_t *procs[] = { proc1, proc2, proc3 }; unsigned int k = 0; unsigned int off = 0; for (k = 0; k < 10; ++k) { if (!create_thread(procs[k % 3], func2, (void *)(off + 80*2), 1, 0, 0)) { kprintf(INFO, "Oups\n"); stop(); } if (!create_thread(procs[k % 3], func1, (void *)k, 1, 1, 0)) { kprintf(INFO, "Oups\n"); stop(); } off += 2; } //create_thread(proc1, func3, (void *)0, 1, 1, 1); k = 0; unsigned int i = 0; off = 0; for (;;) { uint16_t *video = (uint16_t *)(0xc00b8000 + 80); *video = (uint16_t)alph[i++ % sizeof(alph)] | 0x0f00; if (k % 1 == 0) { //set_pos(0, 23); //vga_print_dec(k); //kprintf(INFO, "mem used: %6x num threads:%3d \n", mem_used(kheap), get_num_threads()); } /* if (!create_thread(proc1, func2, (void *)(off + 80*2), 1, 0, 0)) { kprintf(INFO, "Oups\n"); break; } off += 2; off %= (60 * (25-2)); */ char c = keyboard_lastchar(); if (c == 'u') { create_thread(proc1, func1, (void *)5, 1, 1, 0); } else if (c == 'k') { create_thread(proc1, func2, (void *)off, 1, 0, 0); off += 2; } ++k; } serial_terminate(); stop(); }
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; } }