I've been building my version of the xv6 OS, but just as I switch to a newly created page directory and try to call a function, it triple faults.
A lot of similar questions have been asked and usually the problem is that a page fault is not correctly handled, either because of incorrect page mapping or incorrect IDT.
In my case I've manually checked the mapping and it works, so I'm out of ideas what else can be broken. See below for details.
Here's where I am in the kernel (just switched CR3 to the new page table and about to call test_function
):
│0x801017ad <kernel_start+29> call 0x80101040 <init_kernel_memory_range>
│0x801017b2 <kernel_start+34> call 0x801013c0 <init_global_kernel_page_dir>
│0x801017b7 <kernel_start+39> call 0x80101390 <switch_to_kernel_page_dir>
>│0x801017bc <kernel_start+44> call 0x80101770 <test_function>
I can verify in gdb that the memory of test_function
is accessible, so the mapping seems to be correct:
(gdb) x/10i test_function
0x80101770 <test_function>: push ebp
0x80101771 <test_function+1>: mov ebp,esp
0x80101773 <test_function+3>: sub esp,0x8
0x80101776 <test_function+6>: lea eax,ds:0x80101b00
0x8010177c <test_function+12>: mov DWORD PTR [esp],eax
0x8010177f <test_function+15>: call 0x80101750 <panic>
0x80101784 <test_function+20>: add esp,0x8
0x80101787 <test_function+23>: pop ebp
0x80101788 <test_function+24>: ret
0x80101789: nop
I can also verify that the stack can be accessed:
(gdb) i r esp
esp 0x8010101c 0x8010101c
(gdb) x/10w 0x8010101c
0x8010101c: 0x80104024 0x80400000 0x00007bf8 0x90669066
0x8010102c: 0x90669066 0x8be58955 0xc35d0845 0x90909090
0x8010103c: 0x90909090 0x83e58955
The identity mapping of low addresses to physical that used to be in the previous page directory no longer exists, and that is intended (0x101770
is the physical address of test_function
):
(gdb) x/10i 0x101770
0x101770: Cannot access memory at address 0x101770
I have also manually verified that the addresses I care about are correctly translated using the page directory / page table into physical addresses. Yet when I finally call test_function
, I get this in QEMU:
EAX=003ff000 EBX=00010094 ECX=003ff000 EDX=fe000000
ESI=00010094 EDI=00000000 EBP=80101024 ESP=8010101c
EIP=801017bc EFL=00000096 [--S-AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9a00 DPL=0 CS32 [-R-]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0000 00000000 00000000 00000000
GS =0000 00000000 00000000 00000000
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 00007c60 00000017
IDT= 00000000 000003ff
CR0=80010011 CR2=00000040 CR3=003ff000 CR4=00000010
DR0=00000000 DR1=00000000 DR2=00000000 DR3=00000000
DR6=ffff0ff0 DR7=00000400
EFER=0000000000000000
Triple fault. Halting for inspection via QEMU monitor.
IDT is not yet set up, but I'm not expecting any page faults yet.
Anything that I'm missing here? What else can cause a triple fault? Thanks.
User contributions licensed under CC BY-SA 3.0