Ejemplo n.º 1
0
//
// 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)
{
	// 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!
	/*stone's solution for lab2*/
	size_t i;
	for (i = 1; i < npages_basemem; i++){
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
	//use boot_alloc(0) to get next free page
	for (i = (PADDR(boot_alloc(0)) / PGSIZE); i < npages; i++){
		 pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
	chunk_list = NULL;
}
Ejemplo n.º 2
0
Archivo: pmap.c Proyecto: yahu/JOS
// map physcical memory [0,PGSIZE*npages] to [KERNBASE,KERNBASE+PGSIZE*npages] ,in case
// one physical memory can't find its virtual address
static void
boot_phys_map()
{
    uintptr_t sp=KERNBASE+0X400000;
    int i,j;
    pte_t* pgtable;
    pde_t* entry_pgdir=(pde_t*)(rcr3()+KERNBASE);

    int npts= (npages / 1024)+1;

    int actual_top=KERNBASE+npages*PGSIZE;

    for(i=0; i<npts && sp<actual_top; i++){

        pgtable=boot_alloc(PGSIZE);
        memset(pgtable, 0, PGSIZE);

        entry_pgdir[PDX(sp)]=((int)pgtable-KERNBASE) | PTE_P | PTE_U | PTE_W;
       // cprintf("the entry_pgdir'%dth pde is  %x\n ",PDX(sp),(int)entry_pgdir[PDX(sp)]);

        for(j=0;j<1024 && sp<actual_top;j++){

            pgtable[j]=((uint32_t)sp-KERNBASE) | PTE_P | PTE_U | PTE_W;
            sp+=PGSIZE;
        }

    }

}
Ejemplo n.º 3
0
static void *
segkmem_alloc_vn(vmem_t *vmp, size_t size, int vmflag, struct vnode *vp)
{
	void *addr;
	segkmem_gc_list_t *gcp, **prev_gcpp;

	ASSERT(vp != NULL);

	if (kvseg.s_base == NULL) {
#ifndef __sparc
		if (bootops->bsys_alloc == NULL)
			halt("Memory allocation between bop_alloc() and "
			    "kmem_alloc().\n");
#endif

		/*
		 * There's not a lot of memory to go around during boot,
		 * so recycle it if we can.
		 */
		for (prev_gcpp = &segkmem_gc_list; (gcp = *prev_gcpp) != NULL;
		    prev_gcpp = &gcp->gc_next) {
			if (gcp->gc_arena == vmp && gcp->gc_size == size) {
				*prev_gcpp = gcp->gc_next;
				return (gcp);
			}
		}

		addr = vmem_alloc(vmp, size, vmflag | VM_PANIC);
		if (boot_alloc(addr, size, BO_NO_ALIGN) != addr)
			panic("segkmem_alloc: boot_alloc failed");
		return (addr);
	}
	return (segkmem_xalloc(vmp, NULL, size, vmflag, 0,
	    segkmem_page_create, vp));
}
Ejemplo n.º 4
0
//
// 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)
{
	// 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!
	size_t i;
	page_free_list = 0;

	extern char end[]; // Magic pointer to end of kernel data
	
	uint32_t free_pages = 0;
	for (i = npages-1; i + 1 > 0; i--) {
		pages[i].pp_ref = 0;

		// Base memory pages other than 0 are free: add them to the free list
		if ((i < npages_basemem) && (i != 0)) {
			//	pages[i].pp_ref = 0;
			pages[i].pp_link = page_free_list;
			page_free_list = &pages[i];
			free_pages++;
		}
		
		// Skip the IO hole

		// Some of extended memory is free: focus our attention there
		if (i >= (EXTPHYSMEM / PGSIZE)) {
			// The kernel isn't free!
			if (i < (PADDR(ROUNDUP((char *) end, PGSIZE)) / PGSIZE)) {
				continue;
			}
			// We've allocated some number of pages using boot alloc...
			if (i < ((size_t) PADDR(boot_alloc(0))) / PGSIZE) {
				continue;
			}
			// Otherwise, the memory is free XXX What about the kernel stack?
		        //pages[i].pp_ref = 0;
			pages[i].pp_link = page_free_list;
			page_free_list = &pages[i];
			free_pages++;
		}
	}
	//cprintf("Reserved up to %x for kernel\n", ROUNDUP((char *) end, PGSIZE));
	//cprintf("Finished page_init. %d free pages remain.\n", free_page_count());
}
Ejemplo n.º 5
0
//
// Check that the pages on the page_free_list are reasonable.
//
static void
check_page_free_list(bool only_low_memory)
{
	struct Page *pp;
	unsigned pdx_limit = only_low_memory ? 1 : NPDENTRIES;
	int nfree_basemem = 0, nfree_extmem = 0;
	char *first_free_page;

	if (!page_free_list)
		panic("'page_free_list' is a null pointer!");

	if (only_low_memory) {
		// Move pages with lower addresses first in the free
		// list, since entry_pgdir does not map all pages.
		struct Page *pp1, *pp2;
		struct Page **tp[2] = { &pp1, &pp2 };
		for (pp = page_free_list; pp; pp = pp->pp_link) {
			int pagetype = PDX(page2pa(pp)) >= pdx_limit;
			*tp[pagetype] = pp;
			tp[pagetype] = &pp->pp_link;
		}
		*tp[1] = 0;
		*tp[0] = pp2;
		page_free_list = pp1;
	}

	// if there's a page that shouldn't be on the free list,
	// try to make sure it eventually causes trouble.
	for (pp = page_free_list; pp; pp = pp->pp_link)
		if (PDX(page2pa(pp)) < pdx_limit)
			memset(page2kva(pp), 0x97, 128);

	first_free_page = (char *) boot_alloc(0);
	for (pp = page_free_list; pp; pp = pp->pp_link) {
		// check that we didn't corrupt the free list itself
		assert(pp >= pages);
		assert(pp < pages + npages);
		assert(((char *) pp - (char *) pages) % sizeof(*pp) == 0);

		// check a few pages that shouldn't be on the free list
		assert(page2pa(pp) != 0);
		assert(page2pa(pp) != IOPHYSMEM);
		assert(page2pa(pp) != EXTPHYSMEM - PGSIZE);
		assert(page2pa(pp) != EXTPHYSMEM);
		assert(page2pa(pp) < EXTPHYSMEM || (char *) page2kva(pp) >= first_free_page);
		// (new test for lab 4)
		assert(page2pa(pp) != MPENTRY_PADDR);

		if (page2pa(pp) < EXTPHYSMEM)
			++nfree_basemem;
		else
			++nfree_extmem;
	}

	assert(nfree_basemem > 0);
	assert(nfree_extmem > 0);

	cprintf("check_page_free_list() succeeded!\n");
}
Ejemplo n.º 6
0
//
// 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)
{
	// 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 of 384K [IOPHYSMEM starts at 640k, EXTPHYSMEM starts at 1MB), 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!
	size_t i,j;
	struct PageInfo *tail;
	//Initially setting all pages as used.
		for(i=0;i<npages;i++){
		pages[i].pp_ref=1;
		pages[i].pp_link=0;
	}	

	//setting phsyical page 0 in use	
		//pages[0].pp_ref=1;
		//pages[0].pp_link=&pages[ROUNDUP(EXTPHYSMEM,PGSIZE)/PGSIZE];
	//Mark Pages 1 to IOPHYSMEM as free
		page_free_list = 0;
	for (i = 1; i < npages_basemem ; ++i) {
		pages[i].pp_ref = 0;
		pages[i].pp_link =0;
		if(!page_free_list)
			page_free_list=&pages[i];
		else{
		//cprintf("page: %d and page-1: %d\n",i,i-1); 
		 pages[i-1].pp_link=&pages[i];		
		}
	}
	
	tail=&pages[i-1];
	// Map rest of free memory
	for(j=((ROUNDUP(PADDR(boot_alloc(0)),PGSIZE)/PGSIZE)+1);j<npages;++j){
		//cprintf(" print j  %d and j-1 %d \n",j,j-1 ); 
		pages[j].pp_ref = 0;
		pages[j].pp_link =0;
		tail->pp_link=&pages[j];
		tail=&pages[j];
	}
	
		
}
Ejemplo n.º 7
0
//
// 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!
	size_t i;
	for (i = 0; i < npages; i++) {
        if (i == 0 || i == MPENTRY_PADDR / PGSIZE) {
            // This is case 1 or
            // This is the multiprocessor case
    		pages[i].pp_ref = 1;
        }
        else if (i >= 1 && i < npages_basemem) {
            // This is case 2
    		pages[i].pp_ref = 0;
	    	pages[i].pp_link = page_free_list;
		    page_free_list = &pages[i];
        }
        else if (i >= IOPHYSMEM / PGSIZE && i < EXTPHYSMEM / PGSIZE) {
            // This is case 3
    		pages[i].pp_ref = 1;
        }
        else if (i >= EXTPHYSMEM / PGSIZE && i < PADDR(boot_alloc(0)) / PGSIZE) {
            // This is case 4
    		pages[i].pp_ref = 1;
        }
        else {
    		pages[i].pp_ref = 0;
	    	pages[i].pp_link = page_free_list;
		    page_free_list = &pages[i];
        }
	}
}
Ejemplo n.º 8
0
void initialize_vm_64(void){
	uint64_t* pml4e;
    pages = boot_alloc(npages*sizeof(struct PageStruct));
    procs = boot_alloc(NPROCS*sizeof(struct ProcStruct)); 
    proc_free_list = procs;

	pml4e = boot_alloc(PGSIZE);
	boot_pml4e = pml4e;
	boot_cr3 = (physaddr_t*)PADDR(pml4e);
	kmemset(boot_pml4e,0,PGSIZE);
         initialize_page_lists();
    printf("Total free=%d",free_pages); 

  //    while(i--);
   if(  map_vm_pm(boot_pml4e, (uint64_t)PHYSBASE,PADDR(PHYSBASE),(uint64_t)(boot_alloc(0)-PHYSBASE),PTE_P|PTE_W)==-1)
       while(1);
   if(  map_vm_pm(boot_pml4e, (uint64_t)KERNBASE+PGSIZE,0x1000,0x7000000-0x1000,PTE_P|PTE_W)==-1)//KERNELSTACK =tss.rspp0       
   while(1);
   if( map_vm_pm(boot_pml4e, (uint64_t)VIDEO_START,PADDR(VIDEO_START),10*0x1000,PTE_P|PTE_W)==-1)
    while(1);
    printf("TotalFREE=%d",free_pages);
   
     lcr3(boot_cr3);
}
Ejemplo n.º 9
0
//
// 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)
{
	// 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!

	uint32_t num_alloc = ((uint32_t)boot_alloc(0)-KERNBASE)/PGSIZE;
	uint32_t num_io_pages = (EXTPHYSMEM - IOPHYSMEM)/PGSIZE;
	page_free_list = NULL;

	size_t i;

	for(i = 0; i < npages; ++i) {
		if((i == 0)||
				// io hole
				( i >= npages_basemem && i<npages_basemem+num_io_pages )||
				// alloc by kernel, kernel alloc pages and kern_pgdir on stack
				// num_alloc isn't all pages used, it is just memory used by kernel
				( i >= npages_basemem+num_io_pages && i < npages_basemem+num_io_pages+num_alloc  )) {
			pages[0].pp_ref = 1;	
		}else {
			pages[i].pp_ref = 0;
			pages[i].pp_link = page_free_list;
			page_free_list = &pages[i];
		}

	}
}
Ejemplo n.º 10
0
Archivo: pmap.c Proyecto: yuki252111/os
//
// 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)
{
	// 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!
	int i;
	physaddr_t firstFreePhysAddr=(physaddr_t)PADDR(boot_alloc(0));
	page_free_list=NULL;
	for (i = npages-1; i >= 0; i--) 
	{
	     physaddr_t pagePhysAddr=(physaddr_t)PGADDR(0,i,0);
	     if(pagePhysAddr==0||
		(pagePhysAddr>=IOPHYSMEM&&pagePhysAddr<firstFreePhysAddr))
	     {
		pages[i].pp_ref=1;
		pages[i].pp_link=NULL;
	     }
	     else
	     {
		pages[i].pp_ref=0;
		pages[i].pp_link=page_free_list;
		page_free_list=&pages[i];
             }
	}
	
}
Ejemplo n.º 11
0
/**
 * @brief Initialize the array of physical pages and memory free list.
 *
 * The 'pages' array has one 'page_t' entry per physical page.
 * Pages are reference counted, and free pages are kept on a linked list.
 */
void page_init(void)
{
	/*
     * First, make 'pages' point to an array of size 'npages' of
	 * type 'page_t'.
	 * The kernel uses this structure to keep track of physical pages;
	 * 'npages' equals the number of physical pages in memory.
	 * round up to the nearest page
	 */
	pages = (page_t*)boot_alloc(npages*sizeof(page_t), PGSIZE);
	memset(pages, 0, npages*sizeof(page_t));

	/*
     * Then initilaize everything so pages can start to be alloced and freed
	 * from the memory free list
	 */
	page_alloc_init();

	static_assert(PROCINFO_NUM_PAGES <= PTSIZE);
	static_assert(PROCDATA_NUM_PAGES <= PTSIZE);
}
Ejemplo n.º 12
0
//
// Check that the pages on the page_free_list are reasonable.
//
static void
check_page_free_list(bool only_low_memory)
{
	struct Page *pp;
	unsigned pdx_limit = only_low_memory ? 4 : NPDENTRIES;
	int nfree_basemem = 0, nfree_extmem = 0;
	char *first_free_page;

	if (!page_free_list)
		panic("'page_free_list' is a null pointer!");

	// if there's a page that shouldn't be on the free list,
	// try to make sure it eventually causes trouble.
	for (pp = page_free_list; pp; pp = pp->pp_link)
		if (PDX(page2pa(pp)) < pdx_limit)
			memset(page2kva(pp), 0x97, 128);

	first_free_page = (char *) boot_alloc(0);
	for (pp = page_free_list; pp; pp = pp->pp_link) {
		// check that we didn't corrupt the free list itself
		assert(pp >= pages);
		assert(pp < pages + npages);
		assert(((char *) pp - (char *) pages) % sizeof(*pp) == 0);

		// check a few pages that shouldn't be on the free list
		assert(page2pa(pp) != 0);
		assert(page2pa(pp) != IOPHYSMEM);
		assert(page2pa(pp) != EXTPHYSMEM - PGSIZE);
		assert(page2pa(pp) != EXTPHYSMEM);
		assert(page2pa(pp) < EXTPHYSMEM || page2kva(pp) >= first_free_page);

		if (page2pa(pp) < EXTPHYSMEM)
			++nfree_basemem;
		else
			++nfree_extmem;
	}

	assert(nfree_basemem > 0);
	assert(nfree_extmem > 0);
}
Ejemplo n.º 13
0
//
// 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)
{
	// 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!
	size_t i;
	//start i from 1 as 0 in use
	//Sets [PGSIZE, npages_basemem * PGSIZE) as free.
	for (i = 1; i < npages_basemem; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}

	//boot_alloc(0) gives the address of the next free page,after the kernel strucutres
	//cprintf("&&&**** %x %x %x, %x\n", boot_alloc(0), PADDR(boot_alloc(0)), PGNUM(boot_alloc(0)), PGNUM(PADDR(boot_alloc(0)))); 
	for (i = PGNUM(PADDR(boot_alloc(0))); i < npages; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
	
	
}
Ejemplo n.º 14
0
//
// 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!
	size_t i;
	extern char end[];
	uint32_t upp = PADDR(boot_alloc(0));
	cprintf("end: %x npages: %d sizeof struct Page: %x PGSIZE: %x IOPHYSMEM: %x\n",end,npages,sizeof(struct Page),PGSIZE,IOPHYSMEM);
	for (i = 0; i < npages; i++) {
		if (i == 0) continue;
		if ((i >= PGNUM(IOPHYSMEM) && 
			i < PGNUM(upp)) || i==MPENTRY_PADDR/PGSIZE)
			continue;
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}

}
Ejemplo n.º 15
0
//
// 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!
    int i;
    int st = PTX(IOPHYSMEM);
    int en = (int)PTX(PADDR(boot_alloc(0)));
	page_free_list = NULL;
    for (i = 1; i < npages; i++) {
        if (st <= i && i< en) continue;
        if (i == PTX(MPENTRY_PADDR)) continue;
        pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
        //page is in use if pp_link == NULL
	}
}
Ejemplo n.º 16
0
//
// 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)
{
	// 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!
	size_t i;
	uint32_t nextfree = (uint32_t)boot_alloc(0);
	pages[0].pp_ref = 1;
	debug(DEBUG_INFO, "NPAGES: %d NPAGES_BASE_MEM: %d\n", npages, npages_basemem);
	for (i = 1; i < npages; i++) {
		if ((i >= (IOPHYSMEM / PGSIZE)) && (i < ((nextfree - KERNBASE)/ PGSIZE))) {
			pages[i].pp_ref = 1;
			pages[i].pp_link = NULL;
			}
		else {
			pages[i].pp_ref = 0;
			pages[i].pp_link = page_free_list;
			page_free_list = &pages[i];
		}
	}
}
Ejemplo n.º 17
0
//
// 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)
{
	// 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!
/*
	size_t i;
	for (i = 0; i < npages; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
*/
	size_t i;
	void * free_vaddress;
	physaddr_t free_paddress;

	// page 0
	pages[0].pp_ref = 0;
	pages[0].pp_link = NULL;

	// base memory
	for (i = 1; i < npages_basemem; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}

	// IO hole
	assert (IOPHYSMEM % PGSIZE == 0 && EXTPHYSMEM % PGSIZE == 0);
	assert (npages_basemem * PGSIZE == IOPHYSMEM);
	for (i = npages_basemem; i < EXTPHYSMEM / PGSIZE; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = NULL;
	}

	// extended memory
	free_vaddress = boot_alloc(0);
	free_paddress = PADDR(free_vaddress);
	assert(free_paddress > EXTPHYSMEM && free_paddress % PGSIZE == 0 && free_paddress < npages * PGSIZE && free_paddress/PGSIZE < npages);
	for (i = EXTPHYSMEM / PGSIZE; i < free_paddress / PGSIZE; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = NULL;
	}

	for (i = free_paddress / PGSIZE; i < npages; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}	
}
Ejemplo n.º 18
0
// Set up a two-level page table:
//    kern_pgdir is its linear (virtual) address of the root
//
// This function only sets up the kernel part of the address space
// (ie. addresses >= UTOP).  The user part of the address space
// will be setup later.
//
// From UTOP to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read or write.
void
mem_init(void)
{
	uint32_t cr0;
	size_t n;

	// Find out how much memory the machine has (npages & npages_basemem).
	i386_detect_memory();

	//////////////////////////////////////////////////////////////////////
	// create initial page directory.
	kern_pgdir = (pde_t *) boot_alloc(PGSIZE);
	memset(kern_pgdir, 0, PGSIZE);

	//////////////////////////////////////////////////////////////////////
	// Recursively insert PD in itself as a page table, to form
	// a virtual page table at virtual address UVPT.
	// (For now, you don't have understand the greater purpose of the
	// following line.)

	// Permissions: kernel R, user R
	kern_pgdir[PDX(UVPT)] = PADDR(kern_pgdir) | PTE_U | PTE_P;

	//////////////////////////////////////////////////////////////////////
	// Allocate an array of npages 'struct Page's and store it in 'pages'.
	// The kernel uses this array to keep track of physical pages: for
	// each physical page, there is a corresponding struct Page in this
	// array.  'npages' is the number of physical pages in memory.
	// Your code goes here:
    pages = boot_alloc(npages*sizeof(* pages));

	//////////////////////////////////////////////////////////////////////
	// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
	// LAB 3: Your code here.

    envs = boot_alloc(NENV * sizeof(* envs));

	//////////////////////////////////////////////////////////////////////
	// Now that we've allocated the initial kernel data structures, we set
	// up the list of free physical pages. Once we've done so, all further
	// memory management will go through the page_* functions. In
	// particular, we can now map memory using boot_map_region
	// or page_insert
	page_init();

	check_page_free_list(1);
	check_page_alloc();
	check_page();

	//////////////////////////////////////////////////////////////////////
	// Now we set up virtual memory

	//////////////////////////////////////////////////////////////////////
	// Map 'pages' read-only by the user at linear address UPAGES
	// Permissions:
	//    - the new image at UPAGES -- kernel R, user R
	//      (ie. perm = PTE_U | PTE_P)
	//    - pages itself -- kernel RW, user NONE
	// Your code goes here:
    boot_map_region( kern_pgdir,  (uintptr_t) UPAGES, npages*(sizeof(* pages)),
                     PADDR(pages), PTE_U | PTE_P);

    boot_map_region( kern_pgdir, (uintptr_t) pages, npages*(sizeof(* pages)),
                     PADDR(pages), PTE_W | PTE_P);

    
	//////////////////////////////////////////////////////////////////////
	// Map the 'envs' array read-only by the user at linear address UENVS
	// (ie. perm = PTE_U | PTE_P).
	// Permissions:
	//    - the new image at UENVS  -- kernel R, user R
	//    - envs itself -- kernel RW, user NONE
	// LAB 3: Your code here.

    boot_map_region( kern_pgdir,  (uintptr_t) UENVS, npages*(sizeof(* envs)),
                     PADDR(envs), PTE_U | PTE_P);

    boot_map_region( kern_pgdir, (uintptr_t) envs, npages*(sizeof(* envs)),
                     PADDR(envs), PTE_W | PTE_P);

	//////////////////////////////////////////////////////////////////////
	// Use the physical memory that 'bootstack' refers to as the kernel
	// stack.  The kernel stack grows down from virtual address KSTACKTOP.
	// We consider the entire range from [KSTACKTOP-PTSIZE, KSTACKTOP)
	// to be the kernel stack, but break this into two pieces:
	//     * [KSTACKTOP-KSTKSIZE, KSTACKTOP) -- backed by physical memory
	//     * [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) -- not backed; so if
	//       the kernel overflows its stack, it will fault rather than
	//       overwrite memory.  Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	// Your code goes here:

    boot_map_region( kern_pgdir, KSTACKTOP-KSTKSIZE, KSTKSIZE,
                     PADDR(bootstack), PTE_W | PTE_P );

	//////////////////////////////////////////////////////////////////////
	// Map all of physical memory at KERNBASE.
	// Ie.  the VA range [KERNBASE, 2^32) should map to
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	// Your code goes here:
    
    boot_map_region( kern_pgdir, (uintptr_t) KERNBASE, 0xFFFFFFFF, 0,
                     PTE_W | PTE_P);

	// Initialize the SMP-related parts of the memory map
	mem_init_mp();

	// Check that the initial page directory has been set up correctly.
	check_kern_pgdir();

	// Switch from the minimal entry page directory to the full kern_pgdir
	// page table we just created.	Our instruction pointer should be
	// somewhere between KERNBASE and KERNBASE+4MB right now, which is
	// mapped the same way by both page tables.
	//
	// If the machine reboots at this point, you've probably set up your
	// kern_pgdir wrong.
	lcr3(PADDR(kern_pgdir));

	check_page_free_list(0);

	// entry.S set the really important flags in cr0 (including enabling
	// paging).  Here we configure the rest of the flags that we care about.
	cr0 = rcr0();
	cr0 |= CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_MP;
	cr0 &= ~(CR0_TS|CR0_EM);
	lcr0(cr0);

	// Some more checks, only possible after kern_pgdir is installed.
	check_page_installed_pgdir();
}
Ejemplo n.º 19
0
static int libexec_alloc_vm_ondemand(struct exec_info *execi,
	off_t vaddr, size_t len)
{
	boot_alloc(execi, vaddr, len, 0);
	return OK;
}
Ejemplo n.º 20
0
//
// 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!
	//page_free_list = NULL;
	/*
	size_t i;
	for (i = 0; i < npages; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
	*/

	/*	
	**	preserve IO hole + kern_pgdir + pages:
	**	[IOPHYSMEM, EXTPHYSMEM) + 
	**	[EXTPHYSMEM, EXTPHYSMEM + PGSIZE) + 
	**	[EXTPHYSMEM + PGSIZE, EXTPHYSMEM + PGSIZE + npages * sizeof(struct pageInfo))
	*/

	size_t lower_idx = PGNUM(IOPHYSMEM);
	//volatile size_t upper_num = PGNUM( (ROUNDUP( EXTPHYSMEM + PGSIZE + npages * sizeof(struct PageInfo), PGSIZE )));
	size_t upper_idx = PGNUM(PADDR(boot_alloc(0)));	
	size_t mpentry_idx = PGNUM(MPENTRY_PADDR);
	assert(lower_idx < npages);
	assert(upper_idx < npages);
	size_t i;
	for(i = 0; i < npages; i++){
		//pages[i].pp_ref = 0;
		
		/* preserve the real-mode IDT and BIOS structures */
		if(i == 0) { continue; }
		if(i == mpentry_idx) { continue; }
		if(i >= lower_idx && i < upper_idx) { continue; }

		/* insert into page_free_list */
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
}
Ejemplo n.º 21
0
static int libexec_alloc_vm_prealloc(struct exec_info *execi,
	off_t vaddr, size_t len)
{
	boot_alloc(execi, vaddr, len, MF_PREALLOC);
	return OK;
}
Ejemplo n.º 22
0
page_list_t* colored_page_free_list = NULL;
spinlock_t colored_page_free_list_lock = SPINLOCK_INITIALIZER_IRQSAVE;

