void vm_bootstrap() { // get the number of free pages in ram paddr_t last_paddr = ram_getsize(); first_paddr = ram_getfirstfree(); // calculate the total page_count and coremap size page_count = (last_paddr - first_paddr) / PAGE_SIZE; // discarding the last addresses, if any size_t coremap_size = (sizeof(struct core_map_entry) * page_count); // can't call ram_stealmem() after calling ram_getfirstfree, // so steal memory for coremap here and update first_paddr if (first_paddr + coremap_size > last_paddr) { panic("Unable to allocate space for coremap"); } coremap = (struct core_map_entry*) PADDR_TO_KVADDR(first_paddr); first_paddr += coremap_size; // align the pages, the first page should start with an address which is a multiple of PAGE_SIZE if (first_paddr % PAGE_SIZE != 0) { first_paddr += PAGE_SIZE - (first_paddr % PAGE_SIZE); } else { //kprintf("CoreMap Size: %u bytes = %u pages\n", coremap_size, //coremap_size / PAGE_SIZE); } // update the page count, may reduce due to space allocation for coremap page_count = (last_paddr - first_paddr) / PAGE_SIZE; coremap_pages_free = page_count; // initialize the coremap unsigned i; for (i = 0; i < page_count; i++) { // update the state cm_setEntryUseState(COREMAP(i), false); cm_setEntryDirtyState(COREMAP(i), false); // let the address space identifier be NULL initially cm_setEntryAddrspaceIdent(COREMAP(i), NULL); // initial chunk start need not be initialized, will be updated when page is allocated } }
void vm_bootstrap(void) { spinlock_init(&coremap_lock); paddr_t fpaddr, lpaddr; uint32_t coremap_size; lpaddr = ram_getsize(); fpaddr = ram_getfirstfree(); no_of_physical_pages = (lpaddr-fpaddr) / PAGE_SIZE; // We do not consider the memory stolen by kernel during boot. // Should we ? coremap_size = no_of_physical_pages * sizeof(struct coremap_entry); coremap_size = ROUNDUP(coremap_size, PAGE_SIZE); KASSERT((coremap_size & PAGE_FRAME) == coremap_size); coremap = (struct coremap_entry *)PADDR_TO_KVADDR(fpaddr); // Placing the coremap at first available physical address. fpaddr = fpaddr + coremap_size; // Moving my fpaddr to accomadate the coremap. no_of_coremap_entries = (lpaddr - fpaddr) / PAGE_SIZE; // Absurd to store pages containing coremap in coremap. free_page_start = fpaddr / PAGE_SIZE; // First free page. This page maps to 0th entry of coremap. for (int i=0; i<no_of_coremap_entries;i++){ coremap[i].state = FREE; coremap[i].last_page = -1; coremap[i].as = NULL; coremap[i].cpu = -1; coremap[i].pinned = 0; coremap[i].page = NULL; coremap[i].accessed = 0; } page_buffer_lock = lock_create("page_buffer_lock"); clock_hand = 0; }
/* * Logic is to find the first free physical address from where we can start to initialize our coremap. * ram_getsize() returns total ram size, and ram_getfirstfree() returns first free physical address * We make sure that the coremap will reserve the memory that it is present in, to any process. * "freeAddr" variable gives us the actual physical address from which coremap will start to manage the memory. * Memory managed by coremap = [freeAddr, lastpaddr] **/ void vm_bootstrap(void) { int i; paddr_t freeAddr, temp; int coremap_size; // Get the total size of the RAM lastpaddr = ram_getsize(); firstpaddr= ram_getfirstfree(); // Get first free address on RAM // Number of pages that can be used to allocate coremap_page_num = (lastpaddr - firstpaddr) / PAGE_SIZE; // Calculate and set the first free address after coremap is allocated freeAddr = firstpaddr + coremap_page_num * sizeof(struct coremap_entry); freeAddr = ROUNDUP(freeAddr, PAGE_SIZE); // Allocate memory to coremap coremap = (struct coremap_entry *)PADDR_TO_KVADDR(firstpaddr); coremap_size = ROUNDUP( (freeAddr - firstpaddr),PAGE_SIZE) / PAGE_SIZE; // Initiliase each page status in coremap for(i =0 ; i < coremap_page_num; i++ ) { if (i < coremap_size) { coremap[i].state = DIRTY; } else { coremap[i].state = CLEAN; } temp = firstpaddr + (PAGE_SIZE * i); coremap[i].phyAddr= temp; coremap[i].allocPageCount = -1; coremap[i].va = PADDR_TO_KVADDR(temp); } // Set coremap used size to 0 coremap_used_size = 0; }