В итоге я сделал следующее:
Я инициализировал IDT с помощью NASM.
extern routine33
bits 32
lidt[idtr]
sti
halt:
hlt
jmp halt
idt_start:
int0:
dw isr0
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int1:
dw isr1
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int2:
dw isr2
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int3:
dw isr3
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int4:
dw isr4
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int5:
dw isr5
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int6:
dw isr6
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int7:
dw isr7
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int8:
dw isr8
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int9:
dw isr9
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int10:
dw isr10
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int11:
dw isr11
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int12:
dw isr12
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int13:
dw isr13
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int14:
dw isr14
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int15:
dw isr15
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int16:
dw isr16
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int17:
dw isr17
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int18:
dw isr18
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int19:
dw isr19
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int20:
dw isr20
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int21:
dw isr21
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int22:
dw isr22
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int23:
dw isr23
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int24:
dw isr24
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int25:
dw isr25
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int26:
dw isr26
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int27:
dw isr27
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int28:
dw isr28
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int29:
dw isr29
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int30:
dw isr30
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int31:
dw isr31
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int32:
dw isr32
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int33:
dw isr33
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int34:
dw isr34
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int35:
dw isr35
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int36:
dw isr36
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int37:
dw isr37
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int38:
dw isr38
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int39:
dw isr39
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int40:
dw isr40
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int41:
dw isr41
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int42:
dw isr42
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int43:
dw isr43
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int44:
dw isr44
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int45:
dw isr45
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int46:
dw isr46
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
int47:
dw isr47
dw 0x0008
db 0x00
db 10001110b
dw 0x0000
idt_end:
idtr:
dw idt_end - idt_start - 1
dd idt_start
isr0:
iret
isr1:
iret
isr2:
iret
isr3:
iret
isr4:
iret
isr5:
iret
isr6:
iret
isr7:
iret
isr8:
iret
isr9:
iret
isr10:
iret
isr11:
iret
isr12:
iret
isr13:
iret
isr14:
iret
isr15:
iret
isr16:
iret
isr17:
iret
isr18:
iret
isr19:
iret
isr20:
iret
isr21:
iret
isr22:
iret
isr23:
iret
isr24:
iret
isr25:
iret
isr26:
iret
isr27:
iret
isr28:
iret
isr29:
iret
isr30:
iret
isr31:
iret
isr32:
iret
isr33: ;mappped to IRQ 1 for Keyboard interrupt
call routine33
iret
isr34:
iret
isr35:
iret
isr36:
iret
isr37:
iret
isr38:
iret
isr39:
iret
isr40:
iret
isr41:
iret
isr42:
iret
isr43:
iret
isr44:
iret
isr45:
iret
isr46:
iret
isr47:
iret
Затем я написал функцию C ++ в idt. cpp:
void print(){
asm("movw $0x0770, (0xb8000)");
}
extern "C" void routine33(){
print();
return;
}
Я компилирую и связываю результат со сценарием bash:
#!/bin/bash
g++ -static -ffreestanding -znoexecstack -nostdlib -mno-red-zone -s -c -m32 idt.cpp -oidt.o
nasm -felf32 second_stage_bootloader.asm -osecond_stage_bootloader.o
ld -melf_i386 -static -pie --no-dynamic-linker -nostdlib --strip-all -Ttext=0x8000 second_stage_bootloader.o idt.o -o kernel.elf
objcopy --only-section=.text --output-target binary kernel.elf kernel.bin
dd if=/dev/zero of=disk.img bs=512 count=100 && dd if=bootloader.bin of=disk.img conv=notrunc && dd if=kernel.bin seek=1 bs=512 of=disk.img conv=notrunc
Затем я загружаю полученный простой двоичный файл в ОЗУ в свой загрузчик, используя прерывания B IOS на 0x8000. Я перехожу к коду, используя jmp 0x08:0x8000
.
Я запускаю все это с помощью:
qemu-system-x86_64 -drive file=disk.img,format=raw,index=0,media=disk -s
.
Когда я нажимаю клавишу, он печатает белый 'p 'по адресу 0xb8000.