/*
 * Initialize the memory free lists.
 * After this point, ONLY use the functions below
 * to allocate and deallocate physical memory via the 
 * page_free_lists. 
 */
void page_alloc_init(struct multiboot_info *mbi)
{
	init_once_racy(return);

	size_t list_size = llc_cache->num_colors*sizeof(page_list_t);;
	page_list_t* lists = (page_list_t*)boot_alloc(list_size, PGSIZE);

	size_t num_colors = llc_cache->num_colors;
	for (size_t i = 0; i < num_colors; i++)
		BSD_LIST_INIT(&lists[i]);
	
	uintptr_t first_free_page = ROUNDUP(boot_freemem, PGSIZE);
	uintptr_t first_invalid_page = LA2PPN(boot_freelimit);
	assert(first_invalid_page == max_nr_pages);

	// mark kernel pages as in-use
	for (uintptr_t page = 0; page < first_free_page; page++)
		page_setref(&pages[page], 1);
	
	// append other pages to the free lists
	for (uintptr_t page = first_free_page; page < first_invalid_page; page++)
Ejemplo n.º 23
0
// Set up a two-level page table:
//    kern_pgdir is its linear (virtual) address of the root
// Then turn on paging.  Then effectively turn off segmentation.
// (i.e., the segment base addrs are set to zero).
//
// This function only sets up the kernel part of the address space
// (ie. addresses >= UTOP).  The user part of the address space
// will be setup later.
//
// From UTOP to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read or write.
void
mem_init(void)
{
	uint32_t cr0;
	size_t n;

	// Ensure user & kernel struct Pages agree.
	static_assert(sizeof(struct Page) == sizeof(struct UserPage));

	// Find out how much memory the machine has (npages & npages_basemem).
	i386_detect_memory();

	// Remove this line when you're ready to test this function.
	//panic("mem_init: This function is not finished\n");

	//////////////////////////////////////////////////////////////////////
	// create initial page directory.
	kern_pgdir = (pde_t *) boot_alloc(PGSIZE);
	memset(kern_pgdir, 0, PGSIZE);

	//////////////////////////////////////////////////////////////////////
	// Recursively insert PD in itself as a page table, to form
	// a virtual page table at virtual address UVPT.
	// (For now, you don't have understand the greater purpose of the
	// following line.)
	// Permissions: kernel R, user R
	kern_pgdir[PDX(UVPT)] = PADDR(kern_pgdir) | PTE_U | PTE_P;

	//////////////////////////////////////////////////////////////////////
	// Allocate an array of npages 'struct Page's and store it in 'pages'.
	// The kernel uses this array to keep track of physical pages: for
	// each physical page, there is a corresponding struct Page in this
	// array.  'npages' is the number of physical pages in memory.
	pages = (Page *) boot_alloc(npages * sizeof(struct Page));


	//////////////////////////////////////////////////////////////////////
	// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
	// LAB 3: Your code here.
	envs = (Env *) boot_alloc(NENV * sizeof(struct Env));

	//////////////////////////////////////////////////////////////////////
	// Now that we've allocated the initial kernel data structures, we set
	// up the list of free physical pages. Once we've done so, all further
	// memory management will go through the page_* functions. In
	// particular, we can now map memory using page_map_segment
	// or page_insert
	page_init();

	check_page_free_list(true);
	check_page_alloc();
	check_page();

	//////////////////////////////////////////////////////////////////////
	// Now we set up virtual memory

	//////////////////////////////////////////////////////////////////////
	// Use the physical memory that 'entry_stack' refers to as the kernel
	// stack.  The kernel stack grows down from virtual address KSTACKTOP.
	// We consider the entire range from [KSTACKTOP-PTSIZE, KSTACKTOP)
	// to be the kernel stack, but break this into two pieces:
	//     * [KSTACKTOP-KSTKSIZE, KSTACKTOP) -- backed by physical memory
	//     * [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) -- not backed; so if
	//       the kernel overflows its stack, it will fault rather than
	//       overwrite memory.  Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	Page *pp = pa2page((physaddr_t)entry_stack-KERNBASE);
	for (uintptr_t ptr = KSTACKTOP-KSTKSIZE; ptr < KSTACKTOP; ptr += PGSIZE) {
		if (page_insert(kern_pgdir, pp, ptr, PTE_W | PTE_P) < 0)
			panic("Couldn't create page table entries for stack.\n");
		pp++;
	}

	//////////////////////////////////////////////////////////////////////
	// Map all of physical memory at KERNBASE.
	// Ie.  the VA range [KERNBASE, 2^32) should map to
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	page_map_segment(kern_pgdir, KERNBASE, 0xFFFFFFFF-KERNBASE, 0x0, PTE_W | PTE_P);
     
	//print_page_table(kern_pgdir, false, false);

	//////////////////////////////////////////////////////////////////////
	// Map the 'envs' array read-only by the user at linear address UENVS.
	// Permissions: kernel R, user R
	// (That's the UENVS version; 'envs' itself is kernel RW, user NONE.)
	// LAB 3: Your code here.
	page_map_segment(kern_pgdir, (uintptr_t) UENVS, ROUNDUP(NENV*sizeof(struct Env), PGSIZE), PADDR(envs), PTE_U | PTE_P);

	//////////////////////////////////////////////////////////////////////
	// Map 'pages' read-only by the user at linear address UPAGES.
	// Permissions: kernel R, user R
	// (That's the UPAGES version; 'pages' itself is kernel RW, user NONE.)
	// LAB 3: Your code here.
	page_map_segment(kern_pgdir, UPAGES, ROUNDUP(npages*sizeof(struct Page), PGSIZE), PADDR(pages), PTE_U | PTE_P);

	// Check that the initial page directory has been set up correctly.
	check_kern_pgdir();

	// Switch from the minimal entry page directory to the full kern_pgdir
	// page table we just created.	Our instruction pointer should be
	// somewhere between KERNBASE and KERNBASE+4MB right now, which is
	// mapped the same way by both page tables.
	//
	// If the machine reboots at this point, you've probably set up your
	// kern_pgdir wrong.
	lcr3(PADDR(kern_pgdir));

        // entry.S set the really important flags in cr0 (including enabling
        // paging).  Here we configure the rest of the flags we need.
	cr0 = rcr0();
	cr0 |= CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_MP;
	cr0 &= ~(CR0_TS|CR0_EM);
	lcr0(cr0);

	// Some more checks, only possible after kern_pgdir is installed.
	check_page_installed_pgdir();
}
Ejemplo n.º 24
0
//
// 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!

	// Remember: Pages allocated at boot time using pmap.c's
	// boot_alloc do not have valid reference count fields.
	// So don't add them to free list, but don't bother setting
	// pp_ref either.

	uint32_t i = 0;
	page_free_list = NULL; // Start w/ empty free list

	// Mark physical page 0 as in use 
	pages[0].pp_ref = 1;
	i += 1;

	// Mark rest of base memory free
	for (; i < npages_basemem; i++) {
		// Don't add page at MPENTRY_PADDR which has AP bootstrap code
		if (i == MPENTRY_PADDR/PGSIZE) {
			continue;
		}
		
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}

	// Base memory must end at I/O hole
	assert(npages_basemem * PGSIZE == IOPHYSMEM);

	// Mark I/O hole as *used* as well
	for (; i < EXTPHYSMEM/PGSIZE; i++) {
		pages[i].pp_ref = 1;
	}

	// Mark initial extended memory w/ kernel & kernal datastructures 
	// as used.
	for (; i < PADDR(boot_alloc(0))/PGSIZE ; i++) {
		pages[i].pp_ref = 1;
	} 

	// Mark all other physical pages as free
	for (; i < npages; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}
}
Ejemplo n.º 25
0
//
// 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

	struct PageInfo *temp,*temp1,*temp2,*temp3, *mpentry;
	page_free_list = pages;
	// 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!

	size_t i, range;
	for (i = 0; i < npages-1; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = &pages[i+1];
	}
	pages[npages-1].pp_ref = 0;
	pages[npages-1].pp_link = NULL;
	page_free_list = pages;
	
	// marking page 0 as busy. case 1
	page_free_list->pp_ref = 1;
	temp = page_free_list;
	page_free_list = temp->pp_link;
	temp->pp_link=NULL;

	//marking MPENTRY_PADDR as busy page. This page is present in basemem pages

	mpentry = pa2page(MPENTRY_PADDR);
	(mpentry-1)->pp_link = mpentry->pp_link;
	mpentry->pp_link = NULL;
	mpentry->pp_ref = 1;

	//case 2

	temp = page_free_list + npages_basemem-2;
	//temp is last free block in base memory
	temp1 = temp->pp_link;


	//case 3
	range = (EXTPHYSMEM - IOPHYSMEM) / (PGSIZE);
	for(i=0;i<range-1;i++)
	{
		temp2=temp1->pp_link;
		temp1->pp_link = NULL;
		temp1->pp_ref = 1;
		temp1 = temp2;
	}
	temp2 = temp1->pp_link;
	temp1->pp_link = NULL;
	temp1->pp_ref = 1;
	temp1 = temp2;
	
	//case 4
	range = ((uint32_t) boot_alloc(0) - (uint32_t)KADDR(EXTPHYSMEM))/ (PGSIZE);
	for(i=0;i<range-1;i++)
	{
		temp2=temp1->pp_link;
		temp1->pp_link = NULL;
		temp1->pp_ref = 1;
		temp1 = temp2;
	}
	temp2 = temp1->pp_link;
	temp1->pp_link = NULL;
	temp1->pp_ref = 1;
	temp1 = temp2;
	temp->pp_link = temp1;

}
Ejemplo n.º 26
0
void up_allocate_heap(void **heap_start, size_t *heap_size)
{
    void *boot_freemem = boot_alloc(0, sizeof(int));
    *heap_start = boot_freemem;
    *heap_size = KERNBASE + kmem_size - (uint32_t)boot_freemem;
}
Ejemplo n.º 27
0
Archivo: pmap.c Proyecto: yahu/JOS
//
// 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)
{

    // 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!

    size_t s=0,e=0;
    int i;
    page_free_list=0;
    //cprintf("pages=%x\n",(uint32_t )pages);
    //  1) correspond to 1) above ,set the first element 's ret to 1;
    pages[0].pp_ref=1;

    //  2) correspond to 2) above
    //cprintf("npages=%u\n",npages);
    s = PGSIZE / PGSIZE;
    e = MPENTRY_PADDR /PGSIZE-1;
    _page_init(s,e);

    // LAB 4:
	// Change your code to mark the physical page at MPENTRY_PADDR
	// as in use
    pages[MPENTRY_PADDR / PGSIZE].pp_ref=1;


    s = MPENTRY_PADDR / PGSIZE + 1;
    e = npages_basemem-1;

    _page_init(s,e);

    //  3) correspond to 3) above
    s = IOPHYSMEM / PGSIZE;
    e = EXTPHYSMEM / PGSIZE - 1;
    for(i=s; i<=e; i++)
        pages[i].pp_ref=1;

    //  4) correspond to 4) above,the low 4MB memory has been used  to map
    //  virtual address [KERNBASE,KERNBASE+0X400000] by entry.s, kernal and some
    //  important struct such as pages and kern_pgdir is in this region.On the other
    //  side, the rest of free space of we can't get unitl syetem runing ,so we  mark
    //  space [0x100000,0x400000] is not free ,just skip it
    s=EXTPHYSMEM / PGSIZE;
    e=((int)boot_alloc(0)-KERNBASE) / PGSIZE - 1;
    // cprintf("1.boot_alloc(0)=%x\n",boot_alloc(0));
    for(i=s; i<=e; i++)
        pages[i].pp_ref=1;

    //  5) the part no used above
    s=( (int)boot_alloc(0)-KERNBASE) / PGSIZE ;
    e=npages-1;
    //cprintf("2.boot_alloc(0)=%x\n",boot_alloc(0));
    _page_init(s,e);

}
Ejemplo n.º 28
0
//
// 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?

	
    pages[0].pp_ref = 1;
    pages[1].pp_link = page_free_list;
	size_t i;
	for (i = 1; i < MPENTRY_PADDR/PGSIZE; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}

	pages[i].pp_ref = 1;
	pages[1].pp_link = NULL;

	for (i = MPENTRY_PADDR/PGSIZE+1; i < npages_basemem; i++) {
		pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
	}


	for( i=IOPHYSMEM/PGSIZE; i < EXTPHYSMEM/PGSIZE; i++) {
		pages[i].pp_ref = 1;
		pages[i].pp_link = 0;
	}

    for( i; i < PADDR((void *) KERNBASE)/PGSIZE; i++) {
      pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
    }

    uint32_t free_start = ((uint32_t) PADDR(boot_alloc(0)))/PGSIZE;
    for( i; i < free_start; i++) {
        pages[i].pp_ref = 1;
		pages[i].pp_link = 0;
    }

    for(i; i < npages; i++) {
        pages[i].pp_ref = 0;
		pages[i].pp_link = page_free_list;
		page_free_list = &pages[i];
    }

}
Ejemplo n.º 29
0
Archivo: pmap.c Proyecto: ajsbu/cse506
// Set up a four-level page table:
//    boot_pml4e is its linear (virtual) address of the root
//
// This function only sets up the kernel part of the address space
// (ie. addresses >= UTOP).  The user part of the address space
// will be setup later.
//
// From UTOP to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read or write.
void
x64_vm_init(void)
{
	pml4e_t* pml4e;
	uint32_t cr0;
	int i;
	size_t n;
	int r;
	struct Env *env;
	i386_detect_memory();
	//panic("i386_vm_init: This function is not finished\n");
	//////////////////////////////////////////////////////////////////////
	// create initial page directory.
	///panic("x64_vm_init: this function is not finished\n");
	pml4e = boot_alloc(PGSIZE);
	memset(pml4e, 0, PGSIZE);
	boot_pml4e = pml4e;
	boot_cr3 = PADDR(pml4e);

	//////////////////////////////////////////////////////////////////////
	// Allocate an array of npage 'struct Page's and store it in 'pages'.
	// The kernel uses this array to keep track of physical pages: for
	// each physical page, there is a corresponding struct Page in this
	// array.  'npage' is the number of physical pages in memory.
	// User-level programs will get read-only access to the array as well.
	// Your code goes here:
	pages = boot_alloc(npages * sizeof(struct Page));
	//////////////////////////////////////////////////////////////////////
	// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
	// LAB 3: Your code here.
        envs = boot_alloc(NENV * sizeof(struct Env));
	//////////////////////////////////////////////////////////////////////
	// Now that we've allocated the initial kernel data structures, we set
	// up the list of free physical pages. Once we've done so, all further
	// memory management will go through the page_* functions. In
	// particular, we can now map memory using boot_map_segment or page_insert
	page_init();

	check_page_free_list(1);
	check_page_alloc();
	page_check();

	//////////////////////////////////////////////////////////////////////
	// Now we set up virtual memory 
	//////////////////////////////////////////////////////////////////////
	// Map 'pages' read-only by the user at linear address UPAGES
	// Permissions:
	//    - the new image at UPAGES -- kernel R, user R
	//      (ie. perm = PTE_U | PTE_P)
	//    - pages itself -- kernel RW, user NONE
	// Your code goes here:

	//////////////////////////////////////////////////////////////////////
	// Map the 'envs' array read-only by the user at linear address UENVS
	// (ie. perm = PTE_U | PTE_P).
	// Permissions:
	//    - the new image at UENVS  -- kernel R, user R
	//    - envs itself -- kernel RW, user NONE
	// LAB 3: Your code here.

	boot_map_segment(boot_pml4e, UPAGES, ROUNDUP(npages*sizeof(struct Page), PGSIZE), PADDR(pages), PTE_U | PTE_P); 
	boot_map_segment(boot_pml4e, (uintptr_t)pages, ROUNDUP(npages *sizeof(struct Page), PGSIZE), PADDR(pages), PTE_P | PTE_W);
	
        boot_map_segment(boot_pml4e, UENVS, ROUNDUP(NENV*sizeof(struct Env), PGSIZE), PADDR(envs), PTE_U | PTE_P); 
        boot_map_segment(boot_pml4e, (uintptr_t)envs, ROUNDUP(NENV *sizeof(struct Env), PGSIZE), PADDR(envs), PTE_P | PTE_W);
        
	//////////////////////////////////////////////////////////////////////
	// Use the physical memory that 'bootstack' refers to as the kernel
	// stack.  The kernel stack grows down from virtual address KSTACKTOP.
	// We consider the entire range from [KSTACKTOP-PTSIZE, KSTACKTOP) 
	// to be the kernel stack, but break this into two pieces:
	//     * [KSTACKTOP-KSTKSIZE, KSTACKTOP) -- backed by physical memory
	//     * [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) -- not backed; so if
	//       the kernel overflows its stack, it will fault rather than
	//       overwrite memory.  Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	// Your code goes here:
	boot_map_segment(boot_pml4e, KSTACKTOP-KSTKSIZE, KSTKSIZE, PADDR(bootstack), PTE_P | PTE_W); 
	
	///////////////////////////////////////////////////////////////////////
	// Map all of physical memory at KERNBASE. 
	// Ie.  the VA range [KERNBASE, 2^32) should map to
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	// Your code goes here: 
	boot_map_segment(boot_pml4e, KERNBASE,  ~(uint32_t)0 - KERNBASE + 1, 0, PTE_P | PTE_W);

	// Check that the initial page directory has been set up correctly.
	// Initialize the SMP-related parts of the memory map
	mem_init_mp();

	check_boot_pml4e(boot_pml4e);

	//////////////////////////////////////////////////////////////////////
	// Permissions: kernel RW, user NONE
	pdpe_t *pdpe = KADDR(PTE_ADDR(pml4e[0]));
	pde_t *pgdir = KADDR(PTE_ADDR(pdpe[3]));
	lcr3(boot_cr3);

	check_page_free_list(0);
}