diff options
-rw-r--r-- | kernel/boot/init/boot.s | 6 | ||||
-rw-r--r-- | kernel/include/common.h | 13 | ||||
-rw-r--r-- | kernel/include/mm/virtual_mm.h | 5 | ||||
-rw-r--r-- | kernel/kernel/kernel.c | 4 | ||||
-rw-r--r-- | kernel/mm/physical_mm/physical_mm.c | 2 | ||||
-rw-r--r-- | kernel/mm/virtual_mm/virtual_mm.c | 43 |
6 files changed, 48 insertions, 25 deletions
diff --git a/kernel/boot/init/boot.s b/kernel/boot/init/boot.s index a1a6ee5..8a134c4 100644 --- a/kernel/boot/init/boot.s +++ b/kernel/boot/init/boot.s @@ -28,9 +28,9 @@ /* Declare a multiboot header that marks the program as a kernel. These are magic values that are documented in the multiboot standard. The bootloader will - search for this signature in the first 8 KiB of the kernel file, aligned at a + search for this signature in the first 8KiB of the kernel file, aligned at a 32-bit boundary. The signature is in its own section so the header can be - forced to be within the first 8 KiB of the kernel file. + forced to be within the first 8KiB of the kernel file. */ .section .multiboot .align 4 @@ -53,7 +53,7 @@ .section .bss .align 16 stack_bottom: -.skip 16384 # 16 KiB +.skip 16384 # 16KiB stack_top: /* diff --git a/kernel/include/common.h b/kernel/include/common.h index 2e1faa3..7f7f50f 100644 --- a/kernel/include/common.h +++ b/kernel/include/common.h @@ -36,4 +36,17 @@ halt(); \ } +#define ASSERT(condition) \ + { \ + if (!(condition)) { \ + printk("ASSERTION FAILED", \ + "[%s]:%lu IS RENDERED FALSE.", \ + __func__, \ + __LINE__); \ + /* TODO: We should probably remove this exit() eventually */ \ + exit(); \ + halt(); \ + } \ + } + #endif diff --git a/kernel/include/mm/virtual_mm.h b/kernel/include/mm/virtual_mm.h index 6bd5178..c0eb237 100644 --- a/kernel/include/mm/virtual_mm.h +++ b/kernel/include/mm/virtual_mm.h @@ -40,7 +40,7 @@ #define PDE_FRAME(x) ((x) &0xFFFFF000) #define PDE_IS_PRESENT(pd_entry) ((*pd_entry) & 1) -#define GET_PDE_FRAME(virtual_address) (((uint32_t) virtual_address) >> 22) +#define GET_PD_INDEX(virtual_address) (((uint32_t) virtual_address) >> 22) #define PDE_GET_TABLE(pd_entry) ((*pd_entry) & ~0xfff) #define PTE_PRESENT(x) x @@ -58,7 +58,8 @@ #define PTE_FRAME(x) ((x) << 12) #define PTE_IS_PRESENT(pt_entry) ((*pt_entry) & 1) -#define GET_PTE_FRAME(virtual_address) \ +#define GET_PTE_FRAME(x) ((x) >> 12) +#define GET_PT_INDEX(virtual_address) \ ((((uint32_t) virtual_address) >> 12) & 0x3ff) #define ADD_ATTRIB(entry, attribute) (*entry |= (attribute)) diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c index f41f48e..7a7f95f 100644 --- a/kernel/kernel/kernel.c +++ b/kernel/kernel/kernel.c @@ -48,8 +48,8 @@ kernel_main(uint32_t magic, multiboot_info_t *multiboot_info) printk("\nKernel", "Started."); - virtual_mm_map_page((void *) 0x0C00000, (void *) 0x3000); - virtual_mm_find_free_virtual_addresses(2); + // virtual_mm_map_page((void *) 0x0C00000, (void *) 0x3000); + virtual_mm_find_free_virtual_addresses(10000); exit(); halt(); /* If exit() fails (on real hardware) */ diff --git a/kernel/mm/physical_mm/physical_mm.c b/kernel/mm/physical_mm/physical_mm.c index ed89316..801ce7b 100644 --- a/kernel/mm/physical_mm/physical_mm.c +++ b/kernel/mm/physical_mm/physical_mm.c @@ -72,7 +72,7 @@ physical_mm_initialize_region(uint32_t start, uint32_t length) if (physical_mm_test_bit(bit, memory_map)) physical_mm_set_usable(bit++, &total_free_blocks, memory_map); - /* First block is always used (first 64 KiB) */ + /* First block is always used (first 64KiB) */ if (!physical_mm_test_bit(0, memory_map)) physical_mm_set_used(0, &total_free_blocks, memory_map); } diff --git a/kernel/mm/virtual_mm/virtual_mm.c b/kernel/mm/virtual_mm/virtual_mm.c index 929b37d..4153065 100644 --- a/kernel/mm/virtual_mm/virtual_mm.c +++ b/kernel/mm/virtual_mm/virtual_mm.c @@ -89,7 +89,7 @@ virtual_mm_initialize(void) void virtual_mm_map_page(void *physical_address, void *virtual_address) { - uint32_t *pd_entry = ¤t_page_directory[GET_PDE_FRAME(virtual_address)]; + uint32_t *pd_entry = ¤t_page_directory[GET_PD_INDEX(virtual_address)]; uint32_t *table = 0; /* If the pd_entry isn't present, allocate a block for it, zero the table, @@ -106,16 +106,18 @@ virtual_mm_map_page(void *physical_address, void *virtual_address) } else table = (uint32_t *) PDE_GET_TABLE(pd_entry); - uint32_t *pt_entry = &table[GET_PTE_FRAME(virtual_address)]; - if (PTE_IS_PRESENT(pt_entry)) - ASSERT_NOT_REACHED(); /* TODO: Mapping previously mapped memory */ + uint32_t *pt_entry = &table[GET_PT_INDEX(virtual_address)]; + if (PTE_IS_PRESENT(pt_entry)) { + printk("debug", "Mapping previously mapped memory: 0x%x", pt_entry); + ASSERT_NOT_REACHED(); + } *pt_entry = PTE_FRAME((uint32_t) physical_address) | PTE_PRESENT(1) | PTE_WRITABLE(1); } ALWAYS_INLINE uint32_t * -get_table(uint32_t *pd_entry) +get_or_make_table(uint32_t *pd_entry) { uint32_t *table; if (!PDE_IS_PRESENT(pd_entry)) { @@ -123,8 +125,8 @@ get_table(uint32_t *pd_entry) if (!table) ASSERT_NOT_REACHED(); - for (uint32_t _ = 0; _ < 1024; _++) - table[_] = 0; + for (uint32_t i = 0; i < 1024; i++) + table[i] = 0x0; *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1); } else @@ -136,33 +138,38 @@ get_table(uint32_t *pd_entry) ALWAYS_INLINE void virtual_mm_find_free_virtual_addresses(uint32_t n) { - for (uint32_t i = 0; i < PAGE_DIRECTORY_SIZE; i++) { - uint32_t current_pd_index = i; - uint32_t *pd_entry = ¤t_page_directory[current_pd_index]; - uint32_t *table = get_table(pd_entry); + /* Skip the first page directory, we don't wanna touch the first 4MiB. */ + for (uint32_t i = 1; i < PAGE_DIRECTORY_SIZE; i++) { + uint32_t *pd_entry = ¤t_page_directory[i]; + uint32_t *table = get_or_make_table(pd_entry); for (uint32_t j = 0; j < PAGE_TABLE_SIZE; j++) { uint32_t *pt_entry = &table[j]; if (PTE_IS_PRESENT(pt_entry)) continue; - /* We found our starting pt_entry */ + /* We found our starting pt_entry */ printk("debug", "Starting: 0x%x", pt_entry); uint32_t count = 0; for (uint32_t k = j; k <= PAGE_TABLE_SIZE; k++) { /* If we overflow, switch to the consecutive page directory entry */ if (k == PAGE_TABLE_SIZE) { - pd_entry = ¤t_page_directory[++current_pd_index]; - table = get_table(pd_entry); + if (++i == PAGE_DIRECTORY_SIZE) + ASSERT_NOT_REACHED(); /* Ran out of pd_entries */ + + pd_entry = ¤t_page_directory[i]; printk("debug", "Switching pd_entry: 0x%x", pd_entry); + + table = get_or_make_table(pd_entry); k = 0; } + /* If page table entry is already used, break from the current loop */ uint32_t *pt_entry = &table[k]; if (PTE_IS_PRESENT(pt_entry)) { - count = 0; - current_pd_index = i; - pd_entry = ¤t_page_directory[current_pd_index]; + /* Since we have some used address at some point between j and count, + * we can't find n consecutive free addresses in between j and the + * used block (j + count + 1) */ j += count; break; } @@ -170,6 +177,8 @@ virtual_mm_find_free_virtual_addresses(uint32_t n) // printk("debug", "Found page: 0x%x", &table[k]); count++; if (count == n) { + /* TODO: Convert this into a virtual_address using the pd_index & + * pt_index */ printk("debug", "Found starting page at: 0x%x", &table[j]); return; } |