[Closed]Interrupt 14 when executing first assembly instruction in ring 3.
Posted: Sun Jan 05, 2025 5:49 am
I'm trying to load and execute user level program in my kernel code. I use an "iret" to jump from my kernel code to user level program. The first assembly instruction is "mov $1, %eax". I got an interrupt 13 when executing this simple instruction.
What I saw in Gdbgui:
After "iret", CS, EIP, SS, ESP contain the value I give. Then, execute one machine instruction, which is "movl $1, %eax". Control flow transfered to interrupt handler 13.
Guess:
My context switching code is not right. But I can't figure it out.
https://wiki.osdev.org/Getting_to_Ring_3
My project can be found here:
https://github.com/stskyblade/StarOS/tr ... ocess-soft
At git branch: dev-process-soft
How to build:
Explanation of my code: https://github.com/stskyblade/StarOS/bl ... s.cpp#L123
- set up a new page directory for the process
- add ring 3 data segment and code segment to GDT
- set DS, ES, FS, GS with ring 3 data segment
- push SS, ESP, EFLAGS, CS, IP. These value will be used by "iret". I don't know what value should EFLAGS be, I tried 0, or current ESP.
- change CR3
- iret
Here is the program I try to load: https://github.com/stskyblade/StarOS/bl ... add.cpp#L3
For debugging, I jump over the function prologue. Just start with the first inline assembly code.
Memory config:
I enable both segmentation and paging. Every segment starts at address 0x0. Kernel and User program have different segment and page directory.
Kernel code and data are mapped to high address. You can find it here: https://github.com/stskyblade/StarOS/bl ... rnel.h#L31
In kernel, virtual address = linear address = physical address.
User program uses a different page directory. Kernel code has been mapped to same address in user program space as kernel space.
What I saw in Gdbgui:
After "iret", CS, EIP, SS, ESP contain the value I give. Then, execute one machine instruction, which is "movl $1, %eax". Control flow transfered to interrupt handler 13.
Guess:
My context switching code is not right. But I can't figure it out.
https://wiki.osdev.org/Getting_to_Ring_3
My project can be found here:
https://github.com/stskyblade/StarOS/tr ... ocess-soft
At git branch: dev-process-soft
How to build:
Code: Select all
git clone -b dev-process-soft https://github.com/stskyblade/StarOS.git
cd StarOS
mkdir build
cd build
cmake ..
cmake --build . --target qemu
cmake --build . --target debug # for gdb debug
cd <Project_root>
gdbgui . # start a gui gdb
Explanation of my code: https://github.com/stskyblade/StarOS/bl ... s.cpp#L123
- set up a new page directory for the process
- add ring 3 data segment and code segment to GDT
- set DS, ES, FS, GS with ring 3 data segment
- push SS, ESP, EFLAGS, CS, IP. These value will be used by "iret". I don't know what value should EFLAGS be, I tried 0, or current ESP.
- change CR3
- iret
Here is the program I try to load: https://github.com/stskyblade/StarOS/bl ... add.cpp#L3
For debugging, I jump over the function prologue. Just start with the first inline assembly code.
Memory config:
I enable both segmentation and paging. Every segment starts at address 0x0. Kernel and User program have different segment and page directory.
Kernel code and data are mapped to high address. You can find it here: https://github.com/stskyblade/StarOS/bl ... rnel.h#L31
In kernel, virtual address = linear address = physical address.
User program uses a different page directory. Kernel code has been mapped to same address in user program space as kernel space.