aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMarvin Borner2021-02-28 13:40:45 +0100
committerMarvin Borner2021-02-28 13:40:45 +0100
commitd50d3aeaaeaca4a75a807759a54d1d6ae8b5bce4 (patch)
tree5d606caef5599ef8a5c1383560202ca9b89b681e /kernel
parent2a2f12c64a99749b05507d80ba3ee728d5ed76e1 (diff)
Fixed memory mapping detection
Diffstat (limited to 'kernel')
-rw-r--r--kernel/Makefile2
-rw-r--r--kernel/features/memory.c48
-rw-r--r--kernel/inc/memory.h3
-rw-r--r--kernel/link.ld3
-rw-r--r--kernel/main.c6
5 files changed, 39 insertions, 23 deletions
diff --git a/kernel/Makefile b/kernel/Makefile
index 8f090d1..6763185 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -35,5 +35,5 @@ all: compile
compile: $(COBJS)
@mkdir -p ../build/
- @$(LD) -N -ekernel_main -Ttext 0x00050000 -o ../build/kernel.elf -L../build/ $+ -lk
+ @$(LD) -N -z undefs -ekernel_main -Ttext 0x00050000 -o ../build/kernel.elf -L../build/ $+ -lk
@$(LD) -N -Tlink.ld -o ../build/kernel.bin -L../build/ $+ -lk
diff --git a/kernel/features/memory.c b/kernel/features/memory.c
index aa861e1..f8e183a 100644
--- a/kernel/features/memory.c
+++ b/kernel/features/memory.c
@@ -104,8 +104,8 @@ void physical_free(u32 addr, u32 n)
#define PDI(vaddr) ((vaddr) >> 22)
#define PTI(vaddr) (((vaddr) >> 12) & 0x03ff)
-struct page_dir kernel_dir ALIGNED(PAGE_SIZE) = { 0 };
-struct page_table kernel_tables[256] ALIGNED(PAGE_SIZE) = { 0 };
+static struct page_dir kernel_dir ALIGNED(PAGE_SIZE) = { 0 };
+static struct page_table kernel_tables[256] ALIGNED(PAGE_SIZE) = { 0 };
u8 virtual_present(struct page_dir *dir, u32 vaddr)
{
@@ -217,11 +217,8 @@ void virtual_free(struct page_dir *dir, struct memory_range virtual_range)
* Memory wrapper
*/
-/* extern u32 kernel_start; */
-/* extern u32 kernel_end; */
-// TODO!
-u32 kernel_start = 0x50000;
-u32 kernel_end = 0xa0000;
+extern u32 kernel_start;
+extern u32 kernel_end;
struct memory_range memory_range_from_address(u32 base, u32 size)
{
@@ -353,12 +350,12 @@ struct page_dir *memory_dir_create(void)
void memory_dir_destroy(struct page_dir *dir)
{
- for (u32 i = 256; i < 1024; i++) {
+ for (u32 i = 256; i < PAGE_COUNT; i++) {
union page_dir_entry *dir_entry = &dir->entries[i];
if (dir_entry->bits.present) {
struct page_table *table =
(struct page_table *)(dir_entry->bits.address * PAGE_SIZE);
- for (u32 j = 0; j < 1024; j++) {
+ for (u32 j = 0; j < PAGE_COUNT; j++) {
union page_table_entry *table_entry = &table->entries[j];
if (table_entry->bits.present)
physical_free(table_entry->bits.address * PAGE_SIZE, 1);
@@ -375,9 +372,8 @@ void memory_dir_switch(struct page_dir *dir)
paging_switch_dir(virtual_to_physical(&kernel_dir, (u32)dir));
}
-void memory_initialize(void)
+void memory_initialize(struct mem_info *mem_info)
{
- memset(memory, 0xff, PAGE_COUNT * PAGE_COUNT / 8);
for (u32 i = 0; i < 256; i++) {
union page_dir_entry *entry = &kernel_dir.entries[i];
entry->bits.present = 1;
@@ -386,23 +382,43 @@ void memory_initialize(void)
entry->bits.address = (u32)&kernel_tables[i] / PAGE_SIZE;
}
- // TODO: Loop over mmap and set free
+ // Detect memory using E820 memory map
+ for (struct mmap_boot *p = mem_info->start; (u32)(p - mem_info->start) < mem_info->size;
+ p++) {
+ if (p->hbase || !p->acpi || !p->type)
+ continue;
+
+ u32 size = p->lsize;
+ if (p->hsize)
+ size = U32_MAX;
+
+ if (p->type == MEMORY_AVAILABLE) {
+ physical_set_free(p->lbase, size / PAGE_SIZE);
+ memory_total += size;
+ } else if (p->type == MEMORY_DEFECT) {
+ printf("Defect memory at 0x%x-0x%x!\n", p->lbase, p->lbase + size);
+ }
+ }
memory_used = 0;
- memory_total = 100 << 20; // 100Megs?
+ printf("Detected memory: %dKiB (%dMiB)\n", memory_total >> 10, memory_total >> 20);
memory_map_identity(&kernel_dir, kernel_memory_range(), MEMORY_NONE);
+
+ // Unmap NULL byte/page
virtual_free(&kernel_dir, memory_range(0, PAGE_SIZE));
physical_set_used(0, 1);
+
memory_dir_switch(&kernel_dir);
- printf("OK!\n");
+ printf("Enabling...\n");
paging_enable();
+ printf("Enabled!\n");
}
#define HEAP_START 0x00f00000
-void paging_install(void)
+void paging_install(struct mem_info *mem_info)
{
heap_init(HEAP_START);
- memory_initialize();
+ memory_initialize(mem_info);
printf("OK!\n");
}
diff --git a/kernel/inc/memory.h b/kernel/inc/memory.h
index 4647c3e..812b052 100644
--- a/kernel/inc/memory.h
+++ b/kernel/inc/memory.h
@@ -3,6 +3,7 @@
#ifndef PAGING_H
#define PAGING_H
+#include <boot.h>
#include <def.h>
/**
@@ -60,7 +61,7 @@ struct page_dir {
union page_dir_entry entries[PAGE_COUNT];
} PACKED;
-void paging_install(void);
+void paging_install(struct mem_info *mem_info);
/**
* Memory wrappers
diff --git a/kernel/link.ld b/kernel/link.ld
index e63bd71..5a63e33 100644
--- a/kernel/link.ld
+++ b/kernel/link.ld
@@ -5,9 +5,8 @@ phys = 0x00050000;
SECTIONS
{
- kernel_start = .;
-
.text phys : AT(phys) {
+ kernel_start = .;
code = .;
*(.text)
*(.rodata)
diff --git a/kernel/main.c b/kernel/main.c
index 4d8165f..16ae619 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -18,15 +18,15 @@
struct vid_info *boot_passed;
-void kernel_main(struct vid_info *vid_info); // Decl
-void kernel_main(struct vid_info *vid_info)
+void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info); // Decl
+void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
{
// Serial connection
serial_install();
serial_print("\nKernel was compiled at " __TIME__ " on " __DATE__ "\n");
serial_print("Serial connected.\n");
- paging_install();
+ paging_install(mem_info);
boot_passed = vid_info;