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<system.page_count; i++)
- pte[i] = pte[i-1] + 0x1000;
-
- //asm("xchg %bx,%bx");
- asm("movl %%edx, %%cr3"::"d"(va2pa(pde)));
-
- system.pte_end = pte+i;
- system.pte_end = (u32*) PAGE_UP(system.pte_end);
-
- system.page_map = (pPage)system.pte_end;
- system.page_bitmap = PAGE_UP((system.page_map +
- system.page_count));
- memset((u32)system.page_map, 0,
- system.page_bitmap-(u32)system.page_map);
-
- // 初始化伙伴系统的位图
- unsigned int bmSize = system.page_count>>1;//bitmap size
- u32 bmaddr = system.page_bitmap;
- for(i=0; i<MAX_ORDER; i++)
- {
- freeArea[i].map = (unsigned char *)bmaddr;
- bmSize = (bmSize>>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; i<MAX_ORDER; i++)
- INIT_LIST_HEAD(&freeArea[i].freeList);
-
- // 初始化描述每个页的结构体
- for(i=0; i<system.page_count; i++)
- {
- INIT_LIST_HEAD(&pgmap[i].list);
- pgmap[i].mapNR = i;
- pgmap[i].count = 0;
- }
-
- for(i=0; i<mmapCount; i++, pMPI++)
- {
- // unsupport high part
- u32 base = pMPI->base_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; i<MAX_ORDER; i++)
- {
- if(min_pfn % (1UL<<i) == 0)
- order = i;
- }
-
- size = 1UL<<order;
-
- while(min_pfn+size>max_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<<order), max_pfn, order);
-
- //order = (order>=MAX_ORDER)? MAX_ORDER-1: order;
- assert(0<=order && order<MAX_ORDER);
-
- size = 1<<order;
-
- pgmap[min_pfn].order = order;
- list_add(&pgmap[min_pfn].list, &freeArea[order].freeList);
-
- change_bit(pgmap[min_pfn].mapNR>>(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
*--------------------------------------------------------------------------
*/
-#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
#define MAX_ORDER (11)
typedef struct page
+{
+
+
+} page_t;
+
+// TODO Remove
+typedef struct page_
{
//struct page *prev, *next;
ListHead list;
unsigned int count;
} Page, *pPage;
-typedef struct free_area
+typedef struct free_area_
{
//struct page *prev, *next;
ListHead freeList;
} 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);
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: buddy.c
+ * Author: Zhao Yanbai
+ * Fri Apr 4 19:25:02 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+#include <mm.h>
+
+void init_buddy_system()
+{
+
+
+}
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()
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);
{
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()
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<end_inx; ++j)
+ for(j=bgn_pfn; j<end_pfn; ++j)
{
test_and_clear_bit(j, bootmem_data.bitmap);
}
}
-void reserve_bootmem(unsigned long bgn_inx, unsigned long end_inx)
+void reserve_bootmem(unsigned long bgn_pfn, unsigned long end_pfn)
{
- //printk("reserve %d %d\n", bgn_inx, end_inx);
+ //printk("reserve %d %d\n", bgn_pfn, end_pfn);
int i=0;
- for(i=bgn_inx; i<end_inx; ++i)
+ for(i=bgn_pfn; i<end_pfn; ++i)
{
test_and_set_bit(i, bootmem_data.bitmap);
}
void reserve_kernel_pages()
{
- reserve_bootmem(pfn2inx(PFN_DW(va2pa(&kernel_begin))), pfn2inx(PFN_UP(va2pa(&kernel_end))));
+ //reserve_bootmem(PFN_DW(va2pa(&kernel_begin)), PFN_UP(va2pa(&kernel_end)));
+ reserve_bootmem(0, PFN_UP(va2pa(&kernel_end)));
}
void reserve_bootmem_pages()
{
unsigned long bgn_pfn = PFN_DW(va2pa(bootmem_data.bitmap));
- unsigned long end_pfn = bgn_pfn;
-
- end_pfn += PFN_UP(bootmem_data.mapsize);
+ unsigned long end_pfn = bgn_pfn + PFN_UP(bootmem_data.mapsize);
- reserve_bootmem(pfn2inx(bgn_pfn), pfn2inx(end_pfn));
+ reserve_bootmem(bgn_pfn, end_pfn);
}
void init_bootmem_allocator()
{
- int mapsize = (bootmem_data.max_pfn - bootmem_data.min_pfn + 7) / 8;
+ int mapsize = (bootmem_data.max_pfn + 7) / 8;
bootmem_data.bitmap = &kernel_end;
bootmem_data.mapsize= mapsize;
#endif
}
-unsigned long align_bootmem_index(unsigned long inx, unsigned long align)
-{
- unsigned long min_pfn = bootmem_data.min_pfn;
- unsigned long aln_pfn = ALIGN(min_pfn + inx, align);
-
- return aln_pfn - min_pfn;
-}
-
-unsigned long align_bootmem_offset(unsigned long offset, unsigned long align)
-{
- unsigned long base = pfn2pa(bootmem_data.min_pfn);
-
- return ALIGN(base + offset, align) - base;
-}
-
void *alloc_bootmem(unsigned long size, unsigned long align)
{
bootmem_data_t *pbd = &bootmem_data;
assert((align & (align-1)) == 0); // must be power of 2
unsigned long fallback = 0;
- unsigned long bgn_inx, end_inx, step;
+ unsigned long bgn_pfn, end_pfn, step;
step = align >> 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; i<search_end_inx; ++i)
+ for(i=bgn_pfn; i<search_end_pfn; ++i)
{
if(constant_test_bit(i, pbd->bitmap) != 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);
if(fallback)
{
- bgn_inx = align_bootmem_index(fallback-1, step);
+ bgn_pfn = ALIGN(fallback-1, step);
fallback = 0;
goto find_block;
}
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<fa.mapSize; i++)
- printk("%x ", fa.map[i]);
- printk("++++ %d ++++", freeArea[i].count);
- printk(" #\n");
-}
-void setup_mm()
-{
- u32 mm_size = system.mm_size;
- if(mm_size > 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
#define add_page2list(page, order) \
list_add(&page->list, &freeArea[order].freeList)
+FreeArea freeArea[MAX_ORDER];
+
#if 1
void do_no_page(void *addr)
{
{
extern char _start, _end;
- printk("kernel:\t%08x - %08x\n", &_start, &_end);
+ printk("kernel: %08x - %08x\n", &_start, &_end);
init_mm();