diff options
-rw-r--r-- | kernel/features/mm.c | 28 | ||||
-rw-r--r-- | kernel/inc/mm.h | 2 | ||||
-rw-r--r-- | kernel/link.ld | 28 | ||||
-rw-r--r-- | kernel/main.c | 1 |
4 files changed, 37 insertions, 22 deletions
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(); |