我是这一切的新手,所以如果我错过了一些非常明显的,我会提前道歉
所以,我试图在x86汇编和C中制作一个简单的内核。我试图让中断正常工作。我在汇编中定义GDT、IDT。
我甚至不确定GDT或IDT出了什么问题。问题是,一切看起来都很好,直到我真的触发了一个中断。
我查看了OSDev、英特尔手册、James Molloy的指南和随机的博客文章,但我就是搞不明白。
这是代码:
; interrupts.asm
%macro ISRNOERR 1
isr%1:
cli
push byte 0
push byte %1
jmp isr_common_stub
isr%1_end:
%endmacro
%macro ISRERR 1
isr%1:
cli
push byte %1
jmp isr_common_stub
isr%1_end:
%endmacro
ISRNOERR 0
ISRNOERR 1
ISRNOERR 2
ISRNOERR 3
ISRNOERR 4
ISRNOERR 5
ISRNOERR 6
ISRNOERR 7
ISRERR 8
ISRNOERR 9
ISRERR 10
ISRERR 11
ISRERR 12
ISRERR 13
ISRERR 14
ISRNOERR 15
ISRNOERR 16
ISRNOERR 17
ISRNOERR 18
ISRNOERR 19
ISRNOERR 20
ISRNOERR 21
ISRNOERR 22
ISRNOERR 23
ISRNOERR 24
ISRNOERR 25
ISRNOERR 26
ISRNOERR 27
ISRNOERR 28
ISRNOERR 29
ISRNOERR 30
ISRNOERR 31
ISRNOERR 32
isr_common_stub:
pusha
mov ax, ds
push eax
mov ax, 0x10 ; Data segment descriptor (gdt.asm)
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
extern handler
call handler
pop eax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
popa
add esp, 8
sti
iret
; idt.asm
section .text
global _load_idt
_load_idt:
lidt [idt_info]
ret
%macro IRQ 1
irq%1:
dd isr%1
dw 0x0008
db 0x00
db 10101110b
dd isr%1_end
%endmacro
%include "interrupts.asm"
section .rodata
idt:
IRQ 0
IRQ 1
IRQ 2
IRQ 3
IRQ 4
IRQ 5
IRQ 6
IRQ 7
IRQ 8
IRQ 9
IRQ 10
IRQ 11
IRQ 12
IRQ 13
IRQ 14
IRQ 15
IRQ 16
IRQ 17
IRQ 18
IRQ 19
IRQ 20
IRQ 21
IRQ 22
IRQ 23
IRQ 24
IRQ 25
IRQ 26
IRQ 27
IRQ 28
IRQ 29
IRQ 30
IRQ 31
IRQ 32
idt_info:
dw idt_info - idt - 1
dd idt
// lime_main.c
#include <kernel/lime_tty.h>
extern void _load_gdt(); // From assembly
extern void _load_idt();
void lime_main()
{
lime_tty_init(TtyTextMode);
lime_tty_put_string("[ LIME ] Welcome to the Lime kernel!n");
_load_gdt();
lime_tty_put_string("[ LIME ] Loaded GDT successfully!n");
_load_idt();
lime_tty_put_string("[ LIME ] Loaded IDT successfully!n");
asm ("int $0x03"); // It's not crashing if I remove this
}
; gdt.asm
section .data
ALIGN 4
section .text
global _load_gdt
_load_gdt:
cli
lgdt [gdt_desc]
jmp 0x08:gdt_flush
gdt_flush:
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
ret
section .rodata
gdt:
gdt_null:
dd 0h
dd 0h
gdt_code:
dw 0FFFFh
dw 00000h
db 00h
db 10011010b
db 11001111b
db 0
gdt_data:
dw 0FFFFh
dw 00000h
db 00h
db 10010010b
db 11001111b
db 0
gdt_desc:
dw gdt_desc - gdt - 1
dd gdt
在此期间,我在@MichaelPetch的帮助下修复了它。基本上,问题是,正如他试图告诉我的那样,我为IDT中的值定义了错误的大小。我为高位和低位定义了双字(dd(,但我必须定义16位字(dw(。
由于重新定位的问题,如果没有链接器脚本之类的东西,我就无法真正静态地定义它。我试图避免这种情况,所以我最终选择了一种动态的方法,我在C.中做到了
没有太多的东西可以解释,有很多资源我错过了(或误解了(。
如果你像我一样,一个初学者,什么都不懂,我的建议是休息一下,带着全新的心态回来。OSDev Wiki将对你有很大帮助(论坛也是(。