-/*
+ /*
* Physical memory allocation
* Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
* Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
- * $Revision: 1.1 $
+ * $Revision: 1.13 $
*
* This is free software. You are permitted to use,
* redistribute, and modify it as specified in the file "COPYING".
#include <geekos/string.h>
#include <geekos/mem.h>
-#include <geekos/vmm_sizes.h>
#include <geekos/serial.h>
+#include <geekos/debug.h>
+
/* ----------------------------------------------------------------------
* Global data
*/
struct Page* g_pageList;
+#ifdef RAMDISK_BOOT
+ulong_t g_ramdiskImage;
+ulong_t s_ramdiskSize;
+#endif
+
/*
* Number of pages currently available on the freelist.
*/
uint_t g_freePageCount = 0;
+
+
+/*
+ * the disgusting way to get at the memory assigned to a VM
+ */
+extern ulong_t vm_range_start;
+extern ulong_t vm_range_end;
+extern ulong_t guest_kernel_start;
+extern ulong_t guest_kernel_end;
+
+
+
/* ----------------------------------------------------------------------
* Private data and functions
* ---------------------------------------------------------------------- */
*/
int unsigned s_numPages;
+
+
+
/*
* Add a range of pages to the inventory of physical memory.
*/
{
ulong_t addr;
- //Print("Start: %u, End: %u\n", (unsigned int)start, (unsigned int)end);
+ PrintBoth("Start: %u (0x%x), End: %u(0x%x) (Type=0x%.4x)\n", (unsigned int)start, start, (unsigned int)end, end, flags);
KASSERT(Is_Page_Multiple(start));
KASSERT(Is_Page_Multiple(end));
void Init_Mem(struct Boot_Info* bootInfo)
{
ulong_t numPages = bootInfo->memSizeKB >> 2;
- // ulong_t endOfMem = numPages * PAGE_SIZE;
+ ulong_t endOfMem = numPages * PAGE_SIZE;
unsigned numPageListBytes = sizeof(struct Page) * numPages;
ulong_t pageListAddr;
ulong_t pageListEnd;
ulong_t kernEnd;
+ ulong_t heapAddr;
+ ulong_t heapEnd;
+ ulong_t vmmMemEnd;
+
+ /*Zheng 08/03/2008*/
+#ifdef RAMDISK_BOOT
+ g_ramdiskImage = bootInfo->ramdisk_image;
+ s_ramdiskSize = bootInfo->ramdisk_size;
+ ulong_t initrdAddr;
+ ulong_t initrdEnd;
+#endif
+
KASSERT(bootInfo->memSizeKB > 0);
- if (bootInfo->memSizeKB != TOP_OF_MEM/1024) {
- PrintBoth("Kernel compiled for %d KB machine, but machine claims %d KB\n",TOP_OF_MEM/1024,bootInfo->memSizeKB);
- if (bootInfo->memSizeKB < TOP_OF_MEM/1024) {
- PrintBoth("Kernel compiled for more memory than machine has. Panicking\n");
- KASSERT(0);
- }
- }
-
- if (0) {
- // if there is not enough memory between START_OF_VM+VM_SIZE and TOP_OF_MEM
- // to store the kernel and kernel structures, we need to panick
- PrintBoth("Kernel is not compiled with sufficient memory above the VM to support the memory\n");
- KASSERT(0);
- }
-
-
- bootInfo->memSizeKB = TOP_OF_MEM / 1024;
/*
* Before we do anything, switch from setup.asm's temporary GDT
*/
Init_GDT();
- /*
- * We'll put the list of Page objects right after the end
- * of the kernel, and mark it as "kernel". This will bootstrap
- * us sufficiently that we can start allocating pages and
- * keeping track of them.
+
+ PrintBoth("Total Memory Size: %u MBytes\n", bootInfo->memSizeKB/1024);
+ PrintBoth("Page List (at 0x%x) Size: %u bytes\n", &s_freeList, numPageListBytes);
+
+
+ /* Memory Layout:
+ * bios area (1 page reserved)
+ * kernel_thread_obj (1 page)
+ * kernel_stack (1 page)
+ * available space
+ * available space
+ * ISA_HOLE_START - ISA_HOLE_END: hardware
+ * EXTENDED_MEMORY:
+ * start - end: kernel
+ * VM Guest (variable pages)
+ * Heap (512 Pages)
+ * Page List (variable pages)
+ * Available Memory for VMM (4096 pages)
+ * Ramdisk //Zheng 08/03/2008
+ * VM Memory (everything else)
*/
- // JRL: This is stupid...
- // with large mem sizes the page list overruns into the ISA
- // hole. By blind luck this causes an unrelated assertion failure, otherwise
- // I might never have caught it...
- // We fix it by moving the page list after the kernel heap...
- // For now we'll make our own stupid assumption that the mem size
- // is large enough to accomodate the list in high mem.
+ //kernEnd = Round_Up_To_Page((ulong_t)&end);
+ kernEnd = (ulong_t)&end;
- PrintBoth("Total Memory Size: %u MBytes\n", bootInfo->memSizeKB/1024);
- PrintBoth("VM Start: %x\n",START_OF_VM);
- PrintBoth("VM End: %x\n",START_OF_VM+VM_SIZE-1);
-
+ PrintBoth("Kernel End=%lx\n", kernEnd);
- PrintBoth("Page struct size: %u bytes\n", sizeof(struct Page));
- PrintBoth("Page List Size: %u bytes\n", numPageListBytes);
-
- //pageListAddr = Round_Up_To_Page((ulong_t) &end);
- //pageListAddr = Round_Up_To_Page(HIGHMEM_START + KERNEL_HEAP_SIZE);
+ /* ************************************************************************************** */
+ /* If we have dynamic loading of the guest kernel, we should put the relocation code here */
+ /* ************************************************************************************** */
- // Note that this is now moved to be just above the kernel heap
- // see defs.h for layout
- pageListAddr=Round_Up_To_Page(KERNEL_PAGELIST);
-
+ kernEnd = Round_Up_To_Page(kernEnd);
+ heapAddr = kernEnd;
+ heapEnd = Round_Up_To_Page(heapAddr + KERNEL_HEAP_SIZE);
+ pageListAddr = heapEnd;
pageListEnd = Round_Up_To_Page(pageListAddr + numPageListBytes);
-
+ /* Global variables */
+ // These must be set before we can call Add_Page_Range..
g_pageList = (struct Page*) pageListAddr;
- // kernEnd = Round_Up_To_Page(pageListAddr + numPageListBytes);
- //
- // PAD - Note: I am changing this so that everything through the end of
- // the VM boot package (bioses/vmxassist) is off limits
- //kernEnd = Round_Up_To_Page((ulong_t) &end);
- kernEnd = Round_Up_To_Page(VM_BOOT_PACKAGE_END);
s_numPages = numPages;
+ /* ** */
+ vmmMemEnd = Round_Up_To_Page(pageListEnd + VMM_AVAIL_MEM_SIZE);
- PrintBoth("Pagelist addr: %p\n", g_pageList);
- PrintBoth("index: %p\n", &g_pageList[3]);
- PrintBoth("direct offset: %p\n", g_pageList + (sizeof(struct Page) * 2));
- PrintBoth("Kernel Size=%lx\n", (kernEnd - KERNEL_START_ADDR));
- PrintBoth("Kernel Start=%x\n", KERNEL_START_ADDR);
- PrintBoth("Kernel End=%lx\n", kernEnd);
- PrintBoth("VM Boot Package Start=%x\n", VM_BOOT_PACKAGE_START);
- PrintBoth("VM Boot Package End=%x\n", VM_BOOT_PACKAGE_END);
-
+#ifdef RAMDISK_BOOT
/*
- * The initial kernel thread and its stack are placed
- * just beyond the ISA hole.
+ * Zheng 08/03/2008
+ * copy the ramdisk to this area
*/
- // This is no longer true
- // KASSERT(ISA_HOLE_END == KERN_THREAD_OBJ);
- // instead,
- //KASSERT(KERN_THREAD_OBJ==(START_OF_VM+VM_SIZE));
- //KASSERT(KERN_STACK == KERN_THREAD_OBJ + PAGE_SIZE);
+ initrdAddr = vmmMemEnd;
+ initrdEnd = Round_Up_To_Page(initrdAddr + s_ramdiskSize);
+ PrintBoth("mem.c(%d) Move ramdisk(%dB) from %x to %x", __LINE__, s_ramdiskSize, g_ramdiskImage, initrdAddr);
+ memcpy((ulong_t *)initrdAddr, (ulong_t *)g_ramdiskImage, s_ramdiskSize);
+ PrintBoth(" done\n");
+ PrintBoth("mem.c(%d) Set 0 to unused bytes in the last ramdisk page from %x to %x", __LINE__, initrdAddr+s_ramdiskSize, initrdEnd);
+ memset((ulong_t *)initrdAddr+s_ramdiskSize, 0, initrdEnd-(initrdAddr+s_ramdiskSize));
+ PrintBoth(" done\n");
/*
- * Memory looks like this:
- * 0 - start: available (might want to preserve BIOS data area)
- * start - end: kernel
- * end - ISA_HOLE_START: available
- * ISA_HOLE_START - ISA_HOLE_END: used by hardware (and ROM BIOS?)
- * ISA_HOLE_END - HIGHMEM_START: used by initial kernel thread
- * HIGHMEM_START - end of memory: available
- * (the kernel heap is located at HIGHMEM_START; any unused memory
- * beyond that is added to the freelist)
+ * Zheng 08/03/2008
*/
-
- // The VM region... 0 .. VM size is out of bounds
- KASSERT(START_OF_VM==0);
- Add_Page_Range(START_OF_VM, START_OF_VM+VM_SIZE, PAGE_VM);
- // The kernel is still in low memory at this point, in the VM region
- // Thus we will mark it as kernel use
- // Add_Page_Range(KERNEL_START_ADDR, kernEnd, PAGE_KERN);
+ vm_range_start = initrdEnd;
+ vm_range_end = endOfMem;
+#else
+ /*
+ * the disgusting way to get at the memory assigned to a VM
+ */
- //Add_Page_Range(kernEnd, ISA_HOLE_START, PAGE_AVAIL);
- // ISA hole remains closed (no actual memory)
- // Add_Page_Range(ISA_HOLE_START, ISA_HOLE_END, PAGE_HW);
-
- //Add_Page_Range(ISA_HOLE_END, HIGHMEM_START, PAGE_ALLOCATED);
- // Add_Page_Range(HIGHMEM_START, HIGHMEM_START + KERNEL_HEAP_SIZE, PAGE_HEAP);
- //Add_Page_Range(HIGHMEM_START + KERNEL_HEAP_SIZE, endOfMem, PAGE_AVAIL);
- /* JRL: move page list after kernel heap */
+ vm_range_start = vmmMemEnd;
+ vm_range_end = endOfMem;
- //Now, above the VM region...
-
- // Kernel thread object
- Add_Page_Range(KERNEL_THREAD_OBJECT,KERNEL_THREAD_OBJECT+KERNEL_THREAD_OBJECT_SIZE,PAGE_ALLOCATED);
- // Kernel stack
- Add_Page_Range(KERNEL_STACK,KERNEL_STACK+KERNEL_STACK_SIZE,PAGE_ALLOCATED);
- // Kernel heap
- Add_Page_Range(KERNEL_HEAP,KERNEL_HEAP+KERNEL_HEAP_SIZE,PAGE_HEAP);
- // Kernel page list
- Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN);
- // Free space
- Add_Page_Range(pageListEnd,Round_Down_To_Page(FINAL_KERNEL_START), PAGE_AVAIL);
- // The kernel
- Add_Page_Range(Round_Down_To_Page(FINAL_KERNEL_START),Round_Up_To_Page(FINAL_VMBOOTEND+1),PAGE_KERN);
- // The vmbootpackage
- // IDT (this should be one page)
- Add_Page_Range(IDT_LOCATION,TSS_LOCATION,PAGE_KERN);
- // TSS (this should be one page)
- Add_Page_Range(TSS_LOCATION,GDT_LOCATION, PAGE_KERN);
- // GDT (this should be one page)
- Add_Page_Range(GDT_LOCATION,TOP_OF_MEM, PAGE_KERN);
+#endif
+
+ Add_Page_Range(0, PAGE_SIZE, PAGE_UNUSED); // BIOS area
+ Add_Page_Range(PAGE_SIZE, PAGE_SIZE * 3, PAGE_ALLOCATED); // Intial kernel thread obj + stack
+ Add_Page_Range(PAGE_SIZE * 3, ISA_HOLE_START, PAGE_AVAIL); // Available space
+ Add_Page_Range(ISA_HOLE_START, ISA_HOLE_END, PAGE_HW); // Hardware ROMs
+ Add_Page_Range(KERNEL_START_ADDR, kernEnd, PAGE_KERN); // VMM Kernel
+ // Add_Page_Range(guest_kernel_start, guestEnd, PAGE_VM); // Guest kernel location
+ Add_Page_Range(heapAddr, heapEnd, PAGE_HEAP); // Heap
+ Add_Page_Range(pageListAddr, pageListEnd, PAGE_KERN); // Page List
+ Add_Page_Range(pageListEnd, vmmMemEnd, PAGE_AVAIL); // Available VMM memory
+
+#ifdef RAMDISK_BOOT
+ /*
+ * Zheng 08/03/2008
+ */
+ Add_Page_Range(vmmMemEnd, initrdEnd, PAGE_ALLOCATED); //Ramdisk memory area
+ // Add_Page_Range(vmmMemEnd, endOfMem, PAGE_VM); // Memory allocated to the VM
+ // Until we get a more intelligent memory allocator
+ Add_Page_Range(initrdEnd, endOfMem, PAGE_AVAIL); // Memory allocated to the VM
+#else
+ Add_Page_Range(vmmMemEnd, endOfMem, PAGE_AVAIL); // Memory allocated to the VM
+#endif
/* Initialize the kernel heap */
- Init_Heap(KERNEL_HEAP, KERNEL_HEAP_SIZE);
+ Init_Heap(heapAddr, KERNEL_HEAP_SIZE);
PrintBoth("%uKB memory detected, %u pages in freelist, %d bytes in kernel heap\n",
bootInfo->memSizeKB, g_freePageCount, KERNEL_HEAP_SIZE);
PrintBoth("Memory Layout:\n");
- PrintBoth("%x to %x - VM\n",START_OF_VM,START_OF_VM+VM_SIZE-1);
- PrintBoth("%x to %x - INITIAL THREAD\n",KERNEL_THREAD_OBJECT,KERNEL_THREAD_OBJECT+KERNEL_THREAD_OBJECT_SIZE-1);
- PrintBoth("%x to %x - KERNEL STACK\n",KERNEL_STACK,KERNEL_STACK+KERNEL_STACK_SIZE-1);
- PrintBoth("%x to %x - KERNEL HEAP\n",KERNEL_HEAP,KERNEL_HEAP+KERNEL_HEAP_SIZE-1);
- PrintBoth("%lx to %lx - PAGE LIST\n",pageListAddr,pageListEnd-1);
- PrintBoth("%lx to %x - FREE\n",pageListEnd,FINAL_KERNEL_START-1);
- PrintBoth("%x to %x - KERNEL CODE\n",FINAL_KERNEL_START,FINAL_KERNEL_END);
- PrintBoth("%x to %x - BIOS\n",FINAL_BIOS_START,FINAL_BIOS_END);
- PrintBoth("%x to %x - VGABIOS\n",FINAL_VGA_BIOS_START,FINAL_VGA_BIOS_END);
- PrintBoth("%x to %x - VMXASSIST\n",FINAL_VMXASSIST_START,FINAL_VMXASSIST_END);
- PrintBoth("%x to %x - BIOS (2nd copy)\n",FINAL_BIOS2_START,FINAL_BIOS2_END);
- PrintBoth("%x to %x - IDT\n",IDT_LOCATION,TSS_LOCATION-1);
- PrintBoth("%x to %x - TSS\n",TSS_LOCATION,GDT_LOCATION-1);
- PrintBoth("%x to %x - GDT\n",GDT_LOCATION,TOP_OF_MEM-1);
+ PrintBoth("%x to %x - BIOS AREA\n", 0, PAGE_SIZE - 1);
+ PrintBoth("%x to %x - KERNEL_THREAD_OBJ\n", PAGE_SIZE, PAGE_SIZE * 2 - 1);
+ PrintBoth("%x to %x - KERNEL_STACK\n", PAGE_SIZE * 2, PAGE_SIZE * 3 - 1);
+ PrintBoth("%lx to %x - FREE\n", PAGE_SIZE * 3, ISA_HOLE_START - 1);
+ PrintBoth("%x to %x - ISA_HOLE\n", ISA_HOLE_START, ISA_HOLE_END - 1);
+ PrintBoth("%x to %x - KERNEL CODE + VM_KERNEL\n", KERNEL_START_ADDR, kernEnd - 1);
+ // PrintBoth("%x to %x - VM_KERNEL\n", kernEnd, guestEnd - 1);
+ PrintBoth("%x to %x - KERNEL HEAP\n", heapAddr, heapEnd - 1);
+ PrintBoth("%lx to %lx - PAGE LIST\n", pageListAddr, pageListEnd - 1);
+ PrintBoth("%lx to %x - FREE\n", pageListEnd, vmmMemEnd - 1);
+
+#ifdef RAMDISK_BOOT
+ /*
+ * Zheng 08/03/2008
+ */
+ PrintBoth("%lx to %x - RAMDISK\n", vmmMemEnd, initrdEnd - 1);
+ PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", initrdEnd, endOfMem - 1);
+#else
+ PrintBoth("%lx to %x - GUEST_MEMORY (also free)\n", vmmMemEnd, endOfMem - 1);
+#endif
}
/*
/* Fill .bss with zeroes */
memset(&BSS_START, '\0', &BSS_END - &BSS_START);
- PrintBoth("BSS Inited, BSS_START=%x, BSS_END=%x\n",BSS_START,BSS_END);
+ // screen is not inited yet - PAD
+ // PrintBoth("BSS Inited, BSS_START=%x, BSS_END=%x\n",BSS_START,BSS_END);
}
/*