aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kernel/include/mm/physical_mm.h4
-rw-r--r--kernel/include/mm/virtual_mm.h2
-rw-r--r--kernel/kernel/kernel.c3
-rw-r--r--kernel/mm/physical_mm/physical_mm.c4
-rw-r--r--kernel/mm/virtual_mm/virtual_mm.c64
5 files changed, 73 insertions, 4 deletions
diff --git a/kernel/include/mm/physical_mm.h b/kernel/include/mm/physical_mm.h
index 6befcb0..7ad97d9 100644
--- a/kernel/include/mm/physical_mm.h
+++ b/kernel/include/mm/physical_mm.h
@@ -29,12 +29,12 @@
#define BITMAP_ENTRY_SIZE 32
-/* TODO: This is the maximum number of blocks for a 4GiB system. */
+/* This is the maximum number of blocks for a 4GiB system. */
#define MAX_BLOCKS 1048576
void physical_mm_init(void);
-uint32_t physical_mm_find_first_free_block(void);
+uint32_t physical_mm_find_free_block(void);
void *physical_mm_allocate_block(void);
void physical_mm_free_block(void *physical_address);
diff --git a/kernel/include/mm/virtual_mm.h b/kernel/include/mm/virtual_mm.h
index 980e809..6bd5178 100644
--- a/kernel/include/mm/virtual_mm.h
+++ b/kernel/include/mm/virtual_mm.h
@@ -83,4 +83,6 @@ void virtual_mm_initialize(void);
*/
void virtual_mm_map_page(void *physical_address, void *virtual_address);
+void virtual_mm_find_free_virtual_addresses(uint32_t n);
+
#endif
diff --git a/kernel/kernel/kernel.c b/kernel/kernel/kernel.c
index 0ebaf64..f41f48e 100644
--- a/kernel/kernel/kernel.c
+++ b/kernel/kernel/kernel.c
@@ -48,6 +48,9 @@ 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);
+
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 5b405e6..ed89316 100644
--- a/kernel/mm/physical_mm/physical_mm.c
+++ b/kernel/mm/physical_mm/physical_mm.c
@@ -140,7 +140,7 @@ physical_mm_init(void)
}
uint32_t
-physical_mm_find_first_free_block(void)
+physical_mm_find_free_block(void)
{
/* TODO: Why doesn't using block_count instead of MAX_BLOCKS work? */
for (uint32_t i = 0; i < MAX_BLOCKS / BITMAP_ENTRY_SIZE; i++)
@@ -167,7 +167,7 @@ physical_mm_allocate_block(void)
spinlock_acquire(&memory_map_lock);
- uint32_t block = physical_mm_find_first_free_block();
+ uint32_t block = physical_mm_find_free_block();
physical_mm_set_used(block, &total_free_blocks, memory_map);
spinlock_release(&memory_map_lock);
diff --git a/kernel/mm/virtual_mm/virtual_mm.c b/kernel/mm/virtual_mm/virtual_mm.c
index 9c239a1..929b37d 100644
--- a/kernel/mm/virtual_mm/virtual_mm.c
+++ b/kernel/mm/virtual_mm/virtual_mm.c
@@ -113,3 +113,67 @@ virtual_mm_map_page(void *physical_address, void *virtual_address)
*pt_entry = PTE_FRAME((uint32_t) physical_address) | PTE_PRESENT(1)
| PTE_WRITABLE(1);
}
+
+ALWAYS_INLINE uint32_t *
+get_table(uint32_t *pd_entry)
+{
+ uint32_t *table;
+ if (!PDE_IS_PRESENT(pd_entry)) {
+ table = physical_mm_allocate_block();
+ if (!table)
+ ASSERT_NOT_REACHED();
+
+ for (uint32_t _ = 0; _ < 1024; _++)
+ table[_] = 0;
+
+ *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1);
+ } else
+ table = (uint32_t *) PDE_GET_TABLE(pd_entry);
+
+ return table;
+}
+
+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 = &current_page_directory[current_pd_index];
+ uint32_t *table = get_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 */
+
+ 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 = &current_page_directory[++current_pd_index];
+ table = get_table(pd_entry);
+ printk("debug", "Switching pd_entry: 0x%x", pd_entry);
+ k = 0;
+ }
+
+ uint32_t *pt_entry = &table[k];
+ if (PTE_IS_PRESENT(pt_entry)) {
+ count = 0;
+ current_pd_index = i;
+ pd_entry = &current_page_directory[current_pd_index];
+ j += count;
+ break;
+ }
+
+ // printk("debug", "Found page: 0x%x", &table[k]);
+ count++;
+ if (count == n) {
+ printk("debug", "Found starting page at: 0x%x", &table[j]);
+ return;
+ }
+ }
+ }
+ }
+}