Skip to content

Commit 5629456

Browse files
authored
Documentation + Testing (#20)
* updated doxygen setting to include inline source code + class diagram * Added Doxygen documentation for memory management * Moved testing functions from memory.c to its own test file * Added tests directory as source build * added old doc in doxygen ignore * Move doxygen documentatiom from implementation to heafder file * Remove doxygen from public API + removed testing functions * Moved Doxygen documentation from implementation to header files * remove printf and use stdint library instead
1 parent b54b52a commit 5629456

File tree

14 files changed

+399
-349
lines changed

14 files changed

+399
-349
lines changed

Doxyfile

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ OUTPUT_DIRECTORY = docs
1313
INPUT = src include docs/pages README.md
1414
FILE_PATTERNS = *.c *.h *.md *.s *.ld
1515
RECURSIVE = YES
16-
EXCLUDE_PATTERNS = */tests/* */build/* */literature/*
16+
EXCLUDE_PATTERNS = */tests/* */build/* */literature/* */doc/*
1717

1818
#----------------------------------------------------------
1919
# Documentation Extraction
@@ -27,7 +27,7 @@ EXTRACT_STATIC = YES
2727
EXTRACT_LOCAL_CLASSES = YES
2828
INTERNAL_DOCS = YES
2929
SOURCE_BROWSER = YES
30-
INLINE_SOURCES = NO # Set to YES if you want code in docs
30+
INLINE_SOURCES = YES
3131

3232
#----------------------------------------------------------
3333
# Preprocessing / Macros
@@ -38,7 +38,9 @@ EXPAND_ONLY_PREDEF = NO
3838
PREDEFINED = __attribute__(x)= \
3939
asm(x)= \
4040
__asm__= \
41-
KERNEL=1
41+
KERNEL=1 \
42+
__packed \
43+
__aligned(x)
4244

4345
#----------------------------------------------------------
4446
# Warnings
@@ -64,6 +66,7 @@ DOT_IMAGE_FORMAT = svg
6466
CALL_GRAPH = YES
6567
CALLER_GRAPH = YES
6668
DOT_MULTI_TARGETS = YES
69+
CLASS_DIAGRAMS = YES
6770

6871
#----------------------------------------------------------
6972
# Markdown / Main Page

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
OUT_DIR := build/
2-
SRC_DIRS := src/kernel src/user
2+
SRC_DIRS := src/kernel src/user src/kernel/tests
33

44
# Find every .c in those dirs
55
SRCS := $(foreach d,$(SRC_DIRS),$(wildcard $(d)/*.c))

docs/pages/memory.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Memory Management
2+
3+
The memory management subsystem is responsible for handling the allocation,
4+
deallocation, and organization of memory within the kernel. It ensures that
5+
memory is used efficiently and safely, preventing leaks and corruption.
6+
7+
This subsystem provides a simple kernel heap allocator (`kmalloc`/`kfree`)
8+
and manages memory blocks using a linked list of headers.
9+
10+
## Design
11+
12+
- Implements a **first-fit heap allocator** for dynamic memory allocation.
13+
- Provides **public API functions**:
14+
- `kmalloc_init()` – Initialize the heap region.
15+
- `kmalloc()` – Allocate a memory block.
16+
- `kfree()` – Free a previously allocated block.
17+
- `kmalloc_get_head()` – Retrieve the head of the heap (mainly for testing).
18+
- Uses **linked list of headers** to track free and used memory blocks.
19+
- Performs **block splitting and merging** to reduce fragmentation.
20+
- Aligns allocations to `KMALLOC_ALIGN` for proper memory access.
21+
22+
## Usage Example
23+
24+
```c
25+
#include "memory.h"
26+
27+
extern char heap_start[];
28+
extern char heap_end[];
29+
30+
void kernel_main(void)
31+
{
32+
// Initialize the kernel heap
33+
kmalloc_init(heap_start, heap_end);
34+
35+
// Allocate 128 bytes
36+
void *ptr = kmalloc(128);
37+
if (!ptr)
38+
{
39+
// Handle allocation failure
40+
}
41+
42+
// Use memory
43+
char *data = (char*)ptr;
44+
data[0] = 'X';
45+
46+
// Free the memory
47+
kfree(ptr);
48+
}
49+
```
50+
> **Note**: Always initialize the heap before using `kmalloc`.
51+
52+
## Future Plans
53+
- Implement thread-safe operations for concurrent memory access.
54+
- Integrate virtual memory support for better isolation and protection.
55+
- Implement memory paging and swapping mechanisms.
56+
- Add support for memory-mapped files and devices.
57+
- Provide user-space memory management interfaces.

include/clear.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#pragma once
22

3+
/**
4+
* @brief Clears the terminal screen and moves the cursor to the home position.
5+
*/
36
void clear(void);
4-

include/interrupt.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,20 @@ extern "C"
3939
// VIC line number for Timer0/1 on Versatile
4040
#define IRQ_TIMER01 4
4141

42+
/**
43+
* @brief C-level IRQ handler called from assembly stub in start.s
44+
* Must clear the source interrupt and (for VIC) write VIC_VECTADDR to ack end of interrupt.
45+
*/
4246
void irq_handler(void);
4347
void irq_enable(void);
4448
void irq_disable(void);
4549

50+
/**
51+
* @brief VersatilePB SP804 timer clock is typically 1 MHz (can be overridden)
52+
*
53+
* @param tick_hz: desired tick frequency (e.g., 100)
54+
* @param timer_clk_hz: input clock to the SP804 (e.g., 1000000)
55+
*/
4656
void interrupts_init_timer0(uint32_t tick_hz, uint32_t timer_clk_hz);
4757

4858
static inline void timer0_start_periodic(uint32_t load)

include/memory.h

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#pragma once
22

33
#include <stddef.h>
4-
#include <stdint.h>
54

65
#ifdef __cplusplus
76
extern "C"
@@ -32,11 +31,76 @@ extern "C"
3231
struct header *prev; /**< Pointer to the previous block in the linked list. */
3332
};
3433

