From 3ce41454c4f723278306ca27b5aae55c24c45915 Mon Sep 17 00:00:00 2001 From: AceVest Date: Fri, 4 Apr 2014 22:16:54 +0800 Subject: [PATCH] bootmem manage the hole mem. --- boot/boot.c | 206 ------------------------------------------- include/list.h | 57 ++++++------ include/page.h | 11 ++- mm/buddy.c | 15 ++++ mm/mm.c | 235 +++++++++---------------------------------------- mm/page.c | 2 + setup/setup.c | 2 +- 7 files changed, 94 insertions(+), 434 deletions(-) create mode 100644 mm/buddy.c diff --git a/boot/boot.c b/boot/boot.c index 329d169..eed5e5f 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -65,209 +65,3 @@ void CheckKernel(unsigned long addr, unsigned long magic) init_boot_params(mbi); } - -#if 0 -{ - int i, mmapCount; - pmmapItem pMPI; - - pMultiBootInfo pMBI = (pMultiBootInfo) addr; - - - - { - printk("mmap_addr %x mmap_length %x\n", pMBI->mmap_addr, pMBI->mmap_length); - while(1); - - } - - - system.boot_device = pMBI->boot_device; - - /* 分析命令行参数 */ - parse_cmdline((const char *)pMBI->cmdline); - - system.mmap_addr= pMBI->mmap_addr; - system.mmap_size= pMBI->mmap_length; - system.mm_lower = pMBI->mem_lower; - system.mm_upper = pMBI->mem_upper; - system.mm_size = 0x100000 + (system.mm_upper<<10); - // 最大只管理1G的内存 - if(system.mm_size > MAX_SUPT_PHYMM_SIZE) - system.mm_size = MAX_SUPT_PHYMM_SIZE; - - // 重新进行页映射 - system.page_count = (system.mm_size >> PAGE_SHIFT); - system.pgd = (unsigned long *) &krnl_end; - system.pte_start = system.pgd + PAGE_ITEMS; - - unsigned long *pde = system.pgd; - unsigned long *pte = system.pte_start; - unsigned long pde_count = system.page_count/PAGE_ITEMS + - (system.page_count%PAGE_ITEMS != 0); - - unsigned long pde_base = KRNLADDR>>22; - pde[pde_base] = 7 + va2pa(pte); - for(i=pde_base+1; i<(pde_base+pde_count); i++) - pde[i] = pde[i-1] + 0x1000; - pte[0] = 7; - for(i=1; i>1;//bitmap size - u32 bmaddr = system.page_bitmap; - for(i=0; i>1) + (bmSize%8 != 0); - bmaddr += bmSize; - bmaddr = ALIGN(bmaddr, sizeof(long)); - } - memset(system.page_bitmap, 0x00, bmaddr - system.page_bitmap); - - system.kernel_end = PAGE_UP(bmaddr); - - - - mmapCount = system.mmap_size/sizeof(mmapItem); - pMPI = (pmmapItem) system.mmap_addr; - -#if 1 - printk("mm_size: %d MB\n", system.mm_size>>20); - printk("page_count:%d page_map:%08x page_bitmap:%08x\n", - system.page_count, system.page_map, system.page_bitmap); - printk("boot device: %x\n", (unsigned int)system.boot_device); - printk("CmdLine: %s\n", system.cmdline); - printk("mmap count: %d\n", mmapCount); -#endif - - - // 初始化空闲页链表头 - for(i=0; ibase_addr_low; - u32 length = pMPI->length_low; - u32 type = pMPI->type; - - - printk("--%08x %08x %02x\n", base, length, type); - - - if(type == E820_RAM) - { - if((base+length)>MAX_SUPT_PHYMM_SIZE) - { - length = MAX_SUPT_PHYMM_SIZE - base; - } - - if(base < va2pa(system.kernel_end) - && va2pa(system.kernel_end) < base+length) - { - unsigned int offset; - offset = va2pa(PAGE_UP(system.kernel_end)) - base; - base += offset; - length -= offset; - } - if(base == 0) - { - if(length < 0x1000) - continue; - base += 0x1000; - length -= 0x1000; - } - printk("base:%08x length:%08x addr:%08x\n", - base, length, base+length); - - init_free_area(base, length); - } - } -} - -int get_order(unsigned int min_pfn, unsigned int max_pfn) -{ - int i, order, size; - - assert(min_pfn<=max_pfn); - for(i=order=0; imax_pfn) - { - order--; - size >>= 1; - } - - return order; -} - -void init_free_area(u32 base, u32 len) -{ - unsigned int max_pfn, min_pfn; - unsigned int i,order,size; - - min_pfn = get_pfn(base); - max_pfn = get_pfn(base+len); -/* - printk("%08x\t%08x\t%x\t%x\t%x\t%d\n",base, base+len, - min_pfn, max_pfn, - max_pfn-min_pfn, - max_pfn-min_pfn); -*/ - assert(min_pfn<=system.page_count); - assert(max_pfn<=system.page_count); - - while(min_pfn != max_pfn) - { - order = get_order(min_pfn, max_pfn); - //printk("min:%05d end:%05d max:%05d order:%02d\n", - // min_pfn, min_pfn+(1<=MAX_ORDER)? MAX_ORDER-1: order; - assert(0<=order && order>(order+1), - (unsigned long *)freeArea[order].map); - - //printk("%d\t%08x %d\t",pgmap[min_pfn].mapNR>>(order+1), - // freeArea[order].map, min_pfn); - min_pfn += size; - //printk("%d\t%d\t%d\t%d\n",min_pfn, max_pfn, order, size); - //int j=3000000;while(j--); - } -} -#endif diff --git a/include/list.h b/include/list.h index 4b087ff..fba8175 100644 --- a/include/list.h +++ b/include/list.h @@ -14,75 +14,74 @@ *-------------------------------------------------------------------------- */ -#ifndef _LIST_H -#define _LIST_H +#pragma once /* Allmost Copy From Linux */ typedef struct list_head { struct list_head *prev, *next; -} ListHead, *pListHead; +} list_head_t; + +// TODO Remove +typedef list_head_t ListHead, *pListHead; #define LIST_HEAD_INIT(name) {&(name), &(name) } -#define LIST_HEAD(name) ListHead name = LIST_HEAD_INIT(name) -#define INIT_LIST_HEAD(ptr) \ -do{ \ +#define LIST_HEAD(name) list_head_t name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) \ +do{ \ (ptr)->next = (ptr); \ (ptr)->prev = (ptr); \ }while(0) -#define list_entry(ptr, type, member) \ +#define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) -#define list_for_each(pos, head) \ +#define list_for_each(pos, head) \ for(pos = (head)->next; pos != (head); pos = pos->next) -#define list_for_each_safe(pos, tmp, head) \ - for(pos = (head)->next, tmp = pos->next; \ - pos != (head); \ + +#define list_for_each_safe(pos, tmp, head) \ + for(pos = (head)->next, tmp = pos->next;\ + pos != (head); \ pos = tmp, tmp = pos->next) -static inline void _list_add( pListHead newItem, - pListHead prev, - pListHead next) +static inline void _list_add(list_head_t *pnew, list_head_t *prev, list_head_t *next) { - next->prev = newItem; - newItem->next = next; - newItem->prev = prev; - prev->next = newItem; + next->prev = pnew; + pnew->next = next; + pnew->prev = prev; + prev->next = pnew; } -static inline void list_add(pListHead newItem, pListHead head) +static inline void list_add(list_head_t *pnew, list_head_t *head) { - _list_add(newItem, head, head->next); + _list_add(pnew, head, head->next); } -static inline void list_add_tail(pListHead newItem, pListHead head) +static inline void list_add_tail(list_head_t *pnew, list_head_t *head) { - _list_add(newItem, head->prev, head); + _list_add(pnew, head->prev, head); } -static inline void _list_del(pListHead prev, pListHead next) +static inline void _list_del(list_head_t *prev, list_head_t *next) { next->prev = prev; prev->next = next; } -static inline void list_del(pListHead entry) +static inline void list_del(list_head_t *entry) { _list_del(entry->prev, entry->next); } -static inline void list_del_init(pListHead entry) +static inline void list_del_init(list_head_t *entry) { _list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); } -static inline int list_is_empty(pListHead head) +static inline int list_is_empty(list_head_t *head) { return head->next == head; } - - -#endif //_LIST_H diff --git a/include/page.h b/include/page.h index 0eb6492..61911eb 100644 --- a/include/page.h +++ b/include/page.h @@ -66,6 +66,13 @@ typedef unsigned long pte_t; #define MAX_ORDER (11) typedef struct page +{ + + +} page_t; + +// TODO Remove +typedef struct page_ { //struct page *prev, *next; ListHead list; @@ -74,7 +81,7 @@ typedef struct page unsigned int count; } Page, *pPage; -typedef struct free_area +typedef struct free_area_ { //struct page *prev, *next; ListHead freeList; @@ -84,8 +91,6 @@ typedef struct free_area } FreeArea, *pFreeArea; -extern FreeArea freeArea[MAX_ORDER]; - pPage alloc_pages(unsigned int order); void free_pages(pPage page); //void free_pages(pPage page, unsigned int order); diff --git a/mm/buddy.c b/mm/buddy.c new file mode 100644 index 0000000..55fec7f --- /dev/null +++ b/mm/buddy.c @@ -0,0 +1,15 @@ +/* + * ------------------------------------------------------------------------ + * File Name: buddy.c + * Author: Zhao Yanbai + * Fri Apr 4 19:25:02 2014 + * Description: none + * ------------------------------------------------------------------------ + */ +#include + +void init_buddy_system() +{ + + +} diff --git a/mm/mm.c b/mm/mm.c index d51e90e..b669fab 100644 --- a/mm/mm.c +++ b/mm/mm.c @@ -73,15 +73,14 @@ typedef struct bootmem_data { unsigned long max_pfn; unsigned long last_offset; // offset to pfn2pa(this->min_pfn); - unsigned long last_hint_inx; // last hit index in bitmap + unsigned long last_hit_pfn; // last hit index in bitmap void *bitmap; unsigned long mapsize; } bootmem_data_t; bootmem_data_t bootmem_data; -#define pfn2inx(pfn) ((pfn) - bootmem_data.min_pfn) -#define inx2pfn(inx) ((inx) + bootmem_data.min_pfn) + void e820_init_bootmem_data() @@ -104,19 +103,11 @@ void e820_init_bootmem_data() bgn_pfn = pa2pfn(p->addr); end_pfn = pa2pfn(p->addr + p->size); - if(bootmem_data.min_pfn > bgn_pfn) - bootmem_data.min_pfn = bgn_pfn; - if(bootmem_data.max_pfn < end_pfn) bootmem_data.max_pfn = end_pfn; } - // limit min_pfn - unsigned long kernel_begin_pfn = va2pfn(&kernel_begin); - if(bootmem_data.min_pfn < kernel_begin_pfn) - { - bootmem_data.min_pfn = kernel_begin_pfn; - } + bootmem_data.min_pfn = 0; // limit max_pfn unsigned long max_support_pfn = pa2pfn(MAX_SUPT_PHYMM_SIZE); @@ -124,12 +115,6 @@ void e820_init_bootmem_data() { bootmem_data.max_pfn = max_support_pfn; } - - if(bootmem_data.min_pfn >= bootmem_data.max_pfn) - { - printk("can not go on playing...\n"); - while(1); - } } void register_bootmem_pages() @@ -147,18 +132,7 @@ void register_bootmem_pages() unsigned long bgn_pfn = PFN_UP(p->addr); unsigned long end_pfn = PFN_DW(p->addr + p->size); - bgn_pfn = bgn_pfn > bootmem_data.min_pfn ? bgn_pfn : bootmem_data.min_pfn; - end_pfn = end_pfn < bootmem_data.max_pfn ? end_pfn : bootmem_data.max_pfn; - - if(bgn_pfn >= end_pfn) - { - continue; - } - - unsigned long bgn_inx = pfn2inx(bgn_pfn); - unsigned long end_inx = pfn2inx(end_pfn); - - for(j=bgn_inx; j> PAGE_SHIFT; step = step > 0 ? step : 1; - bgn_inx = ALIGN(pbd->min_pfn, step) - pbd->min_pfn; - end_inx = pbd->max_pfn - pbd->min_pfn; + bgn_pfn = ALIGN(pbd->min_pfn, step); + end_pfn = pbd->max_pfn; - // 优先从上次分配结束的地方开始分配 - if(pbd->last_hint_inx > bgn_inx) + // start from last position + if(pbd->last_hit_pfn > bgn_pfn) { - fallback = bgn_inx + 1; - bgn_inx = align_bootmem_index(pbd->last_hint_inx, step); + fallback = bgn_pfn + 1; + bgn_pfn = ALIGN(pbd->last_hit_pfn, step); } while(1) { int merge; void *region; - unsigned long i, search_end_inx; + unsigned long i, search_end_pfn; unsigned long start_off, end_off; find_block: - bgn_inx = find_next_zero_bit(pbd->bitmap, end_inx - bgn_inx, bgn_inx); - bgn_inx = align_bootmem_index(bgn_inx, step); + bgn_pfn = find_next_zero_bit(pbd->bitmap, end_pfn, bgn_pfn); + bgn_pfn = ALIGN(bgn_pfn, step); - search_end_inx = bgn_inx + PFN_UP(size); + search_end_pfn = bgn_pfn + PFN_UP(size); - if(bgn_inx >= end_inx || search_end_inx > end_inx) + if(bgn_pfn >= end_pfn || search_end_pfn > end_pfn) break; - for(i=bgn_inx; ibitmap) != 0) { // space not enough - bgn_inx = align_bootmem_index(i, step); - if(bgn_inx == i) - bgn_inx += step; + bgn_pfn = ALIGN(i, step); + if(bgn_pfn == i) + bgn_pfn += step; goto find_block; } } - // 如果上次分配截止地址不是页对齐,且是本页的上一页.就尝试利用这段空间. - if(pbd->last_offset & (PAGE_SIZE - 1) && PFN_DW(pbd->last_offset) + 1 == bgn_inx) - start_off = align_bootmem_offset(pbd->last_offset, align); + // try to use the unused part of last page + if(pbd->last_offset & (PAGE_SIZE - 1) && PFN_DW(pbd->last_offset) + 1 == bgn_pfn) + start_off = ALIGN(pbd->last_offset, align); else - start_off = pfn2pa(bgn_inx); + start_off = pfn2pa(bgn_pfn); - merge = PFN_DW(start_off) < bgn_inx; + merge = PFN_DW(start_off) < bgn_pfn; end_off = start_off + size; - pbd->last_offset = end_off; - pbd->last_hint_inx = PFN_UP(end_off); + pbd->last_offset = end_off; + pbd->last_hit_pfn = PFN_UP(end_off); reserve_bootmem(PFN_DW(start_off) + merge, PFN_UP(end_off)); - region = pa2va(pfn2pa(pbd->min_pfn) + start_off); + region = pa2va(start_off); memset(region, 0, size); @@ -314,7 +272,7 @@ find_block: if(fallback) { - bgn_inx = align_bootmem_index(fallback-1, step); + bgn_pfn = ALIGN(fallback-1, step); fallback = 0; goto find_block; } @@ -365,122 +323,9 @@ void init_paging() void init_mm() { + printk("init bootmem alloc...\n"); init_bootmem(); + printk("init global paging...\n"); init_paging(); + printk("init buddy system...\n"); } - - - - - - -FreeArea freeArea[MAX_ORDER]; -#if 0 -unsigned long mb_mm_lower, mb_mm_upper; -unsigned long mb_mmap_addr, mb_mmap_size; -unsigned long mmStart, mmEnd; -unsigned long totalPages; -FreeArea freeArea[MAX_ORDER]; - -void printBitMap(FreeArea fa) -{ - int i; - printk("# "); - for(i=0; i 1UL<<30) - mm_size = 1UL<<30; - - printk("mm_size: %x\n", mm_size); - -/* - pmmapItem mmap; - unsigned long maxAddr; - - mmStart = (va2pa(&end) + (PAGE_SIZE-1)) & PAGE_MASK; - //mmEnd = (mb_mm_upper) & PAGE_MASK; - - mmap = (pmmapItem)mb_mmap_addr; - maxAddr = 0; - int n = 1; - printk("Boot Loader Provided Physical RAM Map:\n"); - while((unsigned long)mmap < (mb_mmap_addr + mb_mmap_size)) - { - printk("[%02d] 0x%08x%08x - 0x%08x%08x ", - n++,//mmap->size, - - mmap->base_addr_high, - mmap->base_addr_low, - mmap->length_high, - mmap->length_low); - - switch(mmap->type) - { - case E820_RAM: - printk("RAM"); - if(maxAddr<(mmap->base_addr_low+mmap->length_low)) - { - maxAddr = - mmap->base_addr_low + mmap->length_low; - } - break; - case E820_RESERVED: - printk("Reserved"); - break; - case E820_ACPI: - printk("ACPI Data"); - break; - case E820_NVS: - printk("ACPI NVS"); - break; - default: - printk("Unknown %x\n", mmap->type); - break; - } - printk("\n"); - - mmap = (pmmapItem) ((unsigned long) mmap - + mmap->size + sizeof(mmap->size)); - } - - - //if(maxAddr < mmEnd) - mmEnd = maxAddr & PAGE_MASK; - if(mmEnd > MAX_SUPT_PHY_MEM_SIZE) - mmEnd = MAX_SUPT_PHY_MEM_SIZE; - totalPages = mmEnd >> PAGE_SHIFT; - - - // bit map - int i; - static char *bitmap_start,*bitmap_end; - bitmap_start = (char *)mmStart; - - - - // - unsigned long bitmap_size = (mmEnd + 7) / 8; - bitmap_size = (bitmap_size + (sizeof(long) - 1UL)) - &~ (sizeof(long) - 1UL); - //while(1); - //memset(bitmap_start, 0xFF, bitmap_size); - -#if 0 - printk( "bitmap_start: %x " - "mmStart: %x " - "mmEnd: %x " - "bitmap_size: %x\n", - bitmap_start, - mmStart, - mmEnd, - bitmap_size); -#endif -*/ -} -#endif diff --git a/mm/page.c b/mm/page.c index 64632b6..e81f06c 100644 --- a/mm/page.c +++ b/mm/page.c @@ -24,6 +24,8 @@ #define add_page2list(page, order) \ list_add(&page->list, &freeArea[order].freeList) +FreeArea freeArea[MAX_ORDER]; + #if 1 void do_no_page(void *addr) { diff --git a/setup/setup.c b/setup/setup.c index 72011a6..35fe2fc 100644 --- a/setup/setup.c +++ b/setup/setup.c @@ -42,7 +42,7 @@ void setup_kernel() { extern char _start, _end; - printk("kernel:\t%08x - %08x\n", &_start, &_end); + printk("kernel: %08x - %08x\n", &_start, &_end); init_mm(); -- 2.44.0