From 0c0d220d3eaf61d6ab0aca6d006c278edc5a0440 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Mon, 15 Mar 2021 22:41:31 +0200 Subject: Map .text and .rodata as read-only --- linker.ld | 4 +--- src/boot.S | 55 +++++++++++++++++++++++++++---------------------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/linker.ld b/linker.ld index 764b78b..d1dedd2 100644 --- a/linker.ld +++ b/linker.ld @@ -16,7 +16,6 @@ SECTIONS /* Begin putting sections at 4 MiB */ . = VADDR_BASE; - _kernel_start = .; .text ALIGN(4K) : AT(ADDR(.text) - VADDR_BASE + 4M) { begin_text = .; @@ -34,6 +33,7 @@ SECTIONS /* Read-write data (initialized) */ .data ALIGN(4K) : AT(ADDR(.data) - VADDR_BASE + 4M) { + begin_data = .; begin_constinit = .; *(.constinit) end_constinit = .; @@ -42,7 +42,6 @@ SECTIONS KEEP(*(.init_array)); /* global constructors */ end_ctors = .; - begin_data = .; *(.data) end_data = .; } @@ -55,5 +54,4 @@ SECTIONS *(.stack) end_bss = .; } - _kernel_end = .; } diff --git a/src/boot.S b/src/boot.S index e39883e..0451066 100644 --- a/src/boot.S +++ b/src/boot.S @@ -52,7 +52,24 @@ kernel_ptable0: */ .section .multiboot.text, "ax" .global VADDR_OFFSET -.set VADDR_OFFSET, 0xc0000000 - 0x400000 + .set VADDR_OFFSET, 0xc0000000 - 0x400000 + +.macro map begin, end, access + mov $\begin - VADDR_OFFSET, %esi +1: + cmpl $(\end - VADDR_OFFSET), %esi + jge 2f # move to next section + + movl %esi, %edx # map physical address + orl $\access, %edx # access bits + movl %edx, (%edi) + + addl $4096, %esi # Size of page is 4096 bytes. + addl $4, %edi # Size of entries in kernel_ptable0 is 4 bytes. + loop 1b # Loop to the next entry if we haven't finished. +2: +.endm + .global _start .type _start, @function _start: @@ -60,37 +77,19 @@ _start: # Physical address of kernel_ptable0. movl $(kernel_ptable0 - VADDR_OFFSET), %edi - - # Only map the kernel. - mov $_kernel_start - VADDR_OFFSET, %esi # Map 1024 pages movl $1024, %ecx -l_page_init: - cmpl $(_kernel_end - VADDR_OFFSET), %esi - jge map_table + map begin_text, end_text, 0x001 + map begin_rodata, end_rodata, 0x001 + map begin_data, end_data, 0x003 + map begin_bss, end_bss, 0x003 - /* TODO: Map physical address as "present, writable". Note that this maps .text and .rodata as writable. - Mind security and map them as non-writable. */ - movl %esi, %edx - orl $0x003, %edx - movl %edx, (%edi) - - # Size of page is 4096 bytes. - addl $4096, %esi - # Size of entries in kernel_ptable0 is 4 bytes. - addl $4, %edi - # Loop to the next entry if we haven't finished. - loop l_page_init - -map_table: -/* - Enabling paging does not change the next instruction, which continues to be physical. Therefore, map the kernel - to both its physical address and to the higher half. - Use the page table at: - - entry 1 starts 0x0040 0000 ends 0x007f ffff - - entry 768 starts 0xc000 0000 ends 0xc03f ffff - */ + # Enabling paging does not change the next instruction, which continues to be physical. Therefore, map the kernel + # to both its physical address and to the higher half. + # Use the page table at: + # - entry 1 starts 0x0040 0000 ends 0x007f ffff + # - entry 768 starts 0xc000 0000 ends 0xc03f ffff movl $(kernel_ptable0 - VADDR_OFFSET + 0x003), kernel_pagedir - VADDR_OFFSET + 1 * 4 movl $(kernel_ptable0 - VADDR_OFFSET + 0x003), kernel_pagedir - VADDR_OFFSET + 768 * 4 -- cgit v1.2.1