//pmm_init - setup a pmm to manage physical memory, build PDT&PT to setup paging mechanism // - check the correctness of pmm & paging mechanism, print PDT&PT void pmm_init(void) { //We need to alloc/free the physical memory (granularity is 4KB or other size). //So a framework of physical memory manager (struct pmm_manager)is defined in pmm.h //First we should init a physical memory manager(pmm) based on the framework. //Then pmm can alloc/free the physical memory. //Now the first_fit/best_fit/worst_fit/buddy_system pmm are available. init_pmm_manager(); // detect physical memory space, reserve already used memory, // then use pmm->init_memmap to create free page list page_init(); //use pmm->check to verify the correctness of the alloc/free function in a pmm check_alloc_page(); // create boot_pgdir, an initial page directory(Page Directory Table, PDT) boot_pgdir = boot_alloc_page(); memset(boot_pgdir, 0, PGSIZE); boot_cr3 = PADDR(boot_pgdir); check_pgdir(); static_assert(KERNBASE % PTSIZE == 0 && KERNTOP % PTSIZE == 0); // recursively insert boot_pgdir in itself // to form a virtual page table at virtual address VPT // cprintf("haah1\n"); // map all physical memory to linear memory with base linear addr KERNBASE //linear_addr KERNBASE~KERNBASE+KMEMSIZE = phy_addr 0~KMEMSIZE //But shouldn't use this map until enable_paging() & gdt_init() finished. boot_map_segment(boot_pgdir, 0, KMEMSIZE, 0, PTE_TYPE_URWX_SRWX | PTE_R | PTE_V); boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_TYPE_TABLE | PTE_R | PTE_V; // pgdir_alloc_page(boot_pgdir, USTACKTOP-PGSIZE , PTE_TYPE_URW_SRW); //cprintf("haha2\n"); //temporary map: //virtual_addr 3G~3G+4M = linear_addr 0~4M = linear_addr 3G~3G+4M = phy_addr 0~4M //boot_pgdir[0] = boot_pgdir[PDX(KERNBASE)]; //cprintf("OK!\n"); enable_paging(); // cprintf("haah\n"); //reload gdt(third time,the last time) to map all physical memory //virtual_addr 0~4G=liear_addr 0~4G //then set kernel stack(ss:esp) in TSS, setup TSS in gdt, load TSS //gdt_init(); //disable the map of virtual_addr 0~4M //boot_pgdir[0] = 0; //now the basic virtual memory map(see memalyout.h) is established. //check the correctness of the basic virtual memory map. check_boot_pgdir(); print_pgdir(); kmalloc_init(); }
/** * Initialize page management mechanism. * Parts of no use are deleted, while no extra parts except a check is added. * arch/x86/mm/pmm.c should be a good reference. */ void pmm_init (void) { check_vpm (); init_pmm_manager (); page_init (); check_alloc_page (); boot_pgdir = boot_alloc_page(); memset(boot_pgdir, 0, PGSIZE); check_pgdir(); /* register kernel code and data pages in the table so that it won't raise bad segv. */ boot_map_segment (boot_pgdir, KERNBASE, mem_size, 0, PTE_W); check_boot_pgdir (); print_pgdir (kprintf); slab_init (); }