⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mem.c

📁 The main purpose of this project is to add a new scheduling algorithm to GeekOS and to implement a s
💻 C
字号:
/* * 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.44 $ *  * This is free software.  You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */#include <geekos/defs.h>#include <geekos/ktypes.h>#include <geekos/kassert.h>#include <geekos/bootinfo.h>#include <geekos/gdt.h>#include <geekos/screen.h>#include <geekos/int.h>#include <geekos/malloc.h>#include <geekos/string.h>#include <geekos/mem.h>/* ---------------------------------------------------------------------- * Global data * ---------------------------------------------------------------------- *//* * List of Page structures representing each page of physical memory. */struct Page* g_pageList;/* * Number of pages currently available on the freelist. */uint_t g_freePageCount = 0;/* ---------------------------------------------------------------------- * Private data and functions * ---------------------------------------------------------------------- *//* * Defined in paging.c */extern int debugFaults;#define Debug(args...) if (debugFaults) Print(args)/* * List of pages available for allocation. */static struct Page_List s_freeList;/* * Total number of physical pages. */int unsigned s_numPages;/* * Add a range of pages to the inventory of physical memory. */static void Add_Page_Range(ulong_t start, ulong_t end, int flags){    ulong_t addr;    KASSERT(Is_Page_Multiple(start));    KASSERT(Is_Page_Multiple(end));    KASSERT(start < end);    for (addr = start; addr < end; addr += PAGE_SIZE) {	struct Page *page = Get_Page(addr);	page->flags = flags;	if (flags == PAGE_AVAIL) {	    /* Add the page to the freelist */	    Add_To_Back_Of_Page_List(&s_freeList, page);	    /* Update free page count */	    ++g_freePageCount;	} else {	    Set_Next_In_Page_List(page, 0);	    Set_Prev_In_Page_List(page, 0);	}    }}/* ---------------------------------------------------------------------- * Public functions * ---------------------------------------------------------------------- *//* * The linker defines this symbol to indicate the end of * the executable image. */extern char end;/* * Initialize memory management data structures. * Enables the use of Alloc_Page() and Free_Page() functions. */void Init_Mem(struct Boot_Info* bootInfo){    ulong_t numPages = bootInfo->memSizeKB >> 2;    ulong_t endOfMem = numPages * PAGE_SIZE;    unsigned numPageListBytes = sizeof(struct Page) * numPages;    ulong_t pageListAddr;    ulong_t kernEnd;    KASSERT(bootInfo->memSizeKB > 0);    /*     * Before we do anything, switch from setup.asm's temporary GDT     * to the kernel's permanent 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.     */    pageListAddr = Round_Up_To_Page((ulong_t) &end);    g_pageList = (struct Page*) pageListAddr;    kernEnd = Round_Up_To_Page(pageListAddr + numPageListBytes);    s_numPages = numPages;    /*     * The initial kernel thread and its stack are placed     * just beyond the ISA hole.     */    KASSERT(ISA_HOLE_END == KERN_THREAD_OBJ);    KASSERT(KERN_STACK == KERN_THREAD_OBJ + PAGE_SIZE);    /*     * 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)     */    Add_Page_Range(0, PAGE_SIZE, PAGE_UNUSED);    Add_Page_Range(PAGE_SIZE, KERNEL_START_ADDR, PAGE_AVAIL);    Add_Page_Range(KERNEL_START_ADDR, kernEnd, PAGE_KERN);    Add_Page_Range(kernEnd, ISA_HOLE_START, PAGE_AVAIL);    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);    /* Initialize the kernel heap */    Init_Heap(HIGHMEM_START, KERNEL_HEAP_SIZE);    Print("%uKB memory detected, %u pages in freelist, %d bytes in kernel heap\n",	bootInfo->memSizeKB, g_freePageCount, KERNEL_HEAP_SIZE);}/* * Initialize the .bss section of the kernel executable image. */void Init_BSS(void){    extern char BSS_START, BSS_END;    /* Fill .bss with zeroes */    memset(&BSS_START, '\0', &BSS_END - &BSS_START);}/* * Allocate a page of physical memory. */void* Alloc_Page(void){    struct Page* page;    void *result = 0;    bool iflag = Begin_Int_Atomic();    /* See if we have a free page */    if (!Is_Page_List_Empty(&s_freeList)) {	/* Remove the first page on the freelist. */	page = Get_Front_Of_Page_List(&s_freeList);	KASSERT((page->flags & PAGE_ALLOCATED) == 0);	Remove_From_Front_Of_Page_List(&s_freeList);	/* Mark page as having been allocated. */	page->flags |= PAGE_ALLOCATED;	g_freePageCount--;	result = (void*) Get_Page_Address(page);    }    End_Int_Atomic(iflag);    return result;}/* * Free a page of physical memory. */void Free_Page(void* pageAddr){    ulong_t addr = (ulong_t) pageAddr;    struct Page* page;    bool iflag;    iflag = Begin_Int_Atomic();    KASSERT(Is_Page_Multiple(addr));    /* Get the Page object for this page */    page = Get_Page(addr);    KASSERT((page->flags & PAGE_ALLOCATED) != 0);    /* Clear the allocation bit */    page->flags &= ~(PAGE_ALLOCATED);    /* Put the page back on the freelist */    Add_To_Back_Of_Page_List(&s_freeList, page);    g_freePageCount++;    End_Int_Atomic(iflag);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -