size_t npages; // Amount of physical memory (in pages) static size_t npages_basemem; // Amount of base memory (in pages) // These variables are set in mem_init() pde_t *kern_pgdir; // Kernel's initial page directory struct Page *pages; // Physical page state array static struct Page *page_free_list; // Free list of physical pages
struct Page { struct Page *pp_link; uint16_t pp_ref; };
static void * boot_alloc(uint32_t n) { static char *nextfree; // virtual address of next byte of free memory char *result; // Initialize nextfree if this is the first time. // 'end' is a magic symbol automatically generated by the linker, // which points to the end of the kernel's bss segment: // the first virtual address that the linker did *not* assign // to any kernel code or global variables. if (!nextfree) { extern char end[]; nextfree = ROUNDUP((char *) end, PGSIZE); } // Allocate a chunk large enough to hold 'n' bytes, then update // nextfree. Make sure nextfree is kept aligned // to a multiple of PGSIZE. // // LAB 2: Your code here. result = nextfree; nextfree += (uint32_t)ROUNDUP((char *) n, PGSIZE); if ( (uint32_t)nextfree > (KERNBASE + npages*PGSIZE)) { panic("boot_alloc: Out of Memory!\n"); } return result; }
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; // Mark physical page 0 as in use. pages[0].pp_ref = 1; // Base memory, [PGSIZE, npages_basemem * PGSIZE) is free. for (i = 1; i < (IOPHYSMEM / PGSIZE) ; i++) { pages[i].pp_ref = 0; pages[i].pp_link = page_free_list; page_free_list = &pages[i]; } // IO hole [IOPHYSMEM, EXTPHYSMEM). for (i; i < (EXTPHYSMEM / PGSIZE) ; i++) { pages[i].pp_ref = 1; } // Used in extended memory [EXTPHYSMEM, ...). for (i; i < PADDR(boot_alloc(0)) / PGSIZE; i++) { pages[i].pp_ref = 1; } for (i; i < npages; i++) { pages[i].pp_ref = 0; pages[i].pp_link = page_free_list; page_free_list = &pages[i]; } }
struct Page * page_alloc(int alloc_flags) { // Fill this function in struct Page *free_page; if (page_free_list == NULL) return NULL; free_page = page_free_list; page_free_list = page_free_list->pp_link; //fills the entire physical page with '\0' bytes. if (alloc_flags & ALLOC_ZERO) memset(page2kva(free_page), 0, PGSIZE); return free_page; }
void page_free(struct Page *pp) { // Fill this function in assert(pp->pp_ref == 0); memset(page2kva(pp), 0, PGSIZE); pp->pp_link = page_free_list; page_free_list = pp; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t *ebp, *eip; uint32_t arg1, arg2, arg3, arg4, arg5; struct Eipdebuginfo info; char fn_name[101]; uint32_t i; cprintf("Stack backtrace:\n"); // Get the ebp using read_ebp() in <x86.h>. ebp = (uint32_t *)read_ebp(); // Stop when ebp == 0; while(ebp != 0x0) { eip = (uint32_t*) ebp[1]; arg1 = ebp[2]; arg2 = ebp[3]; arg3 = ebp[4]; arg4 = ebp[5]; arg5 = ebp[6]; cprintf(" ebp %08x eip %08x args %08x %08x %08x %08x %08x\n", ebp, eip, arg1, arg2, arg3, arg4, arg5); // Get the info of function. debuginfo_eip((uintptr_t)eip, &info); // Remove unnecessary char in info.eip_fn_name. // Store the fuction name to an array. for(i = 0; i < info.eip_fn_namelen && i < 100; ++i) fn_name[i] = info.eip_fn_name[i]; fn_name[i] = '\0'; cprintf(" %s:%d: %s+%d\n",info.eip_file, info.eip_line, fn_name, eip-info.eip_fn_addr, info.eip_fn_narg); ebp = (uint32_t*)(*ebp); } return 0; }
int get_color(char type) { int color = 0; switch (type) { case 'R': color = FORE_RED; break; case 'G': color = FORE_GREEN; break; case 'B': color = FORE_BLUE; break; case 'W': color = FORE_WHITE; case 'K': color = FORE_BLACK; default: break; } return color; }
while ((ch = *(unsigned char *) fmt++) != '%') { if (ch == '\0') return; //putch(ch, putdat); cflag = 1; //foreground color if (ch == '$') { ch = *(unsigned char *)fmt++; color = get_color(ch); cflag = 0; } if (cflag) putch(ch, putdat); }
#define FORE_BLACK 0x0000 #define FORE_RED 0x0400 #define FORE_GREEN 0x0200 #define FORE_BLUE 0x0100 #define FORE_WHITE 0x0700 int color = FORE_WHITE;
if (crt_pos >= CRT_SIZE) { int i; memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t)); for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++) crt_buf[i] = 0x0700 | ' '; crt_pos -= CRT_COLS; }
// (unsigned) octal case 'o': // Replace this with your code. num = getuint(&ap, lflag); base = 8; goto number;