From fe468b476d567b6aa0695a030c408ccf46278c7d Mon Sep 17 00:00:00 2001
From: Marvin Borner
Date: Fri, 2 Apr 2021 19:04:34 +0200
Subject: Mapped .text and .rodata readonly

---
 kernel/features/mm.c | 28 +++++++++++++++++++---------
 kernel/inc/mm.h      |  2 ++
 kernel/link.ld       | 28 ++++++++++++++++------------
 kernel/main.c        |  1 -
 4 files changed, 37 insertions(+), 22 deletions(-)

(limited to 'kernel')

diff --git a/kernel/features/mm.c b/kernel/features/mm.c
index 064f78c..3be798a 100644
--- a/kernel/features/mm.c
+++ b/kernel/features/mm.c
@@ -25,14 +25,14 @@ static void paging_switch_dir(u32 dir)
 
 extern void paging_invalidate_tlb(void);
 
-/*void paging_disable(void)
+void paging_disable(void)
 {
 	cr0_set(cr0_get() | 0x7fffffff);
-}*/
+}
 
 void paging_enable(void)
 {
-	cr0_set(cr0_get() | 0x80000000);
+	cr0_set(cr0_get() | 0x80010000);
 }
 
 void page_fault_handler(struct regs *r)
@@ -224,7 +224,7 @@ void virtual_map(struct page_dir *dir, struct memory_range prange, u32 vaddr, u3
 		u32 pti = PTI(vaddr + offset);
 		union page_table_entry *table_entry = &table->entries[pti];
 		table_entry->bits.present = 1;
-		table_entry->bits.writable = 1;
+		table_entry->bits.writable = !(flags & MEMORY_READONLY);
 		table_entry->bits.user = flags & MEMORY_USER;
 		table_entry->bits.address = (prange.base + offset) >> 12;
 	}
@@ -561,11 +561,20 @@ struct memory_range memory_range_around(u32 base, u32 size)
 	return memory_range(base, size);
 }
 
-extern u32 kernel_start;
-extern u32 kernel_end;
-static struct memory_range kernel_memory_range(void)
+extern u32 kernel_rw_start;
+extern u32 kernel_rw_end;
+static struct memory_range kernel_rw_memory_range(void)
+{
+	return memory_range_around((u32)&kernel_rw_start,
+				   (u32)&kernel_rw_end - (u32)&kernel_rw_start);
+}
+
+extern u32 kernel_ro_start;
+extern u32 kernel_ro_end;
+static struct memory_range kernel_ro_memory_range(void)
 {
-	return memory_range_around((u32)&kernel_start, (u32)&kernel_end - (u32)&kernel_start);
+	return memory_range_around((u32)&kernel_ro_start,
+				   (u32)&kernel_ro_end - (u32)&kernel_ro_start);
 }
 
 void memory_install(struct mem_info *mem_info, struct vid_info *vid_info)
@@ -600,7 +609,8 @@ void memory_install(struct mem_info *mem_info, struct vid_info *vid_info)
 	printf("Detected memory: %dKiB (%dMiB)\n", memory_total >> 10, memory_total >> 20);
 
 	// Map kernel
-	memory_map_identity(&kernel_dir, kernel_memory_range(), MEMORY_NONE);
+	memory_map_identity(&kernel_dir, kernel_ro_memory_range(), MEMORY_READONLY);
+	memory_map_identity(&kernel_dir, kernel_rw_memory_range(), MEMORY_NONE);
 
 	// Map kernel stack
 	memory_map_identity(&kernel_dir, memory_range_around(STACK_START - STACK_SIZE, STACK_SIZE),
diff --git a/kernel/inc/mm.h b/kernel/inc/mm.h
index 5dee6d4..a0b39a5 100644
--- a/kernel/inc/mm.h
+++ b/kernel/inc/mm.h
@@ -17,6 +17,7 @@ struct memory_range {
  * Lowlevel paging
  */
 
+void paging_disable(void);
 void paging_enable(void);
 void page_fault_handler(struct regs *r) NONNULL;
 
@@ -110,6 +111,7 @@ struct memory_proc_link {
 #define MEMORY_NONE (0 << 0)
 #define MEMORY_USER (1 << 0)
 #define MEMORY_CLEAR (1 << 1)
+#define MEMORY_READONLY (1 << 2)
 #define memory_range(base, size) ((struct memory_range){ (base), (size) })
 
 struct memory_range memory_range_from(u32 base, u32 size);
diff --git a/kernel/link.ld b/kernel/link.ld
index fbe8a8c..c3b59b3 100644
--- a/kernel/link.ld
+++ b/kernel/link.ld
@@ -5,27 +5,31 @@ phys = 0x00009000;
 
 SECTIONS
 {
-	.text phys : AT(phys) {
-		kernel_start = .;
-		code = .;
+	. = phys;
+
+	kernel_ro_start = .;
+	.text BLOCK(4K) : ALIGN(4K)
+	{
 		*(.text)
+	}
+
+	.rodata BLOCK(4K) : ALIGN(4K)
+	{
 		*(.rodata)
-		. = ALIGN(4096);
 	}
+	kernel_ro_end = .;
+
 
-	.data : AT(phys + (data - code))
+	kernel_rw_start = .;
+	.data BLOCK(4K) : ALIGN(4K)
 	{
-		data = .;
 		*(.data)
-		. = ALIGN(4096);
 	}
 
-	.bss : AT(phys + (bss - code))
+	.bss BLOCK(4K) : ALIGN(4K)
 	{
-		bss = .;
+		*(COMMON)
 		*(.bss)
-		. = ALIGN(4096);
 	}
-
-	kernel_end = .;
+	kernel_rw_end = .;
 }
diff --git a/kernel/main.c b/kernel/main.c
index e28915b..326bd5c 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -28,7 +28,6 @@ void kernel_main(struct mem_info *mem_info, struct vid_info *vid_info)
 
 	memory_install(mem_info, vid_info);
 	memory_switch_dir(virtual_kernel_dir());
-	paging_enable();
 
 	cpu_enable_features();
 	cpu_print();
-- 
cgit v1.2.3