--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: bug.h
+ * Author: Zhao Yanbai
+ * Sat Apr 5 14:51:50 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#define BUG() do { \
+ printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+ panic("BUG!"); \
+} while (0)
+
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: kernel.h
+ * Author: Zhao Yanbai
+ * Sat Apr 5 14:52:06 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include <system.h>
+#include <bug.h>
INIT_LIST_HEAD(entry);
}
-static inline int list_is_empty(list_head_t *head)
+static inline int list_empty(list_head_t *head)
{
return head->next == head;
}
#define va2pfn(addr) pa2pfn(va2pa(addr))
#define pfn2va(pfn) pa2va(pfn2pa(pfn))
+#define valid_va(addr) ((addr) >= PAGE_OFFSET)
#define PFN_UP(addr) (((addr) + PAGE_SIZE - 1) >> PAGE_SHIFT)
#define PFN_DW(addr) ((addr) >> PAGE_SHIFT)
list_head_t free_list;
} free_area_t;
+
+unsigned long alloc_pages(unsigned int gfp_mask, unsigned int order);
+void free_pages(unsigned long addr, unsigned int order);
+
// TODO Remove
typedef struct page_
{
} FreeArea, *pFreeArea;
-pPage alloc_pages(unsigned int order);
-void free_pages(pPage page);
+pPage old_alloc_pages(unsigned int order);
+void old_free_pages(pPage page);
//void free_pages(pPage page, unsigned int order);
void disp_free_area();
--- /dev/null
+/*
+ * ------------------------------------------------------------------------
+ * File Name: sysctl.h
+ * Author: Zhao Yanbai
+ * Sat Apr 5 14:51:53 2014
+ * Description: none
+ * ------------------------------------------------------------------------
+ */
+
+#pragma once
+
+#include <kernel.h>
#include "types.h"
#include "printk.h"
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
void *kmalloc(size_t size);
void kfree(void *p);
printString(pkbuf,0x2);
return 0;
}
-
}
-inline void panic(char *msg)
+void panic(char *msg)
{
printk("PANIC:\"%s\" file:%s function:%s line:%d\n",
msg, __FILE__, __FUNCTION__, __LINE__);
* ------------------------------------------------------------------------
*/
#include <mm.h>
+#include <sysctl.h>
-#define MAX_ORDER 10
+#define MAX_ORDER 5
struct buddy_system
{
page_t *page_map;
- free_area_t free_area[MAX_ORDER + 1];
+ free_area_t free_area[MAX_ORDER];
};
struct buddy_system buddy_system;
return 0;
}
+#define va2page(addr) (buddy_system.page_map + va2pfn(addr))
+#define page2va(page) (pfn2va((page) - buddy_system.page_map))
+
+page_t *__alloc_pages(unsigned int order)
+{
+ //
+ page_t *page = 0;
+ page_t *buddy= 0;
+ free_area_t *area;
+ unsigned long size;
+ unsigned int select_order;
+ for(select_order=order; select_order<MAX_ORDER; ++select_order)
+ {
+ area = buddy_system.free_area + select_order;
+ if(!list_empty(&(area->free_list)))
+ {
+ goto found;
+ }
+ }
+
+ return 0;
+
+found:
+ page = list_entry(area->free_list.next, page_t, lru);
+ list_del(&(page->lru));
+ ClearPagePrivate(page);
+ page->private = 0;
+ area->free_count--;
+
+ while(select_order > order)
+ {
+ area--;
+ select_order--;
+ size = 1UL << select_order;
+
+ buddy = page + size;
+ list_add(&(page->lru), &(area->free_list));
+ area->free_count++;
+ buddy->private = select_order;
+ SetPagePrivate(buddy);
+ }
+
+ return page;
+}
+
+unsigned long alloc_pages(unsigned int gfp_mask, unsigned int order)
+{
+ // gfp_mask
+ // ...
+
+ page_t *page = __alloc_pages(order);
+
+ return (unsigned long) page2va(page);
+}
+
void __free_pages(page_t *page, unsigned int order)
{
if(order > MAX_ORDER)
page_t *buddy = 0;
page_t *base = buddy_system.page_map;
unsigned long page_inx = page - base;
- while(order < MAX_ORDER)
+ while(order < (MAX_ORDER-1))
{
unsigned long buddy_inx = page_inx ^ (1UL << order);
buddy = base + buddy_inx;
buddy_system.free_area[order].free_count++;
}
+
+void free_pages(unsigned long addr, unsigned int order)
+{
+ if(!valid_va(addr))
+ {
+ BUG_ON(!valid_va(addr));
+ }
+
+ __free_pages(va2page(addr), order);
+}
+
void dump_buddy_system()
{
unsigned long i;
- for(i=0; i<MAX_ORDER+1; ++i)
+ for(i=0; i<MAX_ORDER; ++i)
{
printk("order %2d free_count %d ", i, buddy_system.free_area[i].free_count);
printk("\n");
}
+
+ printk("alloc 1 pages va 0x%08x\n", alloc_pages(0, 0));
+ printk("alloc 1 pages va 0x%08x\n", alloc_pages(0, 0));
+ printk("alloc 2 pages va 0x%08x\n", alloc_pages(0, 1));
+ printk("alloc 4 pages va 0x%08x\n", alloc_pages(0, 2));
+ printk("alloc 8 pages va 0x%08x\n", alloc_pages(0, 3));
+
}
void init_buddy_system()
// init free area
memset(&buddy_system, 0, sizeof(buddy_system));
- for(i=0; i<MAX_ORDER+1; ++i)
+ for(i=0; i<MAX_ORDER; ++i)
{
INIT_LIST_HEAD(&(buddy_system.free_area[i].free_list));
}
assert(0<size && size<=32*PAGE_SIZE);
int order = get_order(size);
void *p;
- pPage page = alloc_pages(order);
+ pPage page = old_alloc_pages(order);
if(page == NULL)
return NULL;
//printk("kfree:%08x %08x %08x ", p, va2pa(p));
page += ((unsigned long)va2pa(p)>>PAGE_SHIFT);
//printk("%08x\n", page->mapNR);
- free_pages(page);
+ old_free_pages(page);
}
load_cr3(current);
}
-inline pPage __alloc_pages(unsigned int order, unsigned int alloc_order)
+inline pPage __old_alloc_pages(unsigned int order, unsigned int alloc_order)
{
assert(0 <= order && order<MAX_OLD_ORDER);
- assert(!list_is_empty(&freeArea[order].freeList));
+ assert(!list_empty(&freeArea[order].freeList));
assert(alloc_order <= order);
pListHead pl = freeArea[order].freeList.next;
add_page2list(page, order-1);
//int j=2000000;while(j--);
- return __alloc_pages(order-1, alloc_order);
+ return __old_alloc_pages(order-1, alloc_order);
}
-pPage alloc_pages(unsigned int order)
+pPage old_alloc_pages(unsigned int order)
{
if(order<0 || order>=MAX_OLD_ORDER)
return NULL;
int i;
for(i=order; i<MAX_OLD_ORDER; i++)
{
- if(list_is_empty(&freeArea[i].freeList))
+ if(list_empty(&freeArea[i].freeList))
continue;
- return __alloc_pages(i, order);
+ return __old_alloc_pages(i, order);
}
return NULL;
}
return NULL;
}
-void free_pages(pPage page)
+void old_free_pages(pPage page)
{
assert(page != NULL);
unsigned int order = page->order;
panic("bug");
}
#endif
- free_pages(page);
+ old_free_pages(page);
}
}
#else
-inline pPage __alloc_pages(unsigned int order, unsigned int alloc_order)
+inline pPage __old_alloc_pages(unsigned int order, unsigned int alloc_order)
{
assert(0 <= order && order<MAX_OLD_ORDER);
- assert(!list_is_empty(&freeArea[order].freeList));
+ assert(!list_empty(&freeArea[order].freeList));
assert(alloc_order <= order);
pListHead pl = freeArea[order].freeList.next;
pg += (1 << (order-1));
list_add(&pg->list, &freeArea[order-1].freeList);
- return __alloc_pages(order-1, alloc_order);
+ return __old_alloc_pages(order-1, alloc_order);
}
-pPage alloc_pages(unsigned int order)
+pPage old_alloc_pages(unsigned int order)
{
if(order >= MAX_OLD_ORDER)
return NULL;
int i;
for(i=order; i<MAX_OLD_ORDER; i++)
{
- if(list_is_empty(&freeArea[i].freeList))
+ if(list_empty(&freeArea[i].freeList))
continue;
- return __alloc_pages(i, order);
+ return __old_alloc_pages(i, order);
}
return NULL;
}
-void free_pages(pPage page, unsigned int order)
+void old_free_pages(pPage page, unsigned int order)
{
assert(0<=order && order<MAX_OLD_ORDER);
assert(page != NULL);