OSDev.org

The Place to Start for Operating System Developers
It is currently Mon Mar 18, 2024 8:56 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: BSS Page fault when setting permission for kernel pages
PostPosted: Fri Jan 13, 2023 6:01 am 
Offline

Joined: Fri Jan 13, 2023 5:38 am
Posts: 2
Hi,
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:
        ...
   .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 = .;

And the I set the permission depending if they are within the region
Code:
_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:

However, when later writing to the bss i a get page fault, and I'm quite confused why


Attachments:
File comment: Boot assembly file
boot.S [4.79 KiB]
Downloaded 11 times
File comment: Linker script
linker.ld [1.66 KiB]
Downloaded 11 times
Top
 Profile  
 
 Post subject: Re: BSS Page fault when setting permission for kernel pages
PostPosted: Tue Jan 17, 2023 11:40 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5069
What's the page fault error code? What values are in CR2 and the saved return address?

Which virtual machine are you using? QEMU has several debugging tools that will be helpful here, including the ability to dump exceptions ("-d int") and a monitor that can help you examine your page tables ("info tlb" and "info mem").


Top
 Profile  
 
 Post subject: Re: BSS Page fault when setting permission for kernel pages
PostPosted: Thu Jan 19, 2023 12:18 am 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 670
This looks wrong and won't properly loop as you expect:
Code:
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:
The problem is the `loop table_loop' line. That decrements ECX and checks if it is zero, and if zero it exits the loop. Looking at your code I think you meant 'jmp table_loop' to jump unconditionally back to label 'table_loop'. So it would look like:
Code:
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)
   jmp table_loop
end:
Most likely whatever value was in ECX was low enough that it prevented enough iterations to occur and in turn you didn't map all the pages you wanted.

Since you are running 32-bit code (no 16-bit real mode code) debugging with QEMU and GDB can help find these kinds of problems. It was how I finally noticed the issue with `loop` vs `jmp`.

You can build your assembly and C/C++ files with the `-g` option to enable debugging information. There is a bit of an issue in your `boot.s` because the debugger may not see your `.mulitboot.text` section as executable because you forgot to use the `x` section option. This line:
Code:
.section .multiboot.text, "a"
should be:
Code:
.section .multiboot.text, "ax"
.
To build you could use commands like this:
Code:
gcc -g -c  -m32 -fno-pic -ffreestanding  kernel.c -o kernel.o
as -g --32 boot.s -o boot.o
ld -melf_i386 -Tlinker.ld boot.o kernel.o -o kernel.elf
Then you can run QMEU and debug with GDB doing something like:
Code:
qemu-system-i386 -kernel kernel.elf -no-shutdown -no-reboot -d int -D log.txt -S -s &

gdb kernel.elf \
        -ex 'target remote localhost:1234' \
        -ex 'layout src' \
        -ex 'layout regs' \
        -ex 'break *_start' \
        -ex 'continue'
Interrupt/exception info will be written to log.txt. In this case I have it stopping at label `_start` so that I could debug the code before `kernel_main`. In the QEMU window you can gain access to the monitor with control-alt-2. In the monitor you can type help for all the commands. What may be useful is to see the paging information or the TLB using the `info mem` and `info tlb` commands. To switch out of the monitor back to the virtual machine you can use control-alt-1. You can find additional information on the monitor here: https://en.wikibooks.org/wiki/QEMU/Monitor

You can find reference material/tutorials about using GDB to debug in Google. The GDB documentation is here: https://sourceware.org/gdb/current/onlinedocs/gdb.html/ Some of the useful commands are `ni` (next instruction); 'si' (step instruction); 'c' continue; 'b' (set breakpoints).


Top
 Profile  
 
 Post subject: Re: BSS Page fault when setting permission for kernel pages
PostPosted: Sat Mar 25, 2023 4:42 am 
Offline

Joined: Fri Jan 13, 2023 5:38 am
Posts: 2
Thanks for tips MichaelPetch, they really helped! Sorry for the very late reply, unfortunately life came between me and my os project for a while


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Google [Bot] and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group