34+
/**
35+
* @brief Retrieves the head of the kmalloc allocation list.
36+
*
37+
* This function returns a pointer to the head of the memory allocation
38+
* list used by kmalloc. Mainly useful for testing current allocations.
39+
*
40+
* @return Pointer to the head of the kmalloc allocation list.
41+
* Returns NULL if the list is empty.
42+
*/
3543
struct header *kmalloc_get_head(void);
3644

45+
/**
46+
* @brief Initialize the kernel heap for dynamic memory allocation.
47+
*
48+
* This function sets up the initial heap region for `kmalloc`. It aligns
49+
* the start and end addresses according to the kernel alignment
50+
* requirements and initializes the first free memory block.
51+
*
52+
* @param start Pointer to the beginning of the heap memory region.
53+
* Must be less than `limit`.
54+
* @param limit Pointer to the end of the heap memory region.
55+
* Must be greater than `start`.
56+
*
57+
* @note If the heap range is invalid or too small, this function
58+
* will call `kernel_panic()`.
59+
*
60+
* @note The pointers `start` and `limit` are marked `restrict` to indicate
61+
* that their memory regions do not overlap, allowing the compiler
62+
* to optimize pointer arithmetic safely.
63+
*/
3764
void kmalloc_init(void *start, void *limit);
65+
66+
/**
67+
* @brief Allocate a block of memory from the kernel heap.
68+
*
69+
* This function searches the heap for the first free block that is large
70+
* enough to satisfy the requested `size`. If the block is larger than needed,
71+
* it is split into an allocated block and a new free block.
72+
*
73+
* @param size The number of bytes to allocate. Must be > 0.
74+
*
75+
* @return Pointer to the usable memory area of the allocated block, or
76+
* NULL if `size` is zero.
77+
*
78+
* @warning If no suitable block is found, the function will call `kernel_panic`.
79+
* @note The returned pointer points immediately after the block header.
80+
*
81+
*/
3882
void* kmalloc(size_t size);
83+
84+
/**
85+
* @brief Free a previously allocated block of memory.
86+
*
87+
* Marks the block as free and attempts to merge it with adjacent free blocks
88+
* to reduce fragmentation.
89+
*
90+
* @param block Pointer to the memory previously returned by `kmalloc`.
91+
* Must not be NULL.
92+
*
93+
* @note If `block` is NULL, the function does nothing.
94+
* @note If `block` does not correspond to a valid allocated block,
95+
* the function calls `kernel_panic`.
96+
*/
3997
void kfree(void *block);
98+
99+
/**
100+
* @brief Entry point for testing `kmalloc` and `kfree`.
101+
*
102+
* @return int Return 0 on tests passing, 1 on tests failure.
103+
*/
40104
int kmalloc_test(void);
41105
#ifdef __cplusplus
42106
}

