// // Initialize page structure and memory free list. // After this is done, NEVER use boot_alloc again. ONLY use the page // allocator functions below to allocate and deallocate physical // memory via the page_free_list. // void page_init(void) { // LAB 4: // Change your code to mark the physical page at MPENTRY_PADDR // as in use // The example code here marks all physical pages as free. // However this is not truly the case. What memory is free? // 1) Mark physical page 0 as in use. // This way we preserve the real-mode IDT and BIOS structures // in case we ever need them. (Currently we don't, but...) // 2) The rest of base memory, [PGSIZE, npages_basemem * PGSIZE) // is free. // 3) Then comes the IO hole [IOPHYSMEM, EXTPHYSMEM), which must // never be allocated. // 4) Then extended memory [EXTPHYSMEM, ...). // Some of it is in use, some is free. Where is the kernel // in physical memory? Which pages are already in use for // page tables and other data structures? // // Change the code to reflect this. // NB: DO NOT actually touch the physical memory corresponding to // free pages! //bluesea //注意! //上述注释中说的都是针对物理内存的,因为我们对pages[]中的PageInfo进行初始化,而 //PageInfo是描述指定物理地址的页使用情况。 //所以需要弄清楚的是:在extended memory上的内核及数据结构占据了哪些物理地址, //而不是虚拟地址。 page_free_list = 0; size_t i, mpentry = MPENTRY_PADDR/PGSIZE; for (i = 0; i < npages; i++) { if (i == 0 || i == mpentry) set_page_used(&pages[i]); else if (i >= 1 && i < npages_basemem) set_page_free(&pages[i]); else if (i >= IOPHYSMEM / PGSIZE && i < EXTPHYSMEM / PGSIZE) set_page_used(&pages[i]); //这一段比较蛋疼... 没写的原因是一直不确定kernel除了自身加载进来的4M //以外,还有没有其他的变量占用内存。如PageInfo* pages, kern_pgdir等。 //后来才发现,pages需要自己在mem_init()初始化。。。 else if (i >= EXTPHYSMEM / PGSIZE && i < 0x400000 / PGSIZE) set_page_used(&pages[i]); else set_page_free(&pages[i]); } }
//find first page that is 0 int find_first_free_page(struct file_system *fs) { //finds first free page in free list int pos = 0; //position in array with an open array int i; int j=0; //position of first zero in number for (i=0; i < NUM_FREE_LIST_BYTES; i++) { if (fs->free_list[i]!=255) { pos = i; break; } } while(fs->free_list[pos] & (1<<(7-j))) { j++; } set_page_used(fs, pos*8+j); //set the page as taken return (int)sizeof(struct file_system) + (PAGE_SIZE*(pos*8+j)); //first free page number }