我使用教程 (https://www.youtube.com/watch?v=Wh5nPn2U_1w&list=PLm3B56ql_akNcvH8vvJRYOc7TbYhRs19M&index=6) 创建了一个 GDT 并将其数据放在我编写的其他代码之后和 BIOS 引导字节之前,但现在我注意到我需要为 256 个 IDT 条目留出空间,但我不知道如何正确管理它们。之前我只是一个接一个地放东西,但现在我需要有 2,048 KB 的空间来放 IDT。
我用于 IDT 的教程 (http://www.independent-software.com/operating-system-development-setting-up-interrupt-descriptor-table.html) 在地址 0x0800 处有 GDT,所以所有他们要做的就是将 IDT 放在地址 0x0000 处。那不是要覆盖现有代码吗?
这就是我进入保护模式并设置 GDT 和(刚刚作为测试添加的)IDT 的方式:
enter_PM:
; mov ah, 0x0
; mov al, 0x3
; int 0x10
cli
lidt [IDT_Descriptor]
lgdt [GDT_Descriptor]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp CODE_SEG:protected_mode
[bits 32]
protected_mode:
; mov byte [0xb8000], 'A'
; jmp halt
call KERNEL_LOCATION
jmp halt
halt:
hlt
jmp halt
GDT_Start:
null_descriptor:
dd 0
dd 0
code_descriptor:
dw 0xffff
dw 0
db 0
db 0b10011010
db 0b11001111
db 0
data_descriptor:
dw 0xffff
dw 0
db 0
db 0b10010010
db 0b11001111
db 0
GDT_End:
GDT_Descriptor:
dw GDT_End - GDT_Start - 1
dd GDT_Start
IDT_Start:
KEYBOARD:
dw 0x0078
dw CODE_SEG
db 0
db 0b11100001
dw 0x0000
IDT_End:
IDT_Descriptor:
dw IDT_End - IDT_Start - 1
dd IDT_Start
CODE_SEG equ code_descriptor - GDT_Start
DATA_SEG equ data_descriptor - GDT_Start
KERNEL_LOCATION equ 0x1000
BOOT_DISK db 0
ping_command db "ping", 0
pong db "pong", 0
PS1_env db "admin% ", 0
command_not_found_text db "Command not found!", 0xa, 0xd, 0
string db "It's me! Mario!", 0xa, 0xd, "admin% ", 0
times 510-($-$$) db 0
dw 0xAA55
reserved resb 128
这是完整的代码 - https://pastebin.com/Z9Hp54ne.
也有人可以向我解释什么是这里的“内存”,什么只是我存储代码的二进制文件的一部分。我如何访问内存?堆栈是内存的一部分吗?我使用某些地址(如 0xb8000)来访问内存,但它指向什么?标签也有地址,但它们是二进制文件的一部分。我还认为 GDT 本身保留了内存。为什么需要为 IDT 预留内存?我为数据和代码段提供了完整的 4 GB 内存空间,但后来我将偏移量写为地址,它是二进制文件的一部分?然后它会扫描提供的地址并获取有关 GDT 的所需信息吗?那么这是否意味着 IDT 从二进制文件中获取其配置,然后使用该信息来捕获中断?所以我实际上是在为每个IDT条目的配置预留空间?
谁能给我解释一下?