aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2025-01-22 03:54:40 -0500
committerRaghuram Subramani <raghus2247@gmail.com>2025-01-22 03:54:40 -0500
commit7a594b8bd49ee3c9809a4dda661f1ab85ad84ee6 (patch)
tree3fe1496317621910b9e260ed7b25a8df36a4c786
parent5217b3753370e941da3eba7932223421012abcfa (diff)
virtual_mm: Implement physical to virtual mapping
-rw-r--r--kernel/include/mm/virtual_mm.h17
-rw-r--r--kernel/mm/virtual_mm/virtual_mm.c28
2 files changed, 37 insertions, 8 deletions
diff --git a/kernel/include/mm/virtual_mm.h b/kernel/include/mm/virtual_mm.h
index 52eb92c..980e809 100644
--- a/kernel/include/mm/virtual_mm.h
+++ b/kernel/include/mm/virtual_mm.h
@@ -25,9 +25,6 @@
#define PAGE_DIRECTORY_SIZE 1024
#define PAGE_TABLE_SIZE 1024
-#define PAGE_DIRECTORY_INDEX(virtual_address) ((virtual_address >> 22) & 0x3ff)
-#define PAGE_TABLE_INDEX(virtual_address) ((virtual_address >> 12) & 0x3ff)
-
#define PDE_PRESENT(x) x
#define PDE_WRITABLE(x) ((x) << 1)
#define PDE_USER(x) ((x) << 2)
@@ -42,7 +39,9 @@
/* Page table address */
#define PDE_FRAME(x) ((x) &0xFFFFF000)
-#define GET_PDE_FRAME(x) ((*x) >> 12)
+#define PDE_IS_PRESENT(pd_entry) ((*pd_entry) & 1)
+#define GET_PDE_FRAME(virtual_address) (((uint32_t) virtual_address) >> 22)
+#define PDE_GET_TABLE(pd_entry) ((*pd_entry) & ~0xfff)
#define PTE_PRESENT(x) x
#define PTE_WRITABLE(x) ((x) << 1)
@@ -58,8 +57,9 @@
/* Left shift by 12 because we only need the bits from the twelfth bit. */
#define PTE_FRAME(x) ((x) << 12)
-#define PTE_IS_PRESENT(x) ((x) &1)
-#define GET_PTE_FRAME(x) ((*x) >> 12)
+#define PTE_IS_PRESENT(pt_entry) ((*pt_entry) & 1)
+#define GET_PTE_FRAME(virtual_address) \
+ ((((uint32_t) virtual_address) >> 12) & 0x3ff)
#define ADD_ATTRIB(entry, attribute) (*entry |= (attribute))
@@ -78,4 +78,9 @@ bool virtual_mm_switch_page_directory(uint32_t *page_directory);
*/
void virtual_mm_initialize(void);
+/*
+ * Map a physical address to a virtual address
+ */
+void virtual_mm_map_page(void *physical_address, void *virtual_address);
+
#endif
diff --git a/kernel/mm/virtual_mm/virtual_mm.c b/kernel/mm/virtual_mm/virtual_mm.c
index 9c8292e..c69d194 100644
--- a/kernel/mm/virtual_mm/virtual_mm.c
+++ b/kernel/mm/virtual_mm/virtual_mm.c
@@ -62,10 +62,9 @@ virtual_mm_initialize(void)
uint32_t *table = physical_mm_allocate_block();
if (!table)
ASSERT_NOT_REACHED();
- printk("debug", "Page table is at: 0x%x", table);
for (uint32_t i = 0; i < 1024; i++)
- table[i] = 0x2;
+ table[i] = 0;
/* Identity map the first 4MiB, excluding the 4th MiB
* (maps 4KiB 1024 times) */
@@ -86,3 +85,28 @@ virtual_mm_initialize(void)
virtual_mm_switch_page_directory(page_directory);
virtual_mm_enable_paging();
}
+
+void
+virtual_mm_map_page(void *physical_address, void *virtual_address)
+{
+ uint32_t *pd_entry = &current_page_directory[GET_PDE_FRAME(virtual_address)];
+
+ uint32_t *table = 0;
+ /* If the pd_entry isn't present, allocate a block for it, zero the table,
+ * and set the pd_entry's frame to the table's address. */
+ if (!PDE_IS_PRESENT(pd_entry)) {
+ table = physical_mm_allocate_block();
+ if (!table)
+ ASSERT_NOT_REACHED();
+
+ for (uint32_t i = 0; i < 1024; i++)
+ table[i] = 0;
+
+ *pd_entry = PDE_FRAME((uint32_t) table) | PDE_PRESENT(1) | PDE_WRITABLE(1);
+ } else
+ table = (uint32_t *) PDE_GET_TABLE(pd_entry);
+
+ uint32_t *pt_entry = &table[GET_PTE_FRAME(virtual_address)];
+ *pt_entry = PTE_FRAME((uint32_t) physical_address) | PTE_PRESENT(1)
+ | PTE_WRITABLE(1);
+}