I have started to build a kernel as a hobby project, I have followed the Meaty Skeleton and Higher Half Barebones (https://wiki.osdev.org/Higher_Half_x86_Bare_Bones) tutorials and everything gone smoothly. However, next I wanted to set the correct permissions for the different sections (read/write for data, common, stack and bss, read-only for the rest), but I ran in to some troubles
First i set symbols in the linker script marking start/end of writable sections (src files are attached)
Code: Select all
...
.text ALIGN (4K) : AT (ADDR (.text) - HIGHER_HALF_ADDR)
{
*(.text)
}
.rodata ALIGN (4K) : AT (ADDR (.rodata) - HIGHER_HALF_ADDR)
{
*(.rodata)
}
_wdata_start = .;
.data ALIGN (4K) : AT (ADDR (.data) - HIGHER_HALF_ADDR)
{
*(.data)
}
.bss ALIGN (4K) : AT (ADDR (.bss) - HIGHER_HALF_ADDR)
{
*(COMMON)
*(.bss)
*(.bootstrap_stack)
}
_wdata_end = .;
Code: Select all
_start:
# Physical address of boot_page_table1.
movl $(boot_page_table1 - HIGHER_HALF_ADDR), %edi
# First physical address to map is address 0.
movl $0, %esi
# Page table setup loop
table_loop:
# Skip pages before multiboot (i.e. < 1 MiB section)
cmpl $_kernel_start, %esi
jl skip
# Once the full kernel is mapped, exit loop
cmpl $(_kernel_end - HIGHER_HALF_ADDR), %esi
jge end
# Set default permisisons, "present, read-only"
movl $0x001, %ecx
# If within are the write area (data, bss and stack), enable writing
cmpl $(_wdata_start - HIGHER_HALF_ADDR), %esi
jl set_permission
cmpl $(_wdata_end - HIGHER_HALF_ADDR), %esi
jge set_permission
orl $0x002, %ecx
set_permission:
# Map physical address with specified permissions
movl %esi, %edx
orl %ecx, %edx
movl %edx, (%edi)
skip:
addl $4096, %esi # Increment page address by 4 KiB page size
addl $4, %edi # Increment page table address by 4B (each entry is 32 bits)
loop table_loop
end: