Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lab3 startup allocator #23

Merged
merged 9 commits into from
Apr 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
15 changes: 14 additions & 1 deletion impl-c/include/cfg.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
#pragma once

#define CFG_LOG_ENABLE 0
/**
* 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
41 changes: 41 additions & 0 deletions impl-c/include/mm.h
Original file line number Diff line number Diff line change
@@ -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 <stdint.h>

/**
* 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();
48 changes: 6 additions & 42 deletions impl-c/include/mem.h → impl-c/include/mm/alloc.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,11 @@
#pragma once

#include "list.h"
#include "mm/const.h"
#include "mm/frame.h"
#include "mm/startup.h"
#include <stdint.h>

// #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)

#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;
Expand All @@ -44,6 +24,7 @@ typedef struct Frame {
// allocate contiguous frames
typedef struct BuddyAllocater {
list_head_t free_lists[BUDDY_NUM_FREE_LISTS];
struct Frame *frames;
} BuddyAllocater;

typedef struct SlabAllocator {
Expand All @@ -59,31 +40,14 @@ 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
struct Frame Frames[BUDDY_MAX_EXPONENT << 1];
struct AllocationManager KAllocManager;

// Call slab allocator for allocate an object
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 *frames);
struct Frame *buddy_alloc(BuddyAllocater *alloc, int size_in_byte);
void buddy_free(BuddyAllocater *alloc, struct Frame *frame);
void buddy_dump(BuddyAllocater *alloc);
26 changes: 26 additions & 0 deletions impl-c/include/mm/const.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#define SLAB_NUM_SLAB_SIZES 6

#define BUDDY_MAX_EXPONENT 18 // 1GB
// #define BUDDY_MAX_EXPONENT 10
// #define BUDDY_MAX_EXPONENT 5

#define BUDDY_NUM_FREE_LISTS (BUDDY_MAX_EXPONENT + 1)

// #define MEMORY_START 0x90000
#define MEMORY_START 0x0

// 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
3 changes: 3 additions & 0 deletions impl-c/include/mm/frame.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once
#define FRAME_SHIFT 12 // 4Kb
#define FRAME_ADDR_BASE (1 << FRAME_SHIFT)
47 changes: 47 additions & 0 deletions impl-c/include/mm/startup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#pragma once
#include "bool.h"
#include "cfg.h"
#include "test.h"

#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;
} MemRegion;

typedef struct StartupAllocator {
int num_reserved;
int max_reserved;
struct MemRegion *_reserved;
} StartupAllocator_t;

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();

// 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();
33 changes: 33 additions & 0 deletions impl-c/include/test.h
Original file line number Diff line number Diff line change
@@ -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();
3 changes: 3 additions & 0 deletions impl-c/kernel/linker.ld
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SECTIONS
for more information
*/
. = 0x80000;
__kernel_start = .;
.text :
{
KEEP(*(.text.boot)) *(.text)
Expand All @@ -25,6 +26,8 @@ SECTIONS
*(.bss .bss.*)
__bss_end = .;
}
. = ALIGN(4096);
__kernel_end = .;
_end = .;
}
__bss_size = (__bss_end - __bss_start) >> 3;
Expand Down
46 changes: 24 additions & 22 deletions impl-c/kernel/main.c
Original file line number Diff line number Diff line change
@@ -1,38 +1,40 @@
#include "mem.h"
#include "cfg.h"
#include "mm.h"
#include "mm/startup.h"
#include "shell.h"
#include "test.h"
#include "uart.h"

extern unsigned char __kernel_start, __kernel_end;

int main() {
uart_init();
uart_println("uart initialized");

#ifdef CFG_RUN_TEST
run_tests();
#endif

startup_init();

// 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

KAllocManager_init();
KAllocManager_run_example();
// 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]);
}

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(" input filename to see file content");

while (1) {
shellPrintPrompt();
shellInputLine();
Expand Down
5 changes: 5 additions & 0 deletions impl-c/kernel/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "test.h"
#include "cfg.h"
#include "mm/startup.h"

void run_tests() { test_startup_alloc(); }
Loading