Я создавал свою версию ОС xv6, но как только я переключаюсь на только что созданный каталог страниц и пытаюсь вызвать функцию, возникает тройная ошибка.
Было много похожих вопросов. спросил, и обычно проблема заключается в том, что ошибка страницы не обрабатывается должным образом либо из-за неправильного сопоставления страниц, либо из-за неправильной IDT.
В моем случае я вручную проверил сопоставление, и оно работает, поэтому меня нет идей что еще можно сломать. Подробности см. Ниже.
Вот где я нахожусь в ядре (просто переключил CR3 на новую таблицу страниц и собираюсь вызвать 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>
Я могу проверить в gdb что память test_function
доступна, поэтому отображение кажется правильным:
(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
Я также могу проверить, что к стеку можно получить доступ:
(gdb) i r esp
esp 0x8010101c 0x8010101c
(gdb) x/10w 0x8010101c
0x8010101c: 0x80104024 0x80400000 0x00007bf8 0x90669066
0x8010102c: 0x90669066 0x8be58955 0xc35d0845 0x90909090
0x8010103c: 0x90909090 0x83e58955
Сопоставление идентификаторов низких адресов на физические, которые раньше находились в каталоге предыдущей страницы, больше не существует, и это предназначено (0x101770
- физический адрес test_function
):
(gdb) x/10i 0x101770
0x101770: Cannot access memory at address 0x101770
Я также проверил вручную что адреса, которые меня интересуют, правильно переводятся с помощью каталога страниц / таблицы страниц в физические адреса. Тем не менее, когда я наконец call test_function
, я получаю это в 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 еще не настроен, но я пока не ожидаю каких-либо ошибок страницы.
Что-нибудь, что мне здесь не хватает? Что еще может вызвать тройную неисправность? Спасибо.