static kstatus_t	retain_helper(struct _physicalMemoryManager* self, unsigned nbr_page, 
				      IPhysicalPage* out_pages, BOOL try_to_search_in_free_page_list)
{
  for (unsigned i = 0; i < nbr_page; i++)
    {
      IPhysicalPage page_to_give = 0x0;

      /* First try to get from free list
       */
      if (try_to_search_in_free_page_list)
	page_to_give = SINGLY_LINKED_LIST_FIRST_VALUE(self->_freePageList);
      if (page_to_give) /* There is a free page available */
	{
	  SINGLY_LINKED_LIST_POP(self->_freePageList); /* Remove from free page list */
	}
      else /* Free page list is empty */
	{
	  /* Move the kernel extended memory top address
	   */
	  ASSERT(self->_extendedMemoryTop > self->_usedExtendedMemoryTop, "Extended memory full");
	  page_to_give = physical_page_alloc(); /* Alloc a new physical page object */
	  page_to_give->initWithPhysicalAddress(page_to_give, self->_usedExtendedMemoryTop); /* Associate top address with page */
	  self->_usedExtendedMemoryTop += PAGESIZE;
	}
      ASSERT(page_to_give != 0x0, "page_to_give is null");

      /* Insert in caller output
       */
      out_pages[i] = page_to_give;
    }

  return KS_SUCCESS;
}
예제 #2
0
// copyseg(p, ph, src)
//    Load an ELF segment at virtual address `ph->p_va` in process `p`. Copies
//    `[src, src + ph->p_filesz)` to `dst`, then clears
//    `[ph->p_va + ph->p_filesz, ph->p_va + ph->p_memsz)` to 0.
//    Calls `physical_page_alloc` to allocate pages and `virtual_memory_map`
//    to map them in `p->p_pagetable`. Returns 0 on success and -1 on failure.
static int copyseg(proc* p, const elf_program* ph, const uint8_t* src) {
    uintptr_t va = (uintptr_t) ph->p_va;
    uintptr_t end_file = va + ph->p_filesz, end_mem = va + ph->p_memsz;
    va &= ~(PAGESIZE - 1);              // round to page boundary

    // allocate memory
    for (uintptr_t page_va = va; page_va < end_mem; page_va += PAGESIZE) {
        if (physical_page_alloc(page_va, p->p_pid) < 0)
            return -1;
        virtual_memory_map(p->p_pagetable, page_va, page_va,
                           PAGESIZE, PTE_P|PTE_W|PTE_U);
    }
    // ensure new memory mappings are active
    lcr3((uintptr_t) p->p_pagetable);

    memcpy((uint8_t*) va, src, end_file - va);
    memset((uint8_t*) end_file, 0, end_mem - end_file);
    return 0;
}