include/printf.h

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ extern "C" {
2020
#endif
2121

2222
/**
23-
* @enum fmt_state_t
24-
* @brief Finite-state machine for parsing format strings.
25-
*
26-
* The printf parser moves between these states as it consumes characters.
23+
* @enum fmt_state_t
24+
* @brief Finite-state machine for parsing format strings.
25+
*
26+
* The printf parser moves between these states as it consumes characters.
2727
*/
2828
typedef enum {
2929
FMT_TEXT, /**< Normal character output. */
@@ -32,7 +32,7 @@ extern "C" {
3232
} fmt_state_t;
3333

3434
/**
35-
* @brief Bit flags controlling number formatting.
35+
* @brief Bit flags controlling number formatting.
3636
*/
3737
enum {
3838
FLAG_LONG = 1 << 0, /**< 'l' length modifier (long / long long). */
@@ -42,48 +42,48 @@ extern "C" {
4242
};
4343

4444
/**
45-
* @struct Format_State
46-
* @brief Stores the current numeric value and formatting flags.
47-
*
48-
* This structure is passed to integer-formatting functions during printf
49-
* processing. It represents the transient state for one format specifier.
45+
* @struct Format_State
46+
* @brief Stores the current numeric value and formatting flags.
47+
*
48+
* This structure is passed to integer-formatting functions during printf
49+
* processing. It represents the transient state for one format specifier.
5050
*/
5151
typedef struct {
5252
unsigned long long num; /**< The numeric value to be printed. */
5353
uint8_t flags; /**< Bitmask of FLAG_* constants describing format. */
5454
} Format_State;
5555

5656
/**
57-
* @brief Prints a null-terminated string over UART.
58-
*
59-
* @param s The string to output. If NULL, no output occurs.
57+
* @brief Transmit a null-terminated string over UART.
58+
*
59+
* @param s The string to output. If NULL, no output occurs.
6060
*/
6161
void puts(const char *s);
6262

6363
/**
64-
* @brief Prints a formatted string to the UART output.
65-
*
66-
* @param fmt Format string (supports %c, %s, %d, %u, %x, %X, %p, %%).
67-
* @param ... Variable arguments matching the format specifiers.
68-
*
69-
* This function supports a minimal subset of standard C printf:
70-
* - Signed/unsigned integers (`%d`, `%u`)
71-
* - Hexadecimal (`%x`, `%X`)
72-
* - Pointers (`%p`)
73-
* - Characters (`%c`)
74-
* - Strings (`%s`)
75-
* - Length modifier (`%l`)
64+
* @brief Prints a formatted string to the UART output.
65+
*
66+
* @param fmt Format string (supports %c, %s, %d, %u, %x, %X, %p, %%).
67+
* @param ... Variable arguments matching the format specifiers.
68+
*
69+
* This function supports a minimal subset of standard C printf:
70+
* - Signed/unsigned integers (`%d`, `%u`)
71+
* - Hexadecimal (`%x`, `%X`)
72+
* - Pointers (`%p`)
73+
* - Characters (`%c`)
74+
* - Strings (`%s`)
75+
* - Length modifier (`%l`)
7676
*/
7777
void printf(const char *fmt, ...);
7878

7979
/**
80-
* @brief Reads a line of text from UART into the given buffer.
81-
*
82-
* @param buffer Destination buffer.
83-
* @param length Maximum buffer length (including null terminator).
84-
*
85-
* Blocks until a newline or carriage return is received.
86-
* Supports backspace editing and echoes input characters.
80+
* @brief Reads a line of text from UART into the given buffer.
81+
*
82+
* @param buffer Destination buffer.
83+
* @param length Maximum buffer length (including null terminator).
84+
*
85+
* @note Blocks until a newline or carriage return is received.
86+
* Supports backspace editing and echoes input characters.
8787
*/
8888
void getlines(char *restrict buffer, size_t length);
8989

include/string.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,22 @@ extern "C"
77
{
88
#endif
99

10+
/**
11+
* @brief Compares two null-terminated strings lexicographically.
12+
*
13+
* @param str_1 Pointer to the first string to compare.
14+
* @param str_2 Pointer to the second string to compare.
15+
*
16+
* @return int 0 if strings are equal, -1 if `str_1` < `str_2`, 1 if `str_1` > `str_2`.
17+
*/
1018
int strcmp(const char *str_1, const char *str_2);
19+
20+
/**
21+
* @brief Calculates the length of a null-terminated string.
22+
*
23+
* @param str Pointer to the null-terminated string to be measured.
24+
* @return The number of characters in the string, excluding the null terminator.
25+
*/
1126
size_t strlen(const char *str);
1227

1328
#ifdef __cplusplus

src/kernel/interrupt.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@
55

66
volatile uint64_t systicks = 0;
77

8-
/**
9-
* @brief VersatilePB SP804 timer clock is typically 1 MHz (can be overridden)
10-
*
11-
* @param tick_hz: desired tick frequency (e.g., 100)
12-
* @param timer_clk_hz: input clock to the SP804 (e.g., 1000000)
13-
*/
148
void interrupts_init_timer0(uint32_t tick_hz, uint32_t timer_clk_hz)
159
{
1610
if (tick_hz == 0 || timer_clk_hz == 0)
@@ -33,10 +27,6 @@ void interrupts_init_timer0(uint32_t tick_hz, uint32_t timer_clk_hz)
3327
vic_enable_timer01_irq();
3428
}
3529

36-
/**
37-
* @brief C-level IRQ handler called from assembly stub in start.s
38-
* Must clear the source interrupt and (for VIC) write VIC_VECTADDR to ack end of interrupt.
39-
*/
4030
void irq_handler(void)
4131
{
4232
// Check Timer0 MIS (masked interrupt status)

0 commit comments

Comments
 (0)