Skip to content

Commit b962bf3

Browse files
author
Louis Jenkins
committed
Finally finished implementation of memory management and adequate tests.
The heap is actually causing a page fault when I use too much RAM, but I'm not sure if it is because I reach the end of the space available faster than anticipated or what. Regardless, it is in a very satisfactory state.
1 parent 51e4de2 commit b962bf3

File tree

17 files changed

+229
-693
lines changed

17 files changed

+229
-693
lines changed

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ The below depicts an early "schedule" or rather a path I will be taking in terms
1212
- [x] Interrupts (IRQ + ISR)
1313
- [x] VGA Display Driver
1414
- [x] Keyboard Driver
15-
- [ ] Memory Management (Physical + Virtual)
16-
- [ ] Interactive Shell
15+
- [x] Memory Management (Physical + Virtual)
16+
- [x] Higher Half Kernel
1717
- [ ] File System
18+
- [ ] Process Creation and Managements
1819
- [ ] Multitasking and Scheduling
1920
- [ ] Networking
20-
- [ ] Process Creation and Managements
2121
- [ ] ELF Binary Support
22+
- [ ] Interactive Shell
2223
- [ ] Graphical User Interfaces
2324

2425
#Progress Update & Changelog
@@ -47,4 +48,11 @@ a significant amount of work and should be pushed to master.
4748

4849
Lastly, I also added a nice logger macro, `KLOG`, and panic macro, `KPANIC`.
4950

50-
![Screenshot](/ram_and_kbd.PNG)
51+
![Screenshot](/ram_and_kbd.PNG)
52+
53+
54+
## Version .002
55+
56+
It is FINALLY here! I have implemented not only memory management (paging and a heap allocator), but even converted to a higher-half kernel approach, which was also easier, surprisingly, than a normal identity-mapped system. I've also fixed up the tests and their output format to better portray the significance of the initialization of the kernel thus far. I am very satisfied with what I have done, but unfortunately, I have to attend to another project for the time being.
57+
58+
![Screenshot](/all_tests_and_heap.PNG)

all_tests_and_heap.PNG

70.8 KB
Loading

src/kernel/.sym

Whitespace-only changes.

src/kernel/debug_kernel.sh

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/kernel/include/helpers.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
#include <stdio.h>
55
#include <stdbool.h>
66

