bucketarray = (void *) uvm_pageboot_alloc((bucketcount * sizeof(struct pgflbucket)) + (pagecount * sizeof(struct vm_page))); pagearray = (struct vm_page *)(bucketarray + bucketcount);  for (lcv = 0; lcv < VM_NFREELIST; lcv++) { uvm.page_free[lcv].pgfl_buckets = (bucketarray + (lcv * uvmexp.ncolors)); uvm_page_init_buckets(&uvm.page_free[lcv]); }
pagearray = (vm_page_t)uvm_pageboot_alloc(pagecount * sizeof(struct vm_page));
uvm_page_init(kvm_startp, kvm_endp)	vaddr_t *kvm_startp, *kvm_endp;{	vsize_t freepages, pagecount, bucketcount, n;	struct pgflbucket *bucketarray;	struct vm_page *pagearray;	int lcv, i;	paddr_t paddr;	/*	 * init the page queues and page queue locks, except the free	 * list; we allocate that later (with the initial vm_page	 * structures).	 */	TAILQ_INIT(&uvm.page_active);	TAILQ_INIT(&uvm.page_inactive);	simple_lock_init(&uvm.pageqlock);	simple_lock_init(&uvm.fpageqlock);	/*	 * init the <obj,offset> => <page> hash table.  for now	 * we just have one bucket (the bootstrap bucket).  later on we	 * will allocate new buckets as we dynamically resize the hash table.	 */	uvm.page_nhash = 1;			/* 1 bucket */	uvm.page_hashmask = 0;			/* mask for hash function */	uvm.page_hash = &uvm_bootbucket;	/* install bootstrap bucket */	TAILQ_INIT(uvm.page_hash);		/* init hash table */	simple_lock_init(&uvm.hashlock);	/* init hash table lock */	/*	 * allocate vm_page structures.	 */	/*	 * sanity check:	 * before calling this function the MD code is expected to register	 * some free RAM with the uvm_page_physload() function.   our job	 * now is to allocate vm_page structures for this memory.	 */	if (vm_nphysseg == 0)		panic("uvm_page_bootstrap: no memory pre-allocated");	/*	 * first calculate the number of free pages...	 *	 * note that we use start/end rather than avail_start/avail_end.	 * this allows us to allocate extra vm_page structures in case we	 * want to return some memory to the pool after booting.	 */	freepages = 0;	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++)		freepages += (vm_physmem[lcv].end - vm_physmem[lcv].start);	/*	 * Let MD code initialize the number of colors, or default	 * to 1 color if MD code doesn't care.	 */	if (uvmexp.ncolors == 0)		uvmexp.ncolors = 1;	uvmexp.colormask = uvmexp.ncolors - 1;	/*	 * we now know we have (PAGE_SIZE * freepages) bytes of memory we can	 * use.   for each page of memory we use we need a vm_page structure.	 * thus, the total number of pages we can use is the total size of	 * the memory divided by the PAGE_SIZE plus the size of the vm_page	 * structure.   we add one to freepages as a fudge factor to avoid	 * truncation errors (since we can only allocate in terms of whole	 * pages).	 */	bucketcount = uvmexp.ncolors * VM_NFREELIST;	pagecount = ((freepages + 1) << PAGE_SHIFT) /	    (PAGE_SIZE + sizeof(struct vm_page));	bucketarray = (void *) uvm_pageboot_alloc((bucketcount *	    sizeof(struct pgflbucket)) + (pagecount *	    sizeof(struct vm_page)));	pagearray = (struct vm_page *)(bucketarray + bucketcount);	for (lcv = 0; lcv < VM_NFREELIST; lcv++) {		uvm.page_free[lcv].pgfl_buckets =		    (bucketarray + (lcv * uvmexp.ncolors));		uvm_page_init_buckets(&uvm.page_free[lcv]);	}	memset(pagearray, 0, pagecount * sizeof(struct vm_page));	/*	 * init the vm_page structures and put them in the correct place.	 */	for (lcv = 0 ; lcv < vm_nphysseg ; lcv++) {		n = vm_physmem[lcv].end - vm_physmem[lcv].start;		if (n > pagecount) {			printf("uvm_page_init: lost %ld page(s) in init\n",			    (long)(n - pagecount));			panic("uvm_page_init");  /* XXXCDC: shouldn't happen? */			/* n = pagecount; */		}		/* set up page array pointers */		vm_physmem[lcv].pgs = pagearray;		pagearray += n;		pagecount -= n;		vm_physmem[lcv].lastpg = vm_physmem[lcv].pgs + (n - 1);		/* init and free vm_pages (we've already zeroed them) */		paddr = ptoa(vm_physmem[lcv].start);		for (i = 0 ; i < n ; i++, paddr += PAGE_SIZE) {			vm_physmem[lcv].pgs[i].phys_addr = paddr;#ifdef __HAVE_VM_PAGE_MD			VM_MDPAGE_INIT(&vm_physmem[lcv].pgs[i]);#endif			if (atop(paddr) >= vm_physmem[lcv].avail_start &&			    atop(paddr) <= vm_physmem[lcv].avail_end) {				uvmexp.npages++;				/* add page to free pool */				uvm_pagefree(&vm_physmem[lcv].pgs[i]);			}		}	}	/*	 * pass up the values of virtual_space_start and	 * virtual_space_end (obtained by uvm_pageboot_alloc) to the upper	 * layers of the VM.	 */	*kvm_startp = round_page(virtual_space_start);	*kvm_endp = trunc_page(virtual_space_end);	/*	 * init locks for kernel threads	 */	simple_lock_init(&uvm.pagedaemon_lock);	simple_lock_init(&uvm.aiodoned_lock);	/*	 * init reserve thresholds	 * XXXCDC - values may need adjusting	 */	uvmexp.reserve_pagedaemon = 4;	uvmexp.reserve_kernel = 6;	uvmexp.anonminpct = 10;	uvmexp.vnodeminpct = 10;	uvmexp.vtextminpct = 5;	uvmexp.anonmin = uvmexp.anonminpct * 256 / 100;	uvmexp.vnodemin = uvmexp.vnodeminpct * 256 / 100;	uvmexp.vtextmin = uvmexp.vtextminpct * 256 / 100;  	/*	 * determine if we should zero pages in the idle loop.	 */	uvm.page_idle_zero = vm_page_zero_enable;	/*	 * done!	 */	uvm.page_init_done = TRUE;}