【发布时间】:2022-01-23 23:36:00
【问题描述】:
这是设置 IDT 的代码。
global lngmd_start
extern kernel_main
extern gdt.data
section .text
bits 64
lngmd_start:
mov ax, gdt.data
mov ss, ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call map_entries
lidt [idt.pointer]
sti
;call kernel_main
;int 0x00
jmp krnl_hlt
map_entries:
mov rbx, idt
.map_exceptions:
mov rdx, 0
mov r8, exception_handler
mov rcx, 32
jmp .loop
.map_irqs_pic1:
mov rdx, 1
mov r8, isr_handler.pic1
mov rcx, 8
jmp .loop
.map_irqs_pic2:
mov rdx, 2
mov r8, isr_handler.pic2
mov rcx, 8
.loop:
mov rax, r8
mov word [rbx], ax
shr rax, 16
mov word [rbx + 6], ax
shr rax, 16
mov dword [rbx + 8], eax
add rbx, 16
dec rcx
;jmp krnl_hlt ; This works as intended and halts the kernel, printing "a2"
jne .loop
jmp krnl_hlt ; this is supposed to print "a2" then halt, but causes an INVALID_OPCODE (0x6 in QEMU debugger) exception. Removing this jump causes the code to hang with no exceptions.
test rdx, rdx
je .map_irqs_pic1
dec rdx
test rdx, rdx
je .map_irqs_pic2
ret
idt:
.exception_0:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
; --------------------------------
; exceptions 1 - 30
; --------------------------------
.exception_31:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
.irq_0:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
; --------------------------------
; irqs 1 - 14
; --------------------------------
.irq_15:
dw 0
dw 0x8
db 0
db 10001110b
dw 0
dd 0
dd 0
.pointer:
dw $ - idt - 1
dq idt
exception_handler:
jmp krnl_hlt
isr_handler:
.pic1:
mov ax, 0x20
out 0x20, ax
iretq
.pic2:
mov ax, 0x20
out 0xa0, ax
iretq
krnl_hlt:
mov dword [0xb8000], 0x0c320c61
abbc:
hlt
nop
jmp abbc
在过去的 5 个小时里,我一直在尝试不同的方法来让这个 IDT 通过许多不同的方法工作,而且我通常不会问问题,但似乎我已经走到了死胡同。如果我遗漏了任何必需的信息或提出了“不好的问题”,请告诉我,我会努力改进。
【问题讨论】:
标签: exception assembly crash kernel