diff options
-rw-r--r-- | include/arch/arm/arch.h | 3 | ||||
-rw-r--r-- | include/arch/x86_64/arch.h | 7 | ||||
-rw-r--r-- | include/kern/mem.h | 6 | ||||
-rw-r--r-- | linker/linker_script.ld | 11 | ||||
-rw-r--r-- | src/kern/main.c | 4 | ||||
-rw-r--r-- | src/kern/mem.c | 17 | ||||
-rw-r--r-- | tests/test_memory.c | 28 |
7 files changed, 47 insertions, 29 deletions
diff --git a/include/arch/arm/arch.h b/include/arch/arm/arch.h index 22d0987..8bd47c2 100644 --- a/include/arch/arm/arch.h +++ b/include/arch/arm/arch.h @@ -40,4 +40,7 @@ _Static_assert(sizeof(void*) == sizeof(uint32_t), "Pointers must be 32 bits"); extern uint32_t DATA_SEGMENT_START; extern uint32_t DATA_SEGMENT_STOP; +extern unsigned char HEAP_START; +extern unsigned char HEAP_STOP; + #endif /* ARCH_H_ */ diff --git a/include/arch/x86_64/arch.h b/include/arch/x86_64/arch.h index c17721d..a7ba776 100644 --- a/include/arch/x86_64/arch.h +++ b/include/arch/x86_64/arch.h @@ -1,6 +1,7 @@ #ifndef ARCH_H_ #define ARCH_H_ +#include <stdint.h> #include "fake_env.h" #define ARCH_PC @@ -30,8 +31,8 @@ // Pretend there's a data segement at the start of SRAM1 for more accurate // testing. -#define GHOST_DATA_SEGMENT_SIZE 1234 -#define DATA_SEGMENT_START (*((uint8_t*)SRAM1_BASE)) -#define DATA_SEGMENT_STOP (*(((uint8_t*)SRAM1_BASE) + GHOST_DATA_SEGMENT_SIZE)) +#define GHOST_DATA_SEGMENT_SIZE 1200 +#define HEAP_START (*(((unsigned char*)SRAM1_BASE) + GHOST_DATA_SEGMENT_SIZE)) +#define HEAP_STOP (*(&HEAP_START + 16384 - GHOST_DATA_SEGMENT_SIZE)) #endif /* ARCH_H_ */ diff --git a/include/kern/mem.h b/include/kern/mem.h index 832d31d..2af49cb 100644 --- a/include/kern/mem.h +++ b/include/kern/mem.h @@ -4,12 +4,6 @@ #include "arch.h" #include <stddef.h> -#define DATA_SEGMENT_STOP_ADDR ((uint8_t*) &DATA_SEGMENT_STOP) -#define DATA_SEGMENT_START_ADDR ((uint8_t*) &DATA_SEGMENT_START) - -#define MAX_HEAP_SIZE \ - ((16384 - (DATA_SEGMENT_STOP_ADDR - DATA_SEGMENT_START_ADDR)) / 4 * 4) - /* allocates memory on the head, which is stored in sram2 */ void* kalloc(size_t n); diff --git a/linker/linker_script.ld b/linker/linker_script.ld index 9a9f5b3..909c8cb 100644 --- a/linker/linker_script.ld +++ b/linker/linker_script.ld @@ -28,13 +28,21 @@ SECTIONS INITS_START = .; *(.init0); + INIT_0_END = LOADADDR(.data) + (. - INITS_START); *(.init1); + INIT_1_END = LOADADDR(.data) + (. - INITS_START); *(.init2); + INIT_2_END = LOADADDR(.data) + (. - INITS_START); *(.init3); + INIT_3_END = LOADADDR(.data) + (. - INITS_START); *(.init4); + INIT_4_END = LOADADDR(.data) + (. - INITS_START); *(.init5); + INIT_5_END = LOADADDR(.data) + (. - INITS_START); *(.init6); + INIT_6_END = LOADADDR(.data) + (. - INITS_START); *(.init7); + INIT_7_END = LOADADDR(.data) + (. - INITS_START); INITS_END = .; INIT_ROUTINES_FLASH_STOP = @@ -44,6 +52,9 @@ SECTIONS . = ALIGN(0x04); *(.noinit); + + HEAP_START = .; + HEAP_STOP = 16k; } >sram1 AT>flash BSS_START = .; diff --git a/src/kern/main.c b/src/kern/main.c index 1eedb59..a6743d5 100644 --- a/src/kern/main.c +++ b/src/kern/main.c @@ -2,6 +2,8 @@ #include "arch/stm32l4xxx/peripherals/clock.h" #include "arch/stm32l4xxx/peripherals/system.h" #include "kern/log.h" +#include "kern/panic.h" +#include "kern/init.h" void on_systick() /* Overrides weak-symbol on_systick. */ { @@ -14,6 +16,8 @@ void on_systick() /* Overrides weak-symbol on_systick. */ int main() { klogf("Hello, World! Clock Mhz: %d\n", (uint32_t)get_clock_mhz()); + klogf("Heap Start: %p\n", &HEAP_START); + klogf("Heap End : %p\n", &HEAP_STOP); /* Set the countdown to start from 10,000,0000. */ SCB.strv_r = 10000000; diff --git a/src/kern/mem.c b/src/kern/mem.c index eb4527e..533b394 100644 --- a/src/kern/mem.c +++ b/src/kern/mem.c @@ -1,7 +1,6 @@ #include "kern/mem.h" #include "arch.h" - #include "kern/common.h" #include "kern/panic.h" @@ -55,8 +54,11 @@ static_assert(offsetof(kalloc_node_t, mem) == 4, "Offset check failed."); kalloc_node_t* kalloc_start; -#define kalloc_node_out_of_range(node) \ - ((uint8_t*)(node) == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) +#define HEAP_START_ADDR ((ptrdiff_t)&HEAP_START) +#define REAL_HEAP_START \ + (*((unsigned char*)((HEAP_START_ADDR & (~3)) + (HEAP_START_ADDR % 4 != 0)))) +#define MAX_HEAP_SIZE ((&HEAP_STOP - &REAL_HEAP_START)) +#define kalloc_node_out_of_range(node) ((void*)(node) >= (void*)&HEAP_STOP) #define kalloc_node_next(cur) \ ((kalloc_node_t*)(((uint8_t*)(cur)) + (((cur)->size + 1) * 4))) @@ -76,7 +78,7 @@ kalloc_node_t* kalloc_start; void* kalloc(size_t size) { if (!kalloc_start) { - kalloc_start = (kalloc_node_t*)DATA_SEGMENT_STOP_ADDR; + kalloc_start = (kalloc_node_t*)&REAL_HEAP_START; memset(kalloc_start, 0, sizeof(kalloc_node_t)); kalloc_start->size = (MAX_HEAP_SIZE / 4) - 1; kalloc_start->canary = CANARY; @@ -224,16 +226,15 @@ int debug_kalloc_assert_consistency(char* error, size_t len) total_size += cur->size + 1; kalloc_node_t* next = kalloc_node_next(cur); - if ((uint8_t*)next == ((uint8_t*)&DATA_SEGMENT_STOP) + MAX_HEAP_SIZE) { + if ((void*)next == (void*)&HEAP_STOP) { break; - } else if ( - (uint8_t*)next > (uint8_t*)DATA_SEGMENT_STOP_ADDR + MAX_HEAP_SIZE) { + } else if ((void*)next > (void*)&HEAP_STOP) { snprintf( error, len, "Next node points is out of bounds. %p vs max of %p\n", next, - (void*)(DATA_SEGMENT_STOP_ADDR + MAX_HEAP_SIZE)); + &HEAP_STOP); return 1; } diff --git a/tests/test_memory.c b/tests/test_memory.c index 0f4ccab..a977a70 100644 --- a/tests/test_memory.c +++ b/tests/test_memory.c @@ -90,7 +90,7 @@ TEST(memory, kalloc) char buf[1024]; if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf(stderr, "Consistency check failed. (%s:%d)\n", __FILE__, __LINE__); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } @@ -134,6 +134,9 @@ TEST(memory, uneven_kalloc) return 0; } +#define ASSERT_KALLOC_EMPTY() \ + ASSERT_EQ((void*)(kalloc_start + kalloc_start->size + 1), (void*)&HEAP_STOP) + TEST(memory, kalloc_free) { if (kalloc_start) { @@ -152,7 +155,7 @@ TEST(memory, kalloc_free) kfree(test1); kfree(test5); - ASSERT_EQ((int)kalloc_start->size * 4, MAX_HEAP_SIZE - 4); + ASSERT_KALLOC_EMPTY(); test1 = new_test_struct(); test2 = new_test_struct2(); @@ -166,7 +169,7 @@ TEST(memory, kalloc_free) kfree(test4); kfree(test5); - ASSERT_EQ((int)kalloc_start->size * 4, MAX_HEAP_SIZE - 4); + ASSERT_KALLOC_EMPTY(); test1 = new_test_struct(); test2 = new_test_struct2(); @@ -180,7 +183,7 @@ TEST(memory, kalloc_free) kfree(test2); kfree(test5); - ASSERT_EQ((int)kalloc_start->size * 4, MAX_HEAP_SIZE - 4); + ASSERT_KALLOC_EMPTY(); wipeout_kalloc(); @@ -216,7 +219,7 @@ TEST(memory, kalloc_free_alloc2) char buf[1024]; if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf(stderr, "Consistency check failed.\n"); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } @@ -238,7 +241,7 @@ TEST(memory, relink_backref_after_free) char buf[1024]; if (debug_kalloc_assert_consistency(buf, 1024)) { fprintf(stderr, "Consistency check failed.\n"); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } @@ -267,7 +270,7 @@ TEST(memory, consistency_stress) i, __FILE__, __LINE__); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } @@ -283,7 +286,7 @@ TEST(memory, consistency_stress) i, __FILE__, __LINE__); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } @@ -297,7 +300,7 @@ TEST(memory, consistency_stress) i, __FILE__, __LINE__); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } @@ -312,7 +315,7 @@ TEST(memory, consistency_stress) i, __FILE__, __LINE__); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } } @@ -329,11 +332,12 @@ TEST(memory, consistency_stress) i, __FILE__, __LINE__); - fprintf(stderr, buf); + fprintf(stderr, "%s", buf); ASSERT_TRUE(false); } } - ASSERT_EQ((int)kalloc_start->size * 4, MAX_HEAP_SIZE - 4); + + ASSERT_KALLOC_EMPTY(); return 0; } |