From 5c9109c5b5e5d3c7c9c23cd076321e53339c9e97 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Sun, 4 Apr 2021 00:26:52 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E2=9C=A8=20outline=20for=20startup=20alloc?= =?UTF-8?q?=20(with=20test)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/include/cfg.h | 7 +- impl-c/include/mem.h | 2 +- impl-c/include/mm/frame.h | 3 + impl-c/include/mm/startAlloc.h | 26 +++++++ impl-c/include/test.h | 33 +++++++++ impl-c/kernel/main.c | 52 ++++++++------ impl-c/kernel/test.c | 5 ++ impl-c/mm/startup_alloc.c | 123 +++++++++++++++++++++++++++++++++ 8 files changed, 227 insertions(+), 24 deletions(-) create mode 100644 impl-c/include/mm/frame.h create mode 100644 impl-c/include/mm/startAlloc.h create mode 100644 impl-c/include/test.h create mode 100644 impl-c/kernel/test.c create mode 100644 impl-c/mm/startup_alloc.c diff --git a/impl-c/include/cfg.h b/impl-c/include/cfg.h index 64d32d60b..3c26f2292 100644 --- a/impl-c/include/cfg.h +++ b/impl-c/include/cfg.h @@ -1,3 +1,8 @@ #pragma once -#define CFG_LOG_ENABLE 0 \ No newline at end of file +#define CFG_LOG_ENABLE 0 + +#define CFG_RUN_TEST + +// memory management +#define CFG_RUN_STATUP_ALLOC_TEST \ No newline at end of file diff --git a/impl-c/include/mem.h b/impl-c/include/mem.h index 8752e321a..5edaa32f1 100644 --- a/impl-c/include/mem.h +++ b/impl-c/include/mem.h @@ -1,11 +1,11 @@ #pragma once #include "list.h" +#include "mm/frame.h" #include // #define BUDDY_MAX_EXPONENT 17 // 512Mb #define BUDDY_MAX_EXPONENT 10 -#define FRAME_SHIFT 14 // 4Kb #define BUDDY_NUM_FREE_LISTS (BUDDY_MAX_EXPONENT + 1) diff --git a/impl-c/include/mm/frame.h b/impl-c/include/mm/frame.h new file mode 100644 index 000000000..5f370179c --- /dev/null +++ b/impl-c/include/mm/frame.h @@ -0,0 +1,3 @@ +#pragma once +#define FRAME_SHIFT 14 // 4Kb +#define FRAME_ADDR_BASE (1 << FRAME_SHIFT) diff --git a/impl-c/include/mm/startAlloc.h b/impl-c/include/mm/startAlloc.h new file mode 100644 index 000000000..025d08c08 --- /dev/null +++ b/impl-c/include/mm/startAlloc.h @@ -0,0 +1,26 @@ +#pragma once +#include "bool.h" +#include "cfg.h" +#include "test.h" + +#define STARTUP_MAX_RESERVE_COUNT 10 +// Area reserved by startup allocator +typedef struct ReservedArea { + void *addr; + unsigned long size; +} ReservedArea; + +typedef struct StartupAllocator { + int num_reserved; + int max_reserved; + struct ReservedArea *_reserved; +} StartupAllocator; + +struct ReservedArea ReservedAreas[STARTUP_MAX_RESERVE_COUNT]; + +void StartupAllocator_init(StartupAllocator *sa, struct ReservedArea *reserved, + int max_reserved_count); + +bool reserveMemory(StartupAllocator *sa, void *addr, unsigned long size); + +void test_startup_alloc(); \ No newline at end of file diff --git a/impl-c/include/test.h b/impl-c/include/test.h new file mode 100644 index 000000000..a863665dd --- /dev/null +++ b/impl-c/include/test.h @@ -0,0 +1,33 @@ +#pragma once + +#include "bool.h" +#include "uart.h" + +#define TEST_FAILED(name, description) \ + { uart_println("\033[0;31m[TEST][ERR] %s: %s\033[0m", name, description); } + +#define TEST_SUCCESS(name, description) \ + { uart_println("\033[0;32m[TEST][OK] %s: %s\033[0m", name, description); } + +#define TEST1(test, name, desc) \ + { \ + if (test() == true) { \ + TEST_SUCCESS(name, desc); \ + } else { \ + TEST_FAILED(name, desc); \ + } \ + } + +static inline void unittest(int (*f)(), char *s, char *de) { TEST1(f, s, de); } + +// Return false once the condition does not meet +#define assert(cond) \ + { \ + if (!(cond)) { \ + return false; \ + } \ + } + +void run_tests(); + +void test_suite_startup_alloc(); \ No newline at end of file diff --git a/impl-c/kernel/main.c b/impl-c/kernel/main.c index aab1a8941..21981343b 100644 --- a/impl-c/kernel/main.c +++ b/impl-c/kernel/main.c @@ -1,38 +1,46 @@ +#include "cfg.h" #include "mem.h" #include "shell.h" +#include "test.h" #include "uart.h" int main() { uart_init(); uart_println("uart initialized"); - KAllocManager_init(); + +#ifdef CFG_RUN_TEST + run_tests(); +#endif + + // KAllocManager_init(); // KAllocManager_show_status(); - uart_println("-------------------------------"); - uart_println(" Operating System Capstone 2021"); - uart_println("-------------------------------"); + // void *a[30]; + // for (int i = 0; i < 5; i++) { + // a[i] = kalloc(8192); + // uart_println("i:%d, a: %x", i, a[i]); + // } - void *a[30]; - for (int i = 0; i < 5; i++) { - a[i] = kalloc(8192); - uart_println("i:%d, a: %x", i, a[i]); - } + // for (int i = 0; i < 5; i++) { + // kfree(a[i]); + // } - for (int i = 0; i < 5; i++) { - kfree(a[i]); - } + // for (int i = 0; i < 5; i++) { + // a[i] = kalloc(13); + // uart_println("i:%d, a: %x", i, a[i]); + // }; + // if (a[0] == a[1]) { + // uart_println("nooo"); + // } + // for (int i = 0; i < 5; i++) { + // kfree(a[i]); + // } - for (int i = 0; i < 5; i++) { - a[i] = kalloc(13); - uart_println("i:%d, a: %x", i, a[i]); - }; - if (a[0] == a[1]) { - uart_println("nooo"); - } - for (int i = 0; i < 5; i++) { - kfree(a[i]); - } + uart_println("-------------------------------"); + uart_println(" Operating System Capstone 2021"); + uart_println("-------------------------------"); uart_println(" input filename to see file content"); + while (1) { shellPrintPrompt(); shellInputLine(); diff --git a/impl-c/kernel/test.c b/impl-c/kernel/test.c new file mode 100644 index 000000000..46d7118ab --- /dev/null +++ b/impl-c/kernel/test.c @@ -0,0 +1,5 @@ +#include "test.h" +#include "cfg.h" +#include "mm/startAlloc.h" + +void run_tests() { test_startup_alloc(); } \ No newline at end of file diff --git a/impl-c/mm/startup_alloc.c b/impl-c/mm/startup_alloc.c new file mode 100644 index 000000000..57c6e883b --- /dev/null +++ b/impl-c/mm/startup_alloc.c @@ -0,0 +1,123 @@ +#include "cfg.h" +#include "mm/frame.h" +#include "mm/startAlloc.h" +#include "test.h" +#include "uart.h" + +// Mask for address inside frame +#define FRAME_MASK ((1 << FRAME_SHIFT) - 1) + +bool is_overlap(ReservedArea *a1, ReservedArea *a2); + +bool is_overlap(ReservedArea *a1, ReservedArea *a2) { + ReservedArea *low, *high; + low = a1->addr < a2->addr ? a1 : a2; + high = a1->addr < a2->addr ? a2 : a1; + unsigned long low_end = (unsigned long)low->addr + low->size; + return low_end > ((unsigned long)high->addr); +} + +void sort_reserved(StartupAllocator *sa) { + // simple bubble sort + for (int i = 0; i < sa->max_reserved; i++) { + for (int j = i + 1; j < sa->max_reserved; j++) { + int k = 0; + k++; + } + } +} + +void StartupAllocator_init(StartupAllocator *sa, struct ReservedArea *reserved, + int max_reserved_count) { + sa->max_reserved = max_reserved_count; + sa->num_reserved = 0; + sa->_reserved = reserved; + for (int i = 0; i < sa->max_reserved; i++) { + sa->_reserved[i].addr = 0; + sa->_reserved[i].size = 0; + } +} + +bool reserveMemory(StartupAllocator *sa, void *addr, unsigned long size) { + if (((unsigned long long)addr & FRAME_MASK) != 0 || + (size & FRAME_MASK) != 0) { + return false; + } + if (sa->num_reserved >= sa->max_reserved) { + return false; + } + ReservedArea requested = {.addr = addr, .size = size}; + // Should not overlapped with space that reserved already + for (int i = 0; i < sa->num_reserved; i++) { + if (is_overlap(&requested, &sa->_reserved[i])) { + return false; + } + } + sa->_reserved[sa->num_reserved] = requested; + sa->num_reserved += 1; + return true; +} + +#ifdef CFG_RUN_STATUP_ALLOC_TEST +bool test_is_overlap() { + ReservedArea a1 = {.addr = (void *)0, .size = 13}; + ReservedArea a2 = {.addr = (void *)20, .size = 5}; + uart_println("case: not overlap"); + assert(is_overlap(&a1, &a2) == false); + + ReservedArea a3 = {.addr = (void *)0, .size = 13}; + ReservedArea a4 = {.addr = (void *)2, .size = 5}; + uart_println("case: range include"); + assert(is_overlap(&a3, &a4) == true); + + ReservedArea a5 = {.addr = (void *)0, .size = 13}; + ReservedArea a6 = {.addr = (void *)2, .size = 5}; + uart_println("case: partial overlap"); + assert(is_overlap(&a5, &a6) == true); + return true; +}; + +bool test_startup_alloc_init() { + StartupAllocator a; + struct ReservedArea reservd[5]; + reservd[3].size = 1 << 3; + StartupAllocator_init(&a, reservd, 5); + assert(a.max_reserved == 5); + assert(a.num_reserved == 0); + assert(reservd[3].size == 0); + return true; +} + +bool test_reserveMemory() { + StartupAllocator a; + struct ReservedArea reservd[5]; + StartupAllocator_init(&a, reservd, 5); + + void *start = (void *)(2 * FRAME_ADDR_BASE); + unsigned long size = (3 * FRAME_ADDR_BASE); + reserveMemory(&a, start, size); + assert(a.num_reserved == 1); + assert(a._reserved[0].addr == start); + + void *not_aligned_start = (void *)(2 * FRAME_ADDR_BASE - 1); + unsigned long not_aligned_size = size - 87; + uart_println("case: start addr not page aligned"); + assert(reserveMemory(&a, not_aligned_start, size) == false); + uart_println("case: reserve size not page aligned"); + assert(reserveMemory(&a, start, not_aligned_size) == false); + + void *overlap_start = (void *)(2 * FRAME_ADDR_BASE); + uart_println("case: overlap mem"); + assert(reserveMemory(&a, overlap_start, size) == false); + + return true; +} +#endif + +void test_startup_alloc() { +#ifdef CFG_RUN_STATUP_ALLOC_TEST + unittest(test_is_overlap, "starup_alloc", "is_overlap"); + unittest(test_startup_alloc_init, "starup_alloc", "init"); + unittest(test_reserveMemory, "starup_alloc", "reserveMemory"); +#endif +} \ No newline at end of file From 42674d965ac514d0c6ca75404c558cb40c2e79ea Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Sun, 4 Apr 2021 00:42:03 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E2=9C=85=20sort=20reserve?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/mm/startup_alloc.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/impl-c/mm/startup_alloc.c b/impl-c/mm/startup_alloc.c index 57c6e883b..f8d53aebf 100644 --- a/impl-c/mm/startup_alloc.c +++ b/impl-c/mm/startup_alloc.c @@ -17,12 +17,16 @@ bool is_overlap(ReservedArea *a1, ReservedArea *a2) { return low_end > ((unsigned long)high->addr); } -void sort_reserved(StartupAllocator *sa) { +void sort_reserved_area(StartupAllocator *sa) { // simple bubble sort - for (int i = 0; i < sa->max_reserved; i++) { - for (int j = i + 1; j < sa->max_reserved; j++) { - int k = 0; - k++; + ReservedArea tmpArea; + for (int i = 0; i < sa->num_reserved; i++) { + for (int j = i + 1; j < sa->num_reserved; j++) { + if (sa->_reserved[i].addr < sa->_reserved[j].addr) { + tmpArea = sa->_reserved[i]; + sa->_reserved[i] = sa->_reserved[j]; + sa->_reserved[j] = tmpArea; + } } } } @@ -59,6 +63,7 @@ bool reserveMemory(StartupAllocator *sa, void *addr, unsigned long size) { } #ifdef CFG_RUN_STATUP_ALLOC_TEST + bool test_is_overlap() { ReservedArea a1 = {.addr = (void *)0, .size = 13}; ReservedArea a2 = {.addr = (void *)20, .size = 5}; @@ -77,6 +82,23 @@ bool test_is_overlap() { return true; }; +bool test_sort_reserve_area() { + StartupAllocator sa; + struct ReservedArea reservd[5]; + struct ReservedArea a1 = {.addr = (void *)4, .size = 2}; + struct ReservedArea a2 = {.addr = (void *)99, .size = 2}; + StartupAllocator_init(&sa, reservd, 5); + sa._reserved[0] = a1; + sa._reserved[1] = a2; + sa.num_reserved = 2; + sort_reserved_area(&sa); + assert(sa._reserved[0].addr == a2.addr); + assert(sa._reserved[0].size == a2.size); + assert(sa._reserved[1].addr == a1.addr); + assert(sa._reserved[1].size == a1.size); + return true; +}; + bool test_startup_alloc_init() { StartupAllocator a; struct ReservedArea reservd[5]; @@ -119,5 +141,6 @@ void test_startup_alloc() { unittest(test_is_overlap, "starup_alloc", "is_overlap"); unittest(test_startup_alloc_init, "starup_alloc", "init"); unittest(test_reserveMemory, "starup_alloc", "reserveMemory"); + unittest(test_sort_reserve_area, "starup_alloc", "sort_reserve"); #endif } \ No newline at end of file From d294773cd2d1603a97fe3d4cfe21fb0639a272b6 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Sun, 4 Apr 2021 01:48:47 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=F0=9F=8E=A8=20=F0=9F=9A=9A=20startup=20all?= =?UTF-8?q?ocator=20public=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/include/mm/startAlloc.h | 26 ----- impl-c/include/mm/startup.h | 32 ++++++ impl-c/kernel/main.c | 1 + impl-c/kernel/test.c | 2 +- impl-c/mm/startup.c | 176 +++++++++++++++++++++++++++++++++ impl-c/mm/startup_alloc.c | 146 --------------------------- 6 files changed, 210 insertions(+), 173 deletions(-) delete mode 100644 impl-c/include/mm/startAlloc.h create mode 100644 impl-c/include/mm/startup.h create mode 100644 impl-c/mm/startup.c delete mode 100644 impl-c/mm/startup_alloc.c diff --git a/impl-c/include/mm/startAlloc.h b/impl-c/include/mm/startAlloc.h deleted file mode 100644 index 025d08c08..000000000 --- a/impl-c/include/mm/startAlloc.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include "bool.h" -#include "cfg.h" -#include "test.h" - -#define STARTUP_MAX_RESERVE_COUNT 10 -// Area reserved by startup allocator -typedef struct ReservedArea { - void *addr; - unsigned long size; -} ReservedArea; - -typedef struct StartupAllocator { - int num_reserved; - int max_reserved; - struct ReservedArea *_reserved; -} StartupAllocator; - -struct ReservedArea ReservedAreas[STARTUP_MAX_RESERVE_COUNT]; - -void StartupAllocator_init(StartupAllocator *sa, struct ReservedArea *reserved, - int max_reserved_count); - -bool reserveMemory(StartupAllocator *sa, void *addr, unsigned long size); - -void test_startup_alloc(); \ No newline at end of file diff --git a/impl-c/include/mm/startup.h b/impl-c/include/mm/startup.h new file mode 100644 index 000000000..74d9a3ad0 --- /dev/null +++ b/impl-c/include/mm/startup.h @@ -0,0 +1,32 @@ +#pragma once +#include "bool.h" +#include "cfg.h" +#include "test.h" + +#define STARTUP_MAX_RESERVE_COUNT 10 + +typedef struct MemRegion { + void *addr; + unsigned long size; +} MemRegion; + +typedef struct StartupAllocator { + int num_reserved; + int max_reserved; + struct MemRegion *_reserved; +} StartupAllocator_t; + +struct MemRegion ReservedRegions[STARTUP_MAX_RESERVE_COUNT]; +StartupAllocator_t StartupAlloc; + +// Public api: Initialize the starup allocator module +void startup_init(); + +// Request StartupAllocator to allocate a space +// void *startup_alloc(unsigned long size); + +// Reqeust StartupAllocator to reserve an area +bool startup_reserve(void *addr, unsigned long size); + +// Only used for running tests +void test_startup_alloc(); \ No newline at end of file diff --git a/impl-c/kernel/main.c b/impl-c/kernel/main.c index 21981343b..f27affee8 100644 --- a/impl-c/kernel/main.c +++ b/impl-c/kernel/main.c @@ -1,5 +1,6 @@ #include "cfg.h" #include "mem.h" +#include "mm/startup.h" #include "shell.h" #include "test.h" #include "uart.h" diff --git a/impl-c/kernel/test.c b/impl-c/kernel/test.c index 46d7118ab..91fe6d256 100644 --- a/impl-c/kernel/test.c +++ b/impl-c/kernel/test.c @@ -1,5 +1,5 @@ #include "test.h" #include "cfg.h" -#include "mm/startAlloc.h" +#include "mm/startup.h" void run_tests() { test_startup_alloc(); } \ No newline at end of file diff --git a/impl-c/mm/startup.c b/impl-c/mm/startup.c new file mode 100644 index 000000000..577788481 --- /dev/null +++ b/impl-c/mm/startup.c @@ -0,0 +1,176 @@ + +#include "cfg.h" +#include "test.h" +#include "uart.h" + +#include "mm/frame.h" +#include "mm/startup.h" + +#include + +// Mask for address inside frame +#define FRAME_MASK ((1 << FRAME_SHIFT) - 1) + +static bool is_overlap(MemRegion *a1, MemRegion *a2); +static void sa_init(StartupAllocator_t *sa, struct MemRegion *reserved, + int max_reserved_count); +// static void *sa_alloc(StartupAllocator_t *sa, unsigned long size); +static bool sa_reserve(StartupAllocator_t *sa, void *addr, unsigned long size); + +void startup_init() { + sa_init(&StartupAlloc, ReservedRegions, STARTUP_MAX_RESERVE_COUNT); +} +bool startup_reserve(void *addr, unsigned long size) { + return sa_reserve(&StartupAlloc, addr, size); +} + +// void *startup_alloc(unsigned long size) { +// return sa_alloc(&StartupAlloc, size); +// } + +// If two meory region is overlap +bool is_overlap(MemRegion *a1, MemRegion *a2) { + MemRegion *low, *high; + low = a1->addr < a2->addr ? a1 : a2; + high = a1->addr < a2->addr ? a2 : a1; + unsigned long low_end = (unsigned long)low->addr + low->size; + return low_end > ((unsigned long)high->addr); +} + +// Makesure MemoryRegions is sorted +void sa_sort_reserved(StartupAllocator_t *sa) { + // simple bubble sort + MemRegion tmpArea; + for (int i = 0; i < sa->num_reserved; i++) { + for (int j = i + 1; j < sa->num_reserved; j++) { + if (sa->_reserved[i].addr < sa->_reserved[j].addr) { + tmpArea = sa->_reserved[i]; + sa->_reserved[i] = sa->_reserved[j]; + sa->_reserved[j] = tmpArea; + } + } + } +} + +// Init a StarupAllocator struct +void sa_init(StartupAllocator_t *sa, struct MemRegion *reserved, + int max_reserved_count) { + sa->max_reserved = max_reserved_count; + sa->num_reserved = 0; + sa->_reserved = reserved; + for (int i = 0; i < sa->max_reserved; i++) { + sa->_reserved[i].addr = 0; + sa->_reserved[i].size = 0; + } +} + +// void *sa_alloc(StartupAllocator_t *sa, unsigned long size) { + +// return NULL; +// } + +// Reserve a memory region +bool sa_reserve(StartupAllocator_t *sa, void *addr, unsigned long size) { + if (((unsigned long long)addr & FRAME_MASK) != 0 || + (size & FRAME_MASK) != 0) { + return false; + } + if (sa->num_reserved >= sa->max_reserved) { + return false; + } + MemRegion requested = {.addr = addr, .size = size}; + // Should not overlapped with space that reserved already + for (int i = 0; i < sa->num_reserved; i++) { + if (is_overlap(&requested, &sa->_reserved[i])) { + return false; + } + } + sa->_reserved[sa->num_reserved] = requested; + sa->num_reserved += 1; + sa_sort_reserved(sa); + return true; +} + +//============== TEST START ================= +#ifdef CFG_RUN_STATUP_ALLOC_TEST + +bool test_is_overlap() { + MemRegion a1 = {.addr = (void *)0, .size = 13}; + MemRegion a2 = {.addr = (void *)20, .size = 5}; + uart_println("case: not overlap"); + assert(is_overlap(&a1, &a2) == false); + + MemRegion a3 = {.addr = (void *)0, .size = 13}; + MemRegion a4 = {.addr = (void *)2, .size = 5}; + uart_println("case: range include"); + assert(is_overlap(&a3, &a4) == true); + + MemRegion a5 = {.addr = (void *)0, .size = 13}; + MemRegion a6 = {.addr = (void *)2, .size = 5}; + uart_println("case: partial overlap"); + assert(is_overlap(&a5, &a6) == true); + return true; +}; + +bool test_sa_sort_reserved() { + StartupAllocator_t sa; + struct MemRegion reservd[5]; + struct MemRegion a1 = {.addr = (void *)4, .size = 2}; + struct MemRegion a2 = {.addr = (void *)99, .size = 2}; + sa_init(&sa, reservd, 5); + sa._reserved[0] = a1; + sa._reserved[1] = a2; + sa.num_reserved = 2; + sa_sort_reserved(&sa); + assert(sa._reserved[0].addr == a2.addr); + assert(sa._reserved[0].size == a2.size); + assert(sa._reserved[1].addr == a1.addr); + assert(sa._reserved[1].size == a1.size); + return true; +}; + +bool test_sa_init() { + StartupAllocator_t sa; + struct MemRegion reservd[5]; + reservd[3].size = 1 << 3; + sa_init(&sa, reservd, 5); + assert(sa.max_reserved == 5); + assert(sa.num_reserved == 0); + assert(reservd[3].size == 0); + return true; +} + +bool test_sa_reserve() { + StartupAllocator_t sa; + struct MemRegion reservd[5]; + sa_init(&sa, reservd, 5); + + void *start = (void *)(2 * FRAME_ADDR_BASE); + unsigned long size = (3 * FRAME_ADDR_BASE); + sa_reserve(&sa, start, size); + assert(sa.num_reserved == 1); + assert(sa._reserved[0].addr == start); + + void *not_aligned_start = (void *)(2 * FRAME_ADDR_BASE - 1); + unsigned long not_aligned_size = size - 87; + uart_println("case: start addr not page aligned"); + assert(sa_reserve(&sa, not_aligned_start, size) == false); + uart_println("case: reserve size not page aligned"); + assert(sa_reserve(&sa, start, not_aligned_size) == false); + + void *overlap_start = (void *)(2 * FRAME_ADDR_BASE); + uart_println("case: overlap mem"); + assert(sa_reserve(&sa, overlap_start, size) == false); + + return true; +} +#endif + +void test_startup_alloc() { +#ifdef CFG_RUN_STATUP_ALLOC_TEST + unittest(test_is_overlap, "starup_alloc", "is_overlap"); + unittest(test_sa_init, "starup_alloc", "init"); + unittest(test_sa_reserve, "starup_alloc", "sa_reserve"); + unittest(test_sa_sort_reserved, "starup_alloc", "sort_reserve"); +#endif +} \ No newline at end of file diff --git a/impl-c/mm/startup_alloc.c b/impl-c/mm/startup_alloc.c deleted file mode 100644 index f8d53aebf..000000000 --- a/impl-c/mm/startup_alloc.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "cfg.h" -#include "mm/frame.h" -#include "mm/startAlloc.h" -#include "test.h" -#include "uart.h" - -// Mask for address inside frame -#define FRAME_MASK ((1 << FRAME_SHIFT) - 1) - -bool is_overlap(ReservedArea *a1, ReservedArea *a2); - -bool is_overlap(ReservedArea *a1, ReservedArea *a2) { - ReservedArea *low, *high; - low = a1->addr < a2->addr ? a1 : a2; - high = a1->addr < a2->addr ? a2 : a1; - unsigned long low_end = (unsigned long)low->addr + low->size; - return low_end > ((unsigned long)high->addr); -} - -void sort_reserved_area(StartupAllocator *sa) { - // simple bubble sort - ReservedArea tmpArea; - for (int i = 0; i < sa->num_reserved; i++) { - for (int j = i + 1; j < sa->num_reserved; j++) { - if (sa->_reserved[i].addr < sa->_reserved[j].addr) { - tmpArea = sa->_reserved[i]; - sa->_reserved[i] = sa->_reserved[j]; - sa->_reserved[j] = tmpArea; - } - } - } -} - -void StartupAllocator_init(StartupAllocator *sa, struct ReservedArea *reserved, - int max_reserved_count) { - sa->max_reserved = max_reserved_count; - sa->num_reserved = 0; - sa->_reserved = reserved; - for (int i = 0; i < sa->max_reserved; i++) { - sa->_reserved[i].addr = 0; - sa->_reserved[i].size = 0; - } -} - -bool reserveMemory(StartupAllocator *sa, void *addr, unsigned long size) { - if (((unsigned long long)addr & FRAME_MASK) != 0 || - (size & FRAME_MASK) != 0) { - return false; - } - if (sa->num_reserved >= sa->max_reserved) { - return false; - } - ReservedArea requested = {.addr = addr, .size = size}; - // Should not overlapped with space that reserved already - for (int i = 0; i < sa->num_reserved; i++) { - if (is_overlap(&requested, &sa->_reserved[i])) { - return false; - } - } - sa->_reserved[sa->num_reserved] = requested; - sa->num_reserved += 1; - return true; -} - -#ifdef CFG_RUN_STATUP_ALLOC_TEST - -bool test_is_overlap() { - ReservedArea a1 = {.addr = (void *)0, .size = 13}; - ReservedArea a2 = {.addr = (void *)20, .size = 5}; - uart_println("case: not overlap"); - assert(is_overlap(&a1, &a2) == false); - - ReservedArea a3 = {.addr = (void *)0, .size = 13}; - ReservedArea a4 = {.addr = (void *)2, .size = 5}; - uart_println("case: range include"); - assert(is_overlap(&a3, &a4) == true); - - ReservedArea a5 = {.addr = (void *)0, .size = 13}; - ReservedArea a6 = {.addr = (void *)2, .size = 5}; - uart_println("case: partial overlap"); - assert(is_overlap(&a5, &a6) == true); - return true; -}; - -bool test_sort_reserve_area() { - StartupAllocator sa; - struct ReservedArea reservd[5]; - struct ReservedArea a1 = {.addr = (void *)4, .size = 2}; - struct ReservedArea a2 = {.addr = (void *)99, .size = 2}; - StartupAllocator_init(&sa, reservd, 5); - sa._reserved[0] = a1; - sa._reserved[1] = a2; - sa.num_reserved = 2; - sort_reserved_area(&sa); - assert(sa._reserved[0].addr == a2.addr); - assert(sa._reserved[0].size == a2.size); - assert(sa._reserved[1].addr == a1.addr); - assert(sa._reserved[1].size == a1.size); - return true; -}; - -bool test_startup_alloc_init() { - StartupAllocator a; - struct ReservedArea reservd[5]; - reservd[3].size = 1 << 3; - StartupAllocator_init(&a, reservd, 5); - assert(a.max_reserved == 5); - assert(a.num_reserved == 0); - assert(reservd[3].size == 0); - return true; -} - -bool test_reserveMemory() { - StartupAllocator a; - struct ReservedArea reservd[5]; - StartupAllocator_init(&a, reservd, 5); - - void *start = (void *)(2 * FRAME_ADDR_BASE); - unsigned long size = (3 * FRAME_ADDR_BASE); - reserveMemory(&a, start, size); - assert(a.num_reserved == 1); - assert(a._reserved[0].addr == start); - - void *not_aligned_start = (void *)(2 * FRAME_ADDR_BASE - 1); - unsigned long not_aligned_size = size - 87; - uart_println("case: start addr not page aligned"); - assert(reserveMemory(&a, not_aligned_start, size) == false); - uart_println("case: reserve size not page aligned"); - assert(reserveMemory(&a, start, not_aligned_size) == false); - - void *overlap_start = (void *)(2 * FRAME_ADDR_BASE); - uart_println("case: overlap mem"); - assert(reserveMemory(&a, overlap_start, size) == false); - - return true; -} -#endif - -void test_startup_alloc() { -#ifdef CFG_RUN_STATUP_ALLOC_TEST - unittest(test_is_overlap, "starup_alloc", "is_overlap"); - unittest(test_startup_alloc_init, "starup_alloc", "init"); - unittest(test_reserveMemory, "starup_alloc", "reserveMemory"); - unittest(test_sort_reserve_area, "starup_alloc", "sort_reserve"); -#endif -} \ No newline at end of file From ccbaeb2097f18741ce0beaf346828e8887e17800 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Mon, 5 Apr 2021 14:59:58 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=F0=9F=90=9B=20=20debug=20bind=20to=20stdio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c8d5ecf99..207f711eb 100644 --- a/Makefile +++ b/Makefile @@ -121,7 +121,8 @@ endef # Start qemu with tty opend on host, waiting for gdb to connect define DEBUG_KERNEL - $(_run_qemu_mux_base) \ + $(_run_qemu_base) \ + -serial null -serial stdio \ -s -S \ -kernel endef From 7412a57f14850a8682ff3976d0a8a35c7f54bce0 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Mon, 5 Apr 2021 15:00:57 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E2=9C=A8=20startup=20alloc:=20init=20buddy?= =?UTF-8?q?=20sys's=20data=20structure?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/include/mem.h | 10 ++-- impl-c/include/mm/startup.h | 6 ++- impl-c/kernel/main.c | 14 ++++- impl-c/mm/buddy.c | 101 +++++++++++++++++++++++++++++++++++- impl-c/mm/kalloc.c | 8 +-- impl-c/mm/startup.c | 4 +- 6 files changed, 129 insertions(+), 14 deletions(-) diff --git a/impl-c/include/mem.h b/impl-c/include/mem.h index 5edaa32f1..744bcee6a 100644 --- a/impl-c/include/mem.h +++ b/impl-c/include/mem.h @@ -2,10 +2,12 @@ #include "list.h" #include "mm/frame.h" +#include "mm/startup.h" #include // #define BUDDY_MAX_EXPONENT 17 // 512Mb -#define BUDDY_MAX_EXPONENT 10 +// #define BUDDY_MAX_EXPONENT 10 +#define BUDDY_MAX_EXPONENT 5 #define BUDDY_NUM_FREE_LISTS (BUDDY_MAX_EXPONENT + 1) @@ -74,8 +76,8 @@ void KAllocManager_show_status(); // Statically linked to the heap space // because their lifetimes is equal to the system itself -struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; -struct AllocationManager KAllocManager; +extern struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; +extern struct AllocationManager KAllocManager; // Call slab allocator for allocate an object void *slab_alloc(SlabAllocator *alloc); @@ -83,7 +85,7 @@ void *slab_alloc(SlabAllocator *alloc); // Free an object void slab_free(void *obj); -void buddy_init(BuddyAllocater *alloc); +void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa); struct Frame *buddy_alloc(BuddyAllocater *alloc, int size_in_byte); void buddy_free(BuddyAllocater *alloc, struct Frame *frame); void buddy_dump(BuddyAllocater *alloc); diff --git a/impl-c/include/mm/startup.h b/impl-c/include/mm/startup.h index 74d9a3ad0..1cf40454d 100644 --- a/impl-c/include/mm/startup.h +++ b/impl-c/include/mm/startup.h @@ -16,8 +16,10 @@ typedef struct StartupAllocator { struct MemRegion *_reserved; } StartupAllocator_t; -struct MemRegion ReservedRegions[STARTUP_MAX_RESERVE_COUNT]; -StartupAllocator_t StartupAlloc; +extern struct MemRegion ReservedRegions[STARTUP_MAX_RESERVE_COUNT]; +extern StartupAllocator_t StartupAlloc; + +bool is_overlap(MemRegion *a1, MemRegion *a2); // Public api: Initialize the starup allocator module void startup_init(); diff --git a/impl-c/kernel/main.c b/impl-c/kernel/main.c index f27affee8..639ddaeda 100644 --- a/impl-c/kernel/main.c +++ b/impl-c/kernel/main.c @@ -13,8 +13,18 @@ int main() { run_tests(); #endif - // KAllocManager_init(); - // KAllocManager_show_status(); + startup_init(); + + // startup_reserve((void *)0x0, 0x1000); // spin table + // startup_reserve((void *)0x60000, 0x20000); // stack + startup_reserve((void *)0xa0000, 0x8000); + // startup_reserve((void *)(&kn_start), (&kn_end - &kn_start)); // kernel + // startup_reserve((void *)(&kn_end), mem_size / PAGE_SIZE); // buddy + // system + // startup_reserve((void *)0x3f000000, 0x1000000); // MMIO + + KAllocManager_init(); + KAllocManager_show_status(); // void *a[30]; // for (int i = 0; i < 5; i++) { diff --git a/impl-c/mm/buddy.c b/impl-c/mm/buddy.c index a9f0338b3..d19f074c0 100644 --- a/impl-c/mm/buddy.c +++ b/impl-c/mm/buddy.c @@ -1,17 +1,29 @@ #include "bool.h" #include "list.h" #include "mem.h" +#include "mm/startup.h" #include "uart.h" #include #define NOT_AVAILABLE -9999 +struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; + static inline int buddy_idx(Frame *self) { int bit_to_invert = 1 << self->exp; return self->arr_index ^ bit_to_invert; } +static inline void *end_addr(Frame *f) { + void *addr = f->addr + ((1 << f->exp) << FRAME_SHIFT); + return addr; +} + static bool provide_frame_with_exp(BuddyAllocater *alloc, int required_exp); +static Frame *find_buddy_collide_reserved(BuddyAllocater *alloc, + StartupAllocator_t *sa); +static bool is_frame_wrapped_by_collison(Frame *node, StartupAllocator_t *sa); +static void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa); void buddy_dump(BuddyAllocater *alloc) { uart_println("========Status========"); @@ -116,13 +128,97 @@ bool provide_frame_with_exp(BuddyAllocater *alloc, int required_exp) { return false; } -void buddy_init(BuddyAllocater *alloc) { - // Bind the physical frame for manipulation +// Return a frame if it's area is collide with the reserved area +Frame *find_buddy_collide_reserved(BuddyAllocater *alloc, + StartupAllocator_t *sa) { + int total_reserved = sa->num_reserved; + Frame *node; + list_head_t *list, *entry; + MemRegion node_region; + bool overlap = false; + // for every list + for (int exp = 0; exp <= BUDDY_MAX_EXPONENT; exp++) { + list = &alloc->free_lists[exp]; + // for every entries + for (entry = list->next; entry != list; entry = entry->next) { + node = (Frame *)entry; + node_region.addr = node->addr; + node_region.size = (1 << (node->exp)) << FRAME_SHIFT; + for (int i = 0; i < total_reserved; i++) { + overlap = is_overlap(&node_region, &sa->_reserved[i]); + if (overlap) { + return node; + } + } + } + } + return NULL; +} +bool is_frame_wrapped_by_collison(Frame *node, StartupAllocator_t *sa) { + int total_reserved = sa->num_reserved; + // node region + void *nstart = node->addr; + void *nend = nstart + ((1 << (node->exp)) << FRAME_SHIFT); + + // reserved region + void *rstart, *rend; + + for (int i = 0; i < total_reserved; i++) { + rstart = sa->_reserved[i].addr; + rend = rstart + sa->_reserved[i].size; + if (rstart <= nstart && nend <= rend) { + return true; + } + } + return false; +} + +// Initialize buddy systems initial state to prevent overlap with reserved +// memregion +void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa) { + Frame *node, *child1, *child2; + int child_exp; + while (NULL != (node = find_buddy_collide_reserved(alloc, sa))) { + // split node + list_del(&node->list_base); + if (true == is_frame_wrapped_by_collison(node, sa)) { + uart_println("collison - remove node[%x, %x]", node->addr, + end_addr(node)); + continue; + } + + uart_println("collison - node[%x, %x]", node->addr, end_addr(node)); + child_exp = (node->exp) - 1; + child1 = &Frames[node->arr_index]; + child2 = &Frames[node->arr_index + (1 << child_exp)]; + child1->exp = child_exp; + child2->exp = child_exp; + if (false == is_frame_wrapped_by_collison(child1, sa)) { + uart_println("collison - push child[%x, %x]", child1->addr, + end_addr(child1)); + list_push(&child1->list_base, &alloc->free_lists[child_exp]); + } + if (false == is_frame_wrapped_by_collison(child2, sa)) { + uart_println("collison - push child[%x, %x]", child2->addr, + end_addr(child2)); + list_push(&child2->list_base, &alloc->free_lists[child_exp]); + } + buddy_dump(alloc); + } +} + +void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa) { + // Bind the physical frame for manipulation + // uart_println("startup %x", ReservedRegions); for (int i = 0; i < (1 << BUDDY_MAX_EXPONENT); i++) { Frames[i].arr_index = i; Frames[i].exp = -1; Frames[i].addr = (void *)(((long)i << FRAME_SHIFT) + MEMORY_START); + // uart_println("frame :%x", &Frames[i]); + // uart_println("next: %x", Frames[i].list_base.next); + Frames[i].list_base.next = NULL; + Frames[i].list_base.prev = NULL; } for (int i = 0; i < BUDDY_NUM_FREE_LISTS; i++) { uart_println("addr for list %d, %x", i, &(alloc->free_lists[i])); @@ -133,4 +229,5 @@ void buddy_init(BuddyAllocater *alloc) { Frame *root_frame = &Frames[0]; root_frame->exp = BUDDY_MAX_EXPONENT; list_push(&root_frame->list_base, &alloc->free_lists[BUDDY_MAX_EXPONENT]); + buddy_init_reserved(alloc, sa); } diff --git a/impl-c/mm/kalloc.c b/impl-c/mm/kalloc.c index a806f975a..e82b3b295 100644 --- a/impl-c/mm/kalloc.c +++ b/impl-c/mm/kalloc.c @@ -1,16 +1,18 @@ #include "bool.h" #include "list.h" #include "mem.h" +#include "mm/startup.h" #include "uart.h" #include +struct AllocationManager KAllocManager; +struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; + void KAllocManager_init() { AllocationManager *am = &KAllocManager; - buddy_init(&am->frame_allocator); + buddy_init(&am->frame_allocator, &StartupAlloc); for (int i = 0; i < (1 << BUDDY_MAX_EXPONENT); i++) { - Frames[i].list_base.next = NULL; - Frames[i].list_base.prev = NULL; for (int j = 0; j < (SLAB_MAX_SLOTS >> 3); j++) { Frames[i].slot_available[j] = 0; } diff --git a/impl-c/mm/startup.c b/impl-c/mm/startup.c index 577788481..1a1cec40d 100644 --- a/impl-c/mm/startup.c +++ b/impl-c/mm/startup.c @@ -8,10 +8,12 @@ #include +StartupAllocator_t StartupAlloc; +struct MemRegion ReservedRegions[STARTUP_MAX_RESERVE_COUNT]; + // Mask for address inside frame #define FRAME_MASK ((1 << FRAME_SHIFT) - 1) -static bool is_overlap(MemRegion *a1, MemRegion *a2); static void sa_init(StartupAllocator_t *sa, struct MemRegion *reserved, int max_reserved_count); // static void *sa_alloc(StartupAllocator_t *sa, unsigned long size); From 1526902d4388d13ffcda9b29b09f7c3c3d79e7f8 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Mon, 5 Apr 2021 15:12:51 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20assign=20frames=20to?= =?UTF-8?q?=20buddy=20by=20pointer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/include/mem.h | 5 ++++- impl-c/mm/buddy.c | 37 +++++++++++++++++-------------------- impl-c/mm/kalloc.c | 3 ++- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/impl-c/include/mem.h b/impl-c/include/mem.h index 744bcee6a..ab21ecc41 100644 --- a/impl-c/include/mem.h +++ b/impl-c/include/mem.h @@ -46,6 +46,8 @@ typedef struct Frame { // allocate contiguous frames typedef struct BuddyAllocater { list_head_t free_lists[BUDDY_NUM_FREE_LISTS]; + struct Frame *frames; + unsigned long num_frames; } BuddyAllocater; typedef struct SlabAllocator { @@ -85,7 +87,8 @@ void *slab_alloc(SlabAllocator *alloc); // Free an object void slab_free(void *obj); -void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa); +void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa, + struct Frame *frames, unsigned long num_frames); struct Frame *buddy_alloc(BuddyAllocater *alloc, int size_in_byte); void buddy_free(BuddyAllocater *alloc, struct Frame *frame); void buddy_dump(BuddyAllocater *alloc); diff --git a/impl-c/mm/buddy.c b/impl-c/mm/buddy.c index d19f074c0..8e46096d5 100644 --- a/impl-c/mm/buddy.c +++ b/impl-c/mm/buddy.c @@ -7,8 +7,6 @@ #define NOT_AVAILABLE -9999 -struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; - static inline int buddy_idx(Frame *self) { int bit_to_invert = 1 << self->exp; return self->arr_index ^ bit_to_invert; @@ -29,7 +27,7 @@ void buddy_dump(BuddyAllocater *alloc) { uart_println("========Status========"); uart_println("Framenodes (idx, exp)"); for (int i = 0; i < (1 << BUDDY_MAX_EXPONENT); i++) { - Frame *node = &Frames[i]; + Frame *node = &alloc->frames[i]; uart_printf("[%d,%d,%x]", node->arr_index, node->exp, node->addr); } uart_println(""); @@ -65,14 +63,14 @@ void buddy_free(BuddyAllocater *alloc, struct Frame *frame) { Frame *low, *high; int frame_idx; for (frame_idx = frame->arr_index;;) { - node = &Frames[frame_idx]; + node = &alloc->frames[frame_idx]; if (buddy_idx(node) >= (1 << BUDDY_MAX_EXPONENT)) { list_push(&node->list_base, &alloc->free_lists[node->exp]); uart_println(" push to freelist: node(idx:%d,exp:%d)", node->arr_index, node->exp); break; } - buddy = &Frames[buddy_idx(node)]; + buddy = &alloc->frames[buddy_idx(node)]; uart_printf("Try to merge buddy(idx:%d,exp:%d) node(idx:%d,exp:%d)", buddy->arr_index, buddy->exp, node->arr_index, node->exp); @@ -115,8 +113,8 @@ bool provide_frame_with_exp(BuddyAllocater *alloc, int required_exp) { Frame *node = (Frame *)list_pop(&alloc->free_lists[exp]); int child_exp = exp - 1; - Frame *child1 = &Frames[node->arr_index]; - Frame *child2 = &Frames[node->arr_index + (1 << child_exp)]; + Frame *child1 = &alloc->frames[node->arr_index]; + Frame *child2 = &alloc->frames[node->arr_index + (1 << child_exp)]; child1->exp = child_exp; child2->exp = child_exp; list_push(&child1->list_base, &alloc->free_lists[child_exp]); @@ -190,8 +188,8 @@ void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa) { uart_println("collison - node[%x, %x]", node->addr, end_addr(node)); child_exp = (node->exp) - 1; - child1 = &Frames[node->arr_index]; - child2 = &Frames[node->arr_index + (1 << child_exp)]; + child1 = &alloc->frames[node->arr_index]; + child2 = &alloc->frames[node->arr_index + (1 << child_exp)]; child1->exp = child_exp; child2->exp = child_exp; if (false == is_frame_wrapped_by_collison(child1, sa)) { @@ -208,17 +206,16 @@ void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa) { } } -void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa) { - // Bind the physical frame for manipulation - // uart_println("startup %x", ReservedRegions); +void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa, + struct Frame *frames, unsigned long num_frames) { + alloc->frames = frames; + alloc->num_frames = num_frames; for (int i = 0; i < (1 << BUDDY_MAX_EXPONENT); i++) { - Frames[i].arr_index = i; - Frames[i].exp = -1; - Frames[i].addr = (void *)(((long)i << FRAME_SHIFT) + MEMORY_START); - // uart_println("frame :%x", &Frames[i]); - // uart_println("next: %x", Frames[i].list_base.next); - Frames[i].list_base.next = NULL; - Frames[i].list_base.prev = NULL; + alloc->frames[i].arr_index = i; + alloc->frames[i].exp = -1; + alloc->frames[i].addr = (void *)(((long)i << FRAME_SHIFT) + MEMORY_START); + alloc->frames[i].list_base.next = NULL; + alloc->frames[i].list_base.prev = NULL; } for (int i = 0; i < BUDDY_NUM_FREE_LISTS; i++) { uart_println("addr for list %d, %x", i, &(alloc->free_lists[i])); @@ -226,7 +223,7 @@ void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa) { } // push a root frame - Frame *root_frame = &Frames[0]; + Frame *root_frame = &alloc->frames[0]; root_frame->exp = BUDDY_MAX_EXPONENT; list_push(&root_frame->list_base, &alloc->free_lists[BUDDY_MAX_EXPONENT]); buddy_init_reserved(alloc, sa); diff --git a/impl-c/mm/kalloc.c b/impl-c/mm/kalloc.c index e82b3b295..acc533e2d 100644 --- a/impl-c/mm/kalloc.c +++ b/impl-c/mm/kalloc.c @@ -10,7 +10,8 @@ struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; void KAllocManager_init() { AllocationManager *am = &KAllocManager; - buddy_init(&am->frame_allocator, &StartupAlloc); + buddy_init(&am->frame_allocator, &StartupAlloc, Frames, + (1 << BUDDY_MAX_EXPONENT)); for (int i = 0; i < (1 << BUDDY_MAX_EXPONENT); i++) { for (int j = 0; j < (SLAB_MAX_SLOTS >> 3); j++) { From f92c7ddfc5aa8a32ceef2f743077d2996a075406 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Mon, 5 Apr 2021 15:53:15 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20=20seperate=20funcs=20?= =?UTF-8?q?for=20alloc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/include/mm.h | 41 +++++++++++++++++++++++++ impl-c/include/{mem.h => mm/alloc.h} | 45 ++-------------------------- impl-c/include/mm/const.h | 25 ++++++++++++++++ impl-c/include/mm/startup.h | 13 ++++++++ impl-c/kernel/main.c | 24 ++------------- impl-c/mm/buddy.c | 6 ++-- impl-c/mm/kalloc.c | 29 ++++++++++++++++-- impl-c/mm/slab.c | 2 +- 8 files changed, 114 insertions(+), 71 deletions(-) create mode 100644 impl-c/include/mm.h rename impl-c/include/{mem.h => mm/alloc.h} (51%) create mode 100644 impl-c/include/mm/const.h diff --git a/impl-c/include/mm.h b/impl-c/include/mm.h new file mode 100644 index 000000000..9a9fb80c3 --- /dev/null +++ b/impl-c/include/mm.h @@ -0,0 +1,41 @@ +#pragma once + +#include "list.h" +#include "mm/alloc.h" +#include "mm/const.h" +#include "mm/frame.h" +#include "mm/startup.h" +#include + +/** + * Allocation Manager: + * On charge of dynamic memory allocation by using frame/object allocators + * + * Caution: must initialize the startup allocator before using + * any of the function listed below, otherwise the buddy system + * wont initialize properly + * */ + +extern struct AllocationManager KAllocManager; +typedef struct AllocationManager { + SlabAllocator obj_allocator_list[SLAB_NUM_SLAB_SIZES]; + BuddyAllocater frame_allocator; +} AllocationManager; + +// Statically linked to the heap space +// because their lifetimes is equal to the system itself +extern struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; + +// Allocate a memory space to use in kernel space +void *kalloc(int size); + +// Free a memory space +void kfree(void *addr); + +// Initialize dynamic memory allocator +void KAllocManager_init(); + +void KAllocManager_show_status(); + +// Run several allocation/free as an example +void KAllocManager_run_example(); \ No newline at end of file diff --git a/impl-c/include/mem.h b/impl-c/include/mm/alloc.h similarity index 51% rename from impl-c/include/mem.h rename to impl-c/include/mm/alloc.h index ab21ecc41..6d0de3854 100644 --- a/impl-c/include/mem.h +++ b/impl-c/include/mm/alloc.h @@ -1,33 +1,11 @@ #pragma once #include "list.h" +#include "mm/const.h" #include "mm/frame.h" #include "mm/startup.h" #include -// #define BUDDY_MAX_EXPONENT 17 // 512Mb -// #define BUDDY_MAX_EXPONENT 10 -#define BUDDY_MAX_EXPONENT 5 - -#define BUDDY_NUM_FREE_LISTS (BUDDY_MAX_EXPONENT + 1) - -#define MEMORY_START 0x90000 - -// SlabAllocator -// manage slabs with the same allocation size, -// A slab is a frame allocated with small objects with same size -// + @SLAB_MAX_SLOTS: The number of pages available for a single slab -// -> Frame is 4kb by architecture. -// CortexA53 is 16 bytes aligned, so the here 16 bytes is set to be -// the minimum size available for objects in slab. -// -> Therefore, the maximum slots in slab is 4096/16 = 256 -#define SLAB_MAX_SLOTS 256 - -// The size of slab range from 16(2^4) to 512(2^9) bytes -#define SLAB_OBJ_MIN_SIZE_EXP 4 -#define SLAB_OBJ_MAX_SIZE_EXP 9 -#define SLAB_NUM_SLAB_SIZES 6 - typedef struct Frame { // inherit a list type, so we could cast FrameNode into list_head struct list_head list_base; @@ -47,7 +25,6 @@ typedef struct Frame { typedef struct BuddyAllocater { list_head_t free_lists[BUDDY_NUM_FREE_LISTS]; struct Frame *frames; - unsigned long num_frames; } BuddyAllocater; typedef struct SlabAllocator { @@ -63,24 +40,6 @@ typedef struct SlabAllocator { // full_list for storage. } SlabAllocator; -typedef struct AllocationManager { - SlabAllocator obj_allocator_list[SLAB_NUM_SLAB_SIZES]; - BuddyAllocater frame_allocator; -} AllocationManager; - -void *kalloc(int size); -void kfree(void *addr); - -// Initialize dynamic memory allocator -void KAllocManager_init(); - -void KAllocManager_show_status(); - -// Statically linked to the heap space -// because their lifetimes is equal to the system itself -extern struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; -extern struct AllocationManager KAllocManager; - // Call slab allocator for allocate an object void *slab_alloc(SlabAllocator *alloc); @@ -88,7 +47,7 @@ void *slab_alloc(SlabAllocator *alloc); void slab_free(void *obj); void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa, - struct Frame *frames, unsigned long num_frames); + struct Frame *frames); struct Frame *buddy_alloc(BuddyAllocater *alloc, int size_in_byte); void buddy_free(BuddyAllocater *alloc, struct Frame *frame); void buddy_dump(BuddyAllocater *alloc); diff --git a/impl-c/include/mm/const.h b/impl-c/include/mm/const.h new file mode 100644 index 000000000..58e4ddae9 --- /dev/null +++ b/impl-c/include/mm/const.h @@ -0,0 +1,25 @@ +#pragma once + +#define SLAB_NUM_SLAB_SIZES 6 + +// #define BUDDY_MAX_EXPONENT 17 // 512Mb +// #define BUDDY_MAX_EXPONENT 10 +#define BUDDY_MAX_EXPONENT 5 + +#define BUDDY_NUM_FREE_LISTS (BUDDY_MAX_EXPONENT + 1) + +#define MEMORY_START 0x90000 + +// SlabAllocator +// manage slabs with the same allocation size, +// A slab is a frame allocated with small objects with same size +// + @SLAB_MAX_SLOTS: The number of pages available for a single slab +// -> Frame is 4kb by architecture. +// CortexA53 is 16 bytes aligned, so the here 16 bytes is set to be +// the minimum size available for objects in slab. +// -> Therefore, the maximum slots in slab is 4096/16 = 256 +#define SLAB_MAX_SLOTS 256 + +// The size of slab range from 16(2^4) to 512(2^9) bytes +#define SLAB_OBJ_MIN_SIZE_EXP 4 +#define SLAB_OBJ_MAX_SIZE_EXP 9 \ No newline at end of file diff --git a/impl-c/include/mm/startup.h b/impl-c/include/mm/startup.h index 1cf40454d..fcc49c4b4 100644 --- a/impl-c/include/mm/startup.h +++ b/impl-c/include/mm/startup.h @@ -5,6 +5,19 @@ #define STARTUP_MAX_RESERVE_COUNT 10 +/** + * Startup allocator: + * The very first memory allocator of the opoerating system + * + * The purpose of startup allocator is to reserve spaces on system starup, + * Hand all of it's knowledfe to( memory regions have bee reserved) + * to the dynamic memory allcator. + * + * This allocator is fairly basic, which only allocate but not free spaces at + * all. + * + * */ + typedef struct MemRegion { void *addr; unsigned long size; diff --git a/impl-c/kernel/main.c b/impl-c/kernel/main.c index 639ddaeda..9657677c1 100644 --- a/impl-c/kernel/main.c +++ b/impl-c/kernel/main.c @@ -1,5 +1,5 @@ #include "cfg.h" -#include "mem.h" +#include "mm.h" #include "mm/startup.h" #include "shell.h" #include "test.h" @@ -26,26 +26,8 @@ int main() { KAllocManager_init(); KAllocManager_show_status(); - // void *a[30]; - // for (int i = 0; i < 5; i++) { - // a[i] = kalloc(8192); - // uart_println("i:%d, a: %x", i, a[i]); - // } - - // for (int i = 0; i < 5; i++) { - // kfree(a[i]); - // } - - // for (int i = 0; i < 5; i++) { - // a[i] = kalloc(13); - // uart_println("i:%d, a: %x", i, a[i]); - // }; - // if (a[0] == a[1]) { - // uart_println("nooo"); - // } - // for (int i = 0; i < 5; i++) { - // kfree(a[i]); - // } + KAllocManager_run_example(); + KAllocManager_show_status(); uart_println("-------------------------------"); uart_println(" Operating System Capstone 2021"); diff --git a/impl-c/mm/buddy.c b/impl-c/mm/buddy.c index 8e46096d5..8d0811b1c 100644 --- a/impl-c/mm/buddy.c +++ b/impl-c/mm/buddy.c @@ -1,6 +1,7 @@ #include "bool.h" #include "list.h" -#include "mem.h" +#include "mm.h" +#include "mm/alloc.h" #include "mm/startup.h" #include "uart.h" #include @@ -207,9 +208,8 @@ void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa) { } void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa, - struct Frame *frames, unsigned long num_frames) { + struct Frame *frames) { alloc->frames = frames; - alloc->num_frames = num_frames; for (int i = 0; i < (1 << BUDDY_MAX_EXPONENT); i++) { alloc->frames[i].arr_index = i; alloc->frames[i].exp = -1; diff --git a/impl-c/mm/kalloc.c b/impl-c/mm/kalloc.c index acc533e2d..d2010318b 100644 --- a/impl-c/mm/kalloc.c +++ b/impl-c/mm/kalloc.c @@ -1,6 +1,6 @@ #include "bool.h" #include "list.h" -#include "mem.h" +#include "mm.h" #include "mm/startup.h" #include "uart.h" #include @@ -8,10 +8,33 @@ struct AllocationManager KAllocManager; struct Frame Frames[BUDDY_MAX_EXPONENT << 1]; +void KAllocManager_run_example() { + void *a[30]; + uart_println("[Example] Allocate 5 single frames:"); + for (int i = 0; i < 5; i++) { + a[i] = kalloc(8192); + uart_println("i:%d, a: %x", i, a[i]); + } + + uart_println("[Example] free 5 frames we've just allocated"); + for (int i = 0; i < 5; i++) { + kfree(a[i]); + } + + uart_println("[Example] print 5 objects with 13 bytes each"); + for (int i = 0; i < 5; i++) { + a[i] = kalloc(13); + uart_println("i:%d, a: %x", i, a[i]); + }; + uart_println("[Example] free 5 frames we've just allocated"); + for (int i = 0; i < 5; i++) { + kfree(a[i]); + } +} + void KAllocManager_init() { AllocationManager *am = &KAllocManager; - buddy_init(&am->frame_allocator, &StartupAlloc, Frames, - (1 << BUDDY_MAX_EXPONENT)); + buddy_init(&am->frame_allocator, &StartupAlloc, Frames); for (int i = 0; i < (1 << BUDDY_MAX_EXPONENT); i++) { for (int j = 0; j < (SLAB_MAX_SLOTS >> 3); j++) { diff --git a/impl-c/mm/slab.c b/impl-c/mm/slab.c index 784794ede..302acd8f5 100644 --- a/impl-c/mm/slab.c +++ b/impl-c/mm/slab.c @@ -1,6 +1,6 @@ #include "bool.h" #include "list.h" -#include "mem.h" +#include "mm.h" #include "uart.h" #include From bfbb1c68c0aa8a37a7ded81c005132b015560ab2 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Mon, 5 Apr 2021 16:29:33 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E2=9C=A8=20startup=20alloc:=20reserve=20re?= =?UTF-8?q?al=20system=20area?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/include/mm/const.h | 7 ++++--- impl-c/include/mm/frame.h | 2 +- impl-c/kernel/linker.ld | 3 +++ impl-c/kernel/main.c | 19 ++++++++++--------- impl-c/mm/buddy.c | 11 +++++++++-- impl-c/mm/startup.c | 11 ++++++++++- 6 files changed, 37 insertions(+), 16 deletions(-) diff --git a/impl-c/include/mm/const.h b/impl-c/include/mm/const.h index 58e4ddae9..81409bc75 100644 --- a/impl-c/include/mm/const.h +++ b/impl-c/include/mm/const.h @@ -2,13 +2,14 @@ #define SLAB_NUM_SLAB_SIZES 6 -// #define BUDDY_MAX_EXPONENT 17 // 512Mb +#define BUDDY_MAX_EXPONENT 18 // 1GB // #define BUDDY_MAX_EXPONENT 10 -#define BUDDY_MAX_EXPONENT 5 +// #define BUDDY_MAX_EXPONENT 5 #define BUDDY_NUM_FREE_LISTS (BUDDY_MAX_EXPONENT + 1) -#define MEMORY_START 0x90000 +// #define MEMORY_START 0x90000 +#define MEMORY_START 0x0 // SlabAllocator // manage slabs with the same allocation size, diff --git a/impl-c/include/mm/frame.h b/impl-c/include/mm/frame.h index 5f370179c..ed17d678c 100644 --- a/impl-c/include/mm/frame.h +++ b/impl-c/include/mm/frame.h @@ -1,3 +1,3 @@ #pragma once -#define FRAME_SHIFT 14 // 4Kb +#define FRAME_SHIFT 12 // 4Kb #define FRAME_ADDR_BASE (1 << FRAME_SHIFT) diff --git a/impl-c/kernel/linker.ld b/impl-c/kernel/linker.ld index 582540335..e0f912770 100644 --- a/impl-c/kernel/linker.ld +++ b/impl-c/kernel/linker.ld @@ -7,6 +7,7 @@ SECTIONS for more information */ . = 0x80000; + __kernel_start = .; .text : { KEEP(*(.text.boot)) *(.text) @@ -25,6 +26,8 @@ SECTIONS *(.bss .bss.*) __bss_end = .; } + . = ALIGN(4096); + __kernel_end = .; _end = .; } __bss_size = (__bss_end - __bss_start) >> 3; diff --git a/impl-c/kernel/main.c b/impl-c/kernel/main.c index 9657677c1..c8c1b18d5 100644 --- a/impl-c/kernel/main.c +++ b/impl-c/kernel/main.c @@ -5,6 +5,8 @@ #include "test.h" #include "uart.h" +extern unsigned char __kernel_start, __kernel_end; + int main() { uart_init(); uart_println("uart initialized"); @@ -15,19 +17,18 @@ int main() { startup_init(); - // startup_reserve((void *)0x0, 0x1000); // spin table - // startup_reserve((void *)0x60000, 0x20000); // stack - startup_reserve((void *)0xa0000, 0x8000); - // startup_reserve((void *)(&kn_start), (&kn_end - &kn_start)); // kernel + // Kernel + startup_reserve((void *)0x0, 0x1000); // spin table + startup_reserve((void *)0x60000, 0x20000); // stack + startup_reserve((void *)(&__kernel_start), + (&__kernel_end - &__kernel_start)); // kernel // startup_reserve((void *)(&kn_end), mem_size / PAGE_SIZE); // buddy - // system - // startup_reserve((void *)0x3f000000, 0x1000000); // MMIO + // System + startup_reserve((void *)0x3f000000, 0x1000000); // MMIO KAllocManager_init(); - KAllocManager_show_status(); - KAllocManager_run_example(); - KAllocManager_show_status(); + // KAllocManager_show_status(); uart_println("-------------------------------"); uart_println(" Operating System Capstone 2021"); diff --git a/impl-c/mm/buddy.c b/impl-c/mm/buddy.c index 8d0811b1c..1fede60e8 100644 --- a/impl-c/mm/buddy.c +++ b/impl-c/mm/buddy.c @@ -178,6 +178,13 @@ bool is_frame_wrapped_by_collison(Frame *node, StartupAllocator_t *sa) { void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa) { Frame *node, *child1, *child2; int child_exp; + + MemRegion reg; + for (int i = 0; i < sa->num_reserved; i++) { + reg.addr = sa->_reserved[i].addr; + reg.size = sa->_reserved[i].size; + uart_println("reserved: %d, %d", reg.addr, reg.size); + } while (NULL != (node = find_buddy_collide_reserved(alloc, sa))) { // split node list_del(&node->list_base); @@ -203,7 +210,7 @@ void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa) { end_addr(child2)); list_push(&child2->list_base, &alloc->free_lists[child_exp]); } - buddy_dump(alloc); + // buddy_dump(alloc); } } @@ -218,7 +225,7 @@ void buddy_init(BuddyAllocater *alloc, StartupAllocator_t *sa, alloc->frames[i].list_base.prev = NULL; } for (int i = 0; i < BUDDY_NUM_FREE_LISTS; i++) { - uart_println("addr for list %d, %x", i, &(alloc->free_lists[i])); + // uart_println("addr for list %d, %x", i, &(alloc->free_lists[i])); list_init(&alloc->free_lists[i]); } diff --git a/impl-c/mm/startup.c b/impl-c/mm/startup.c index 1a1cec40d..de27bca51 100644 --- a/impl-c/mm/startup.c +++ b/impl-c/mm/startup.c @@ -23,7 +23,13 @@ void startup_init() { sa_init(&StartupAlloc, ReservedRegions, STARTUP_MAX_RESERVE_COUNT); } bool startup_reserve(void *addr, unsigned long size) { - return sa_reserve(&StartupAlloc, addr, size); + bool succes = sa_reserve(&StartupAlloc, addr, size); + if (succes) { + uart_println("reserve addr: %x", addr); + } else { + uart_println("failed to reserve addr: %x", addr); + } + return succes; } // void *startup_alloc(unsigned long size) { @@ -75,15 +81,18 @@ void sa_init(StartupAllocator_t *sa, struct MemRegion *reserved, bool sa_reserve(StartupAllocator_t *sa, void *addr, unsigned long size) { if (((unsigned long long)addr & FRAME_MASK) != 0 || (size & FRAME_MASK) != 0) { + uart_println("not aligned"); return false; } if (sa->num_reserved >= sa->max_reserved) { + uart_println("limited reached"); return false; } MemRegion requested = {.addr = addr, .size = size}; // Should not overlapped with space that reserved already for (int i = 0; i < sa->num_reserved; i++) { if (is_overlap(&requested, &sa->_reserved[i])) { + uart_println("overlap"); return false; } } From 17061665bff609255e5900fd48ed75c948ad8a5d Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Mon, 5 Apr 2021 16:41:17 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E2=9C=A8=20conditional=20log:=20kalloc,=20?= =?UTF-8?q?startup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- impl-c/include/cfg.h | 10 +++++++++- impl-c/mm/buddy.c | 12 ++++++++++++ impl-c/mm/kalloc.c | 10 +++++++++- impl-c/mm/startup.c | 8 ++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/impl-c/include/cfg.h b/impl-c/include/cfg.h index 3c26f2292..f7eceff4a 100644 --- a/impl-c/include/cfg.h +++ b/impl-c/include/cfg.h @@ -1,8 +1,16 @@ #pragma once +/** + * Log + * */ + #define CFG_LOG_ENABLE 0 +#define CFG_LOG_STARTUP +#define CFG_LOG_KALLOC +/** + * TEST + * */ #define CFG_RUN_TEST - // memory management #define CFG_RUN_STATUP_ALLOC_TEST \ No newline at end of file diff --git a/impl-c/mm/buddy.c b/impl-c/mm/buddy.c index 1fede60e8..f40763f7c 100644 --- a/impl-c/mm/buddy.c +++ b/impl-c/mm/buddy.c @@ -1,4 +1,5 @@ #include "bool.h" +#include "cfg.h" #include "list.h" #include "mm.h" #include "mm/alloc.h" @@ -179,35 +180,46 @@ void buddy_init_reserved(BuddyAllocater *alloc, StartupAllocator_t *sa) { Frame *node, *child1, *child2; int child_exp; +#ifdef CFG_LOG_STARTUP MemRegion reg; for (int i = 0; i < sa->num_reserved; i++) { reg.addr = sa->_reserved[i].addr; reg.size = sa->_reserved[i].size; uart_println("reserved: %d, %d", reg.addr, reg.size); } +#endif + while (NULL != (node = find_buddy_collide_reserved(alloc, sa))) { // split node list_del(&node->list_base); if (true == is_frame_wrapped_by_collison(node, sa)) { +#ifdef CFG_LOG_STARTUP uart_println("collison - remove node[%x, %x]", node->addr, end_addr(node)); +#endif continue; } +#ifdef CFG_LOG_STARTUP uart_println("collison - node[%x, %x]", node->addr, end_addr(node)); +#endif child_exp = (node->exp) - 1; child1 = &alloc->frames[node->arr_index]; child2 = &alloc->frames[node->arr_index + (1 << child_exp)]; child1->exp = child_exp; child2->exp = child_exp; if (false == is_frame_wrapped_by_collison(child1, sa)) { +#ifdef CFG_LOG_STARTUP uart_println("collison - push child[%x, %x]", child1->addr, end_addr(child1)); +#endif list_push(&child1->list_base, &alloc->free_lists[child_exp]); } if (false == is_frame_wrapped_by_collison(child2, sa)) { +#ifdef CFG_LOG_STARTUP uart_println("collison - push child[%x, %x]", child2->addr, end_addr(child2)); +#endif list_push(&child2->list_base, &alloc->free_lists[child_exp]); } // buddy_dump(alloc); diff --git a/impl-c/mm/kalloc.c b/impl-c/mm/kalloc.c index d2010318b..50420bdad 100644 --- a/impl-c/mm/kalloc.c +++ b/impl-c/mm/kalloc.c @@ -63,7 +63,9 @@ void *kalloc(int size) { if (size <= (1 << SLAB_OBJ_MAX_SIZE_EXP)) { for (int i = SLAB_OBJ_MIN_SIZE_EXP; i < SLAB_OBJ_MAX_SIZE_EXP; i++) { if (size < 1 << i) { +#ifdef CFG_LOG_KALLOC uart_println("Allocation from slab allocator, size: %d", size); +#endif addr = slab_alloc( &KAllocManager.obj_allocator_list[i - SLAB_OBJ_MIN_SIZE_EXP]); return addr; @@ -73,10 +75,13 @@ void *kalloc(int size) { // allcation using buddy system for (int i = 0; i < BUDDY_MAX_EXPONENT; i++) { if ((i << FRAME_SHIFT) >= size) { - uart_println("Allocate Request exp:%d", i); Frame *frame = buddy_alloc(&KAllocManager.frame_allocator, i); +#ifdef CFG_LOG_KALLOC + + uart_println("Allocate Request exp:%d", i); uart_println("Allocated addr:%x, frame_idx:%d", frame->addr, frame->arr_index); +#endif return frame->addr; } } @@ -89,8 +94,11 @@ void kfree(void *addr) { if (frame->slab_allocator) { slab_free(addr); } else { + +#ifdef CFG_LOG_KALLOC uart_println("Free Request addr:%x, frame_idx:%d", frame->addr, frame->arr_index); +#endif buddy_free(&KAllocManager.frame_allocator, frame); } } diff --git a/impl-c/mm/startup.c b/impl-c/mm/startup.c index de27bca51..0cf85f8c5 100644 --- a/impl-c/mm/startup.c +++ b/impl-c/mm/startup.c @@ -24,11 +24,13 @@ void startup_init() { } bool startup_reserve(void *addr, unsigned long size) { bool succes = sa_reserve(&StartupAlloc, addr, size); +#ifdef CFG_LOG_STARTUP if (succes) { uart_println("reserve addr: %x", addr); } else { uart_println("failed to reserve addr: %x", addr); } +#endif return succes; } @@ -81,18 +83,24 @@ void sa_init(StartupAllocator_t *sa, struct MemRegion *reserved, bool sa_reserve(StartupAllocator_t *sa, void *addr, unsigned long size) { if (((unsigned long long)addr & FRAME_MASK) != 0 || (size & FRAME_MASK) != 0) { +#ifdef CFG_LOG_STARTUP uart_println("not aligned"); +#endif return false; } if (sa->num_reserved >= sa->max_reserved) { +#ifdef CFG_LOG_STARTUP uart_println("limited reached"); +#endif return false; } MemRegion requested = {.addr = addr, .size = size}; // Should not overlapped with space that reserved already for (int i = 0; i < sa->num_reserved; i++) { if (is_overlap(&requested, &sa->_reserved[i])) { +#ifdef CFG_LOG_STARTUP uart_println("overlap"); +#endif return false; } }