//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) { init_pmm_manager (); page_init (); #ifndef NOCHECK //check_alloc_page(); #endif boot_pgdir = boot_alloc_page (); memset (boot_pgdir, 0, PGSIZE); boot_pgdir_pa = PADDR (boot_pgdir); current_pgdir_pa = boot_pgdir_pa; #ifndef NOCHECK //check_pgdir (); #endif static_assert(KERNBASE % PTSIZE == 0 && KERNTOP % PTSIZE == 0); boot_pgdir[PDX(VPT)] = PADDR(boot_pgdir) | PTE_P | PTE_SPR_R | PTE_SPR_W | PTE_A | PTE_D; boot_map_segment(boot_pgdir, KERNBASE, RAM_SIZE, 0, PTE_SPR_R | PTE_SPR_W | PTE_A | PTE_D); enable_paging (); #ifndef NOCHECK //check_boot_pgdir (); #endif print_pgdir (kprintf); slab_init (); }
int main(void) { cprintf("I am %d, print pgdir.\n", getpid()); print_pgdir(); cprintf("pgdir pass.\n"); return 0; }
int main(void) { struct slot *tmp, *head = NULL; int n = 0, rounds = 10; cprintf("I am going to eat out all the mem, MU HA HA!!.\n"); while (rounds > 0 && (tmp = (struct slot *)malloc(sizeof(struct slot))) != NULL) { if ((++n) % 1000 == 0) { cprintf("I ate %d slots.\n", n); rounds--; } tmp->next = head; head = tmp; head->data[0] = (char)n; } cprintf("I ate (at least) %d byte memory.\n", n * sizeof(struct slot)); print_pgdir(); int error = 0; while (head != NULL) { if (head->data[0] != (char)(n--)) { error++; } tmp = head->next; free(head); head = tmp; } cprintf("I free all the memory.(%d)\n", error); cprintf("brktest pass.\n"); return 0; }
//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 (); }
/* * * __panic - __panic is called on unresolvable fatal errors. it prints * "panic: 'message'", and then enters the kernel monitor. * */ void __panic(const char *file, int line, const char *fmt, ...) { if (is_panic) { goto panic_dead; } is_panic = 1; // print the 'message' va_list ap; va_start(ap, fmt); cprintf("kernel panic at %s:%d:\n ", file, line); print_pgdir(); vcprintf(fmt, ap); cprintf("\n"); va_end(ap); panic_dead: intr_disable(); while (1) { kmonitor(NULL); } }
static uint32_t sys_pgdir(uint32_t arg[]) { print_pgdir(kprintf); return 0; }
static int sys_pgdir(uint32_t arg[]) { print_pgdir(); return 0; }
static uint64_t sys_pgdir(uint64_t arg[]) { print_pgdir(); return 0; }