void mem_init(void) { if (!cpu_onboot()) // only do once, on the boot CPU return; // Determine how much base (<640K) and extended (>1MB) memory // is available in the system (in bytes), // by reading the PC's BIOS-managed nonvolatile RAM (NVRAM). // The NVRAM tells us how many kilobytes there are. // Since the count is 16 bits, this gives us up to 64MB of RAM; // additional RAM beyond that would have to be detected another way. size_t basemem = ROUNDDOWN(nvram_read16(NVRAM_BASELO)*1024, PAGESIZE); size_t extmem = ROUNDDOWN(nvram_read16(NVRAM_EXTLO)*1024, PAGESIZE); warn("Assuming we have 1GB of memory!"); extmem = 1024*1024*1024 - MEM_EXT; // assume 1GB total memory // The maximum physical address is the top of extended memory. mem_max = MEM_EXT + extmem; // Compute the total number of physical pages (including I/O holes) mem_npage = mem_max / PAGESIZE; cprintf("Physical memory: %dK available, ", (int)(mem_max/1024)); cprintf("base = %dK, extended = %dK\n", (int)(basemem/1024), (int)(extmem/1024)); spinlock_init(&_freelist_lock); pageinfo *mem_pageinfo = (pageinfo*)ROUNDUP((uint32_t)end, (uint32_t)sizeof(pageinfo)); memset(mem_pageinfo, 0, sizeof(pageinfo)*mem_npage); pageinfo **freetail = &mem_freelist; int i; // Pages 0 and 1 are reserved. for (i = 2; i < mem_npage; i++) { // All of base memory otherwise is free after the kernel // and the pageinfo table all memory should be free if(i < basemem/4096 || i >= (uint32_t)(ROUNDUP(&mem_pageinfo[mem_npage],4096))/4096) { // A free page has no references to it. mem_pageinfo[i].refcount = 0; // Add the page to the end of the free list. *freetail = &mem_pageinfo[i]; freetail = &mem_pageinfo[i].free_next; } } *freetail = NULL; // null-terminate the freelist // Check to make sure the page allocator seems to work correctly. mem_check(); }
void main_console (void *data) { /* Read parameters from NVRAM. */ nvram_init (); reset_counter = nvram_read16 (0); /* Increment reset counter. */ ++reset_counter; /* Write reset counter to NVRAM. */ nvram_unprotect (&timer); nvram_write16 (0, reset_counter); nvram_protect (&timer); for (;;) tcl_main ((stream_t*) &uart); }
void mem_init(void) { if (!cpu_onboot()) // only do once, on the boot CPU return; // Determine how much base (<640K) and extended (>1MB) memory // is available in the system (in bytes), // by reading the PC's BIOS-managed nonvolatile RAM (NVRAM). // The NVRAM tells us how many kilobytes there are. // Since the count is 16 bits, this gives us up to 64MB of RAM; // additional RAM beyond that would have to be detected another way. size_t basemem = ROUNDDOWN(nvram_read16(NVRAM_BASELO)*1024, PAGESIZE); size_t extmem = ROUNDDOWN(nvram_read16(NVRAM_EXTLO)*1024, PAGESIZE); warn("Assuming we have 1GB of memory!"); extmem = 1024*1024*1024 - MEM_EXT; // assume 1GB total memory // The maximum physical address is the top of extended memory. mem_max = MEM_EXT + extmem; // Compute the total number of physical pages (including I/O holes) mem_npage = mem_max / PAGESIZE; cprintf("Physical memory: %dK available, ", (int)(mem_max/1024)); cprintf("base = %dK, extended = %dK\n", (int)(basemem/1024), (int)(extmem/1024)); // Insert code here to: // (1) allocate physical memory for the mem_pageinfo array, // making it big enough to hold mem_npage entries. // (2) add all pageinfo structs in the array representing // available memory that is not in use for other purposes. // // For step (2), here is some incomplete/incorrect example code // that simply marks all mem_npage pages as free. // Which memory is actually free? // 1) Reserve page 0 for the real-mode IDT and BIOS structures // (do not allow this page to be used for anything else). // 2) Reserve page 1 for the AP bootstrap code (boot/bootother.S). // 3) Mark the rest of base memory as free. // 4) Then comes the IO hole [MEM_IO, MEM_EXT). // Mark it as in-use so that it can never be allocated. // 5) Then extended memory [MEM_EXT, ...). // Some of it is in use, some is free. // Which pages hold the kernel and the pageinfo array? // Hint: the linker places the kernel (see start and end above), // but YOU decide where to place the pageinfo array. // Change the code to reflect this. pageinfo **freetail = &mem_freelist; int i; for (i = 0; i < mem_npage; i++) { // A free page has no references to it. mem_pageinfo[i].refcount = 0; // Add the page to the end of the free list. *freetail = &mem_pageinfo[i]; freetail = &mem_pageinfo[i].free_next; } *freetail = NULL; // null-terminate the freelist // ...and remove this when you're ready. panic("mem_init() not implemented"); // Check to make sure the page allocator seems to work correctly. mem_check(); }