#include <page.h>
+#define BOOTMEM_PAGE_FREE 0
+#define BOOTMEM_PAGE_USED 1
+
void *alloc_bootmem(unsigned long size, unsigned long align);
+unsigned long bootmem_total_pages();
+unsigned long bootmem_page_state(unsigned long pfn);
#define bootmem_alloc_pages(n) alloc_bootmem((n)*PAGE_SIZE, PAGE_SIZE)
-
#define LOAD_CR3(pde) asm("movl %%edx, %%cr3"::"d"(va2pa(pde)))
-#define MAX_ORDER (11)
+#define MAX_OLD_ORDER (11)
typedef struct page
{
-
-
+ unsigned long index;
} page_t;
+typedef struct free_area
+{
+ unsigned long count;
+} free_area_t;
+
// TODO Remove
typedef struct page_
{
*/
#include <mm.h>
+#define MAX_ORDER 4
+struct buddy_system
+{
+ page_t **page_map;
+ free_area_t free_area[MAX_ORDER + 1];
+};
+
+struct buddy_system buddy_system;
+
void init_buddy_system()
{
+ unsigned long pfn_cnt = bootmem_total_pages();
+
+ buddy_system.page_map = alloc_bootmem(pfn_cnt*sizeof(page_t*), sizeof(page_t*));
+ if(0 == buddy_system.page_map) {
+ printk("can not go on playing...\n");
+ while(1);
+ }
+ unsigned long i;
+ for(i=0; i<pfn_cnt; ++i)
+ {
+ buddy_system.page_map[i] = alloc_bootmem(sizeof(page_t), sizeof(unsigned long));
+ if(0 == buddy_system.page_map[i]) {
+ printk("can not go on playing...\n");
+ while(1);
+ }
+ }
+ for(i=0; i<pfn_cnt; ++i)
+ {
+ if(BOOTMEM_PAGE_FREE == bootmem_page_state(i))
+ {
+ // free to buddy system
+ }
+
+ buddy_system.page_map[i]->index = i;
+ }
}
//printk(" %08x\n", size);
int i;
int n = size>>PAGE_SHIFT;
- for(i=0; i<MAX_ORDER; i++)
+ for(i=0; i<MAX_OLD_ORDER; i++)
{
if(n<=(1UL<<i))
break;
extern char kernel_begin, kernel_end;
extern char etext,edata,end;
+extern void init_buddy_system();
static void e820_print_type(unsigned long type)
{
}
}
-
typedef struct bootmem_data {
unsigned long min_pfn;
unsigned long max_pfn;
unsigned long mapsize;
} bootmem_data_t;
+
bootmem_data_t bootmem_data;
+unsigned long bootmem_total_pages()
+{
+ return bootmem_data.max_pfn;
+}
+unsigned long bootmem_page_state(unsigned long pfn)
+{
+ return constant_test_bit(pfn, bootmem_data.bitmap);
+}
void e820_init_bootmem_data()
{
if(p->type != E820_RAM)
continue;
- bgn_pfn = pa2pfn(p->addr);
- end_pfn = pa2pfn(p->addr + p->size);
+ bgn_pfn = PFN_UP(p->addr);
+ end_pfn = PFN_DW(p->addr + p->size);
if(bootmem_data.max_pfn < end_pfn)
bootmem_data.max_pfn = end_pfn;
bootmem_data.min_pfn = 0;
// limit max_pfn
- unsigned long max_support_pfn = pa2pfn(MAX_SUPT_PHYMM_SIZE);
+ unsigned long max_support_pfn = PFN_DW(MAX_SUPT_PHYMM_SIZE);
if(bootmem_data.max_pfn > max_support_pfn)
{
bootmem_data.max_pfn = max_support_pfn;
test_and_clear_bit(j, bootmem_data.bitmap);
}
}
-
}
void reserve_bootmem(unsigned long bgn_pfn, unsigned long end_pfn)
for(i=bgn_pfn; i<search_end_pfn; ++i)
{
- if(constant_test_bit(i, pbd->bitmap) != 0) { // space not enough
+ if(bootmem_page_state(i) != BOOTMEM_PAGE_FREE) { // space not enough
bgn_pfn = ALIGN(i, step);
if(bgn_pfn == i)
bgn_pfn += step;
printk("init global paging...\n");
init_paging();
printk("init buddy system...\n");
+ init_buddy_system();
}
#include <mm.h>
+
#define get_page_from_list(pList) list_entry(pList, Page, list)
#define add_page2list(page, order) \
list_add(&page->list, &freeArea[order].freeList)
-FreeArea freeArea[MAX_ORDER];
+FreeArea freeArea[MAX_OLD_ORDER];
#if 1
void do_no_page(void *addr)
inline pPage __alloc_pages(unsigned int order, unsigned int alloc_order)
{
- assert(0 <= order && order<MAX_ORDER);
+ assert(0 <= order && order<MAX_OLD_ORDER);
assert(!list_is_empty(&freeArea[order].freeList));
assert(alloc_order <= order);
pPage alloc_pages(unsigned int order)
{
- if(order<0 || order>=MAX_ORDER)
+ if(order<0 || order>=MAX_OLD_ORDER)
return NULL;
int i;
- for(i=order; i<MAX_ORDER; i++)
+ for(i=order; i<MAX_OLD_ORDER; i++)
{
if(list_is_empty(&freeArea[i].freeList))
continue;
pPage get_buddy_page(pPage page, unsigned int order)
{
- assert(0<=order && order<MAX_ORDER);
+ assert(0<=order && order<MAX_OLD_ORDER);
assert(page != NULL);
//printk("mapnr: %d order:%d %d\n", page->mapNR, order, 1UL<<order);
{
assert(page != NULL);
unsigned int order = page->order;
- assert(0<=order && order<MAX_ORDER);
+ assert(0<=order && order<MAX_OLD_ORDER);
// buddy page
//printk("<%d %d>", bpage->mapNR, bpage->order);
- if(bpage == NULL || order == MAX_ORDER-1)
+ if(bpage == NULL || order == MAX_OLD_ORDER-1)
{
add_page2list(page, order);
}
inline pPage __alloc_pages(unsigned int order, unsigned int alloc_order)
{
- assert(0 <= order && order<MAX_ORDER);
+ assert(0 <= order && order<MAX_OLD_ORDER);
assert(!list_is_empty(&freeArea[order].freeList));
assert(alloc_order <= order);
pPage alloc_pages(unsigned int order)
{
- if(order >= MAX_ORDER)
+ if(order >= MAX_OLD_ORDER)
return NULL;
int i;
- for(i=order; i<MAX_ORDER; i++)
+ for(i=order; i<MAX_OLD_ORDER; i++)
{
if(list_is_empty(&freeArea[i].freeList))
continue;
void free_pages(pPage page, unsigned int order)
{
- assert(0<=order && order<MAX_ORDER);
+ assert(0<=order && order<MAX_OLD_ORDER);
assert(page != NULL);
int nr = page->mapNR>>(order+1);
//printk("#########%d %d\n",page->mapNR, variable_test_bit( nr, (unsigned long *)freeArea[order].map));
- if(order == MAX_ORDER -1
+ if(order == MAX_OLD_ORDER -1
|| !variable_test_bit( nr, (unsigned long *)freeArea[order].map))
{
change_bit( nr, (unsigned long *)freeArea[order].map);
void disp_free_area()
{
int i;
- for(i=0; i<MAX_ORDER; i++)
+ for(i=0; i<MAX_OLD_ORDER; i++)
{
pListHead pos,tmp;
int count = 0;
/*
*--------------------------------------------------------------------------
- * File Name: link.ld
+ * File Name: link.ld
*
* Description: Link All Object Files to KERNEL ...
*
*
- * Author: Zhao Yanbai [zhaoyanbai@126.com]
+ * Author: Zhao Yanbai [zhaoyanbai@126.com]
*
- * Version: 1.1
+ * Version: 1.1
* Create Date: Mon Mar 2 12:21:03 2009
* Last Update: Mon Mar 2 12:21:03 2009
*
kernel_begin = kernel_virtual_addr_start + kernel_loaded_physic_addr;
SECTIONS
{
- . = kernel_begin;
- .text : AT(phys_addr) ALIGN(0x1000)
- {
- code = .;
+ . = kernel_begin;
+ .text : AT(phys_addr) ALIGN(0x1000)
+ {
+ code = .;
phys_addr = . - kernel_virtual_addr_start;
*(.multiboot_header)
- *(.text)
- }
- etext = .;
- .data : AT(phys_addr) ALIGN(0x1000)
- {
- data = .;
+ *(.text)
+ }
+ etext = .;
+ .data : AT(phys_addr) ALIGN(0x1000)
+ {
+ data = .;
phys_addr = . - kernel_virtual_addr_start;
- *(.data)
- }
- edata = .;
- .bss : AT(phys_addr) ALIGN(0x1000)
- {
- bss = .;
+ *(.data)
+ }
+ edata = .;
+ .bss : AT(phys_addr) ALIGN(0x1000)
+ {
+ bss = .;
phys_addr = . - kernel_virtual_addr_start;
- *(.bss);
- }
+ *(.bss);
+ }
ebss = .;
}
- end = .;
- _end = .;
- kernel_end = (end + 0x1000 - 1) & ~ (0x1000 -1);
+ end = .;
+ _end = .;
+ kernel_end = (end + 0x1000 - 1) & ~ (0x1000 -1);
}
void setup_kernel()
{
- extern char _start, _end;
+ extern char kernel_begin, kernel_end;
- printk("kernel: %08x - %08x\n", &_start, &_end);
+ printk("kernel: %08x - %08x\n", &kernel_begin, &kernel_end);
init_mm();