7+
#define MAX(x, y) ((x) > (y) ? (x) : (y))
8+
9+
#define MIN(x, y) ((x) > (y) ? (y) : (x))
10+
711
#define HALT \
812
do { \
913
asm volatile ("cli"); \

src/kernel/include/kernel/multiboot.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,12 @@ struct multiboot_mmap {
6363

6464
static bool multiboot_RAM(struct multiboot_info *mbinfo, uint32_t *start, uint32_t *end) {
6565
bool found = false;
66-
printf("Flags: %d\n", mbinfo->flags);
6766
// Check if there is a memory mapping available
6867
if (mbinfo->flags & (1 << 6)) {
69-
KLOG("MMAP Entries: %d", mbinfo->mmap_length / 24);
68+
// KLOG("MMAP Entries: %d", mbinfo->mmap_length / 24);
7069
struct multiboot_mmap *mmap = (struct multiboot_mmap *) (0xC0000000 + mbinfo->mmap_addr);
7170
while((uint32_t) mmap - 0xC0000000 < (mbinfo->mmap_addr + mbinfo->mmap_length)) {
72-
KLOG("MMAP Entry: {Type: %s, Start: %x, Length: %x}", mmap->type == MULTIBOOT_MMAP_RAM ? "RAM" : "RESERVED", mmap->start_low, mmap->length_low);
71+
// KLOG("MMAP Entry: {Type: %s, Start: %x, Length: %x}", mmap->type == MULTIBOOT_MMAP_RAM ? "RAM" : "RESERVED", mmap->start_low, mmap->length_low);
7372
// Jackpot... (The OS is 32-bit, so there is no upper currently.)
7473
if (mmap->type == MULTIBOOT_MMAP_RAM) {
7574
*start = mmap->start_low;

src/kernel/include/mm/page.h

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/kernel/kernel.sym

-39.4 KB
Binary file not shown.

src/kernel/kernel/kernel.c

Lines changed: 121 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include <stdbool.h>
22
#include <stddef.h>
33
#include <stdint.h>
4+
#include <string.h>
45
#include <stdio.h>
56

67
#define __IS_MOLTAROS 1
@@ -13,62 +14,123 @@
1314
#include <include/drivers/rtc.h>
1415
#include <include/kernel/multiboot.h>
1516
#include <include/kernel/logger.h>
16-
#include <include/mm/page.h>
1717
#include <include/kernel/mem.h>
1818
#include <include/helpers.h>
1919

2020
uint32_t PHYSICAL_MEMORY_END;
2121
uint32_t PHYSICAL_MEMORY_START;
2222

2323
size_t ticks_x, ticks_y, time_x, time_y;
24+
static bool timer_done = false;
2425

2526
void kernel_init(struct multiboot_info *info) {
2627
vga_init();
28+
KLOG("Virtual Memory (Paging) Initialized...");
29+
KLOG("Video Graphics Array (VGA) Initialized...");
2730
gdt_init();
31+
KLOG("Global Descriptor Table (GDT) Initialized...");
2832
idt_init();
33+
KLOG("Interrupt Descriptor Table (IDT) Initialized...");
2934
timer_init();
30-
bool retval = multiboot_RAM(info, &PHYSICAL_MEMORY_START, &PHYSICAL_MEMORY_END);
31-
KLOG("RAM Stats: Available: %d, Start: %d, End: %d", retval, PHYSICAL_MEMORY_START, PHYSICAL_MEMORY_END);
32-
// page_init();
33-
// KFRAME;
35+
KLOG("System Timer (PIT) Initialized...");
36+
if (!multiboot_RAM(info, &PHYSICAL_MEMORY_START, &PHYSICAL_MEMORY_END)) {
37+
KPANIC("Failed to detect physical memory (RAM)!!!");
38+
}
39+
KLOG("Detected => RAM {Start: %d, End: %d, Total: %d}", PHYSICAL_MEMORY_START, PHYSICAL_MEMORY_END, PHYSICAL_MEMORY_END - PHYSICAL_MEMORY_START);
40+
mem_init();
41+
KLOG("Memory Heap and Allocators (kmalloc & kfree) Initialized...");
3442
}
3543

36-
static void kernel_tick(struct registers *UNUSED(regs)) {
37-
static uint32_t ticks = 0;
38-
39-
vga_set_x(ticks_x);
40-
vga_set_y(ticks_y);
41-
printf("%d", ++ticks);
44+
// Memory test that purposefully performs allocation-heavy allocations to test the state of the heap and virtual memory
45+
// implementation. It works by filling up half of the amount of RAM with a deterministic sequence (for debugging) of
46+
// values. On each iteration, we resize by allocating and copying into a new container.
47+
static void memtest() {
48+
uint32_t total_memory = PHYSICAL_MEMORY_END - PHYSICAL_MEMORY_START;
49+
uint32_t total_alloc = 0;
50+
uint32_t alloc_size = 1;
51+
uint32_t **allocated_data = NULL;
52+
uint32_t num_alloc = 1;
53+
54+
printf("Allocated: ");
55+
uint32_t x = vga_get_x();
56+
uint32_t y = vga_get_y();
57+
printf("%d/%d", total_alloc, total_memory / 4);
58+
59+
// TODO: Stops working at 1/2 RAM used.
60+
while (total_alloc < (total_memory / 4)) {
61+
// Allocate new storage
62+
uint32_t **new_data = kmalloc(sizeof(void *) * num_alloc);
63+
memcpy(new_data, allocated_data, sizeof(void *) * (num_alloc - 1));
64+
kfree(allocated_data);
65+
allocated_data = new_data;
66+
67+
allocated_data[num_alloc - 1] = kmalloc(alloc_size);
68+
*allocated_data[num_alloc - 1] = alloc_size;
69+
total_alloc += alloc_size;
70+
alloc_size = MIN(2 * 1024 * 1024, alloc_size * 2);
71+
num_alloc++;
72+
73+
vga_set_x(x);
74+
vga_set_y(y);
75+
printf("%d/%d", total_alloc, total_memory / 4);
76+
}
4277

43-
if(ticks % 1000 == 0) {
44-
vga_set_x(time_x);
45-
vga_set_y(time_y);
46-
rtc_print();
47-
vga_putc(' ');
78+
alloc_size = 1;
79+
num_alloc = 0;
80+
81+
printf("\nTesting and Deallocating: ");
82+
x = vga_get_x();
83+
y = vga_get_y();
84+
printf("%d/%d", total_alloc, total_memory / 4);
85+
86+
while (total_alloc) {
87+
uint32_t *val = allocated_data[num_alloc];
88+
if (*val != alloc_size) {
89+
KPANIC("Bad Value for Index: %d, Expected: %d, Received: %d, Address: %x", num_alloc, alloc_size, *val, val);
90+
}
91+
92+
total_alloc -= alloc_size;
93+
num_alloc++;
94+
alloc_size = MIN(2 * 1024 * 1024, alloc_size * 2);
95+
kfree(val);
96+
vga_set_x(x);
97+
vga_set_y(y);
98+
printf("%d/%d", total_alloc, total_memory / 4);
4899
}
49100

50-
if (ticks > 0 && ticks % 10000 == 0) {
51-
int i = *(int *) 5000000;
52-
i++;
101+
printf("\n");
102+
}
103+
104+
static void kernel_tick(struct registers *UNUSED(regs)) {
105+
static uint32_t ticks = 0;
106+
107+
if (ticks == 10000) {
108+
timer_done = true;
109+
} else {
110+
vga_set_x(ticks_x);
111+
vga_set_y(ticks_y);
112+
printf("%d", ++ticks);
53113
}
54114
}
55115

56-
static void kernel_clock_test() {
57-
printf("Operating System: MoltarOS\nKernel: Moltar\nVersion: 0.001a\nTime: ");
116+
static void timer_test() {
58117
time_x = vga_get_x();
59118
time_y = vga_get_y();
60-
rtc_print();
61119

62-
printf("\nTesting Clock at 1KHz...\nTicks: 0");
120+
printf("Ticks: 0");
63121
ticks_x = vga_get_x() - 1;
64122
ticks_y = vga_get_y();
65123

66124
timer_set_handler(1000, kernel_tick);
67125

68126
asm volatile ("sti");
69-
70-
while(true)
127+
while(!timer_done)
71128
asm volatile ("hlt");
129+
130+
// init currently only sets a default callback, so this is adequate
131+
timer_init();
132+
133+
printf("\n");
72134
}
73135

74136
static void kernel_keyboard_test() {
@@ -85,13 +147,38 @@ void kernel_main(void) {
85147
// kernel_clock_test();
86148
// KLOG("Initiating Keyboard Test...");
87149
// kernel_keyboard_test();
88-
KLOG("Initializing Heap...");
89-
mem_init();
90-
KLOG("Allocating memory...");
91-
char *str = kmalloc(3);
92-
KLOG("Writing to memory...");
93-
str[0] = 'H';
94-
str[1] = 'i';
95-
str[2] = '\0';
96-
KLOG("String: %s", str);
150+
printf("Memory Test (%d Bytes): ", (PHYSICAL_MEMORY_END - PHYSICAL_MEMORY_START) / 4);
151+
uint32_t x = vga_get_x();
152+
uint32_t y = vga_get_y();
153+
printf("START\n");
154+
memtest();
155+
uint32_t tmpx = vga_get_x();
156+
uint32_t tmpy = vga_get_y();
157+
vga_set_x(x);
158+
vga_set_y(y);
159+
KLOG("SUCCESS!");
160+
vga_set_x(tmpx);
161+
vga_set_y(tmpy);
162+
163+
printf("SysTimer Test (1KHz): ");
164+
x = vga_get_x();
165+
y = vga_get_y();
166+
printf("START\n");
167+
timer_test();
168+
tmpx = vga_get_x();
169+
tmpy = vga_get_y();
170+
vga_set_x(x);
171+
vga_set_y(y);
172+
KLOG("SUCCESS!");
173+
vga_set_x(tmpx);
174+
vga_set_y(tmpy);
175+
176+
KLOG("Tests Complete!");
177+
keyboard_init();
178+
KLOG("Keyboard Initialized... Press any Button...");
179+
180+
// Loop infinitely
181+
while (true) {
182+
asm volatile ("hlt");
183+
}
97184
}

src/kernel/kernel/mem.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ void mem_init() {
1313
// Initialize modules we depend on
1414
memheap_init(&kheap);
1515
alloc_init();
16-
17-
// Allocate the first chunk of memory for the kernel heap
18-
more_memory();
1916
}
2017

2118
void *kmalloc(size_t sz) {
@@ -31,9 +28,15 @@ void *kmalloc(size_t sz) {
3128
data = memheap_alloc(&kheap, sz);
3229
}
3330

31+
if (!data) {
32+
KPANIC("Heap Allocation Failed!");
33+
}
34+
3435
return data;
3536
}
3637

3738
void kfree(void *ptr) {
38-
memheap_free(&kheap, ptr);
39+
if (ptr) {
40+
memheap_free(&kheap, ptr);
41+
}
3942
}

0 commit comments

Comments
 (0)