Как статически определить IDT с младшими 16 адресами в 32-битном ядре (с встроенной сборкой g cc) - PullRequest
2 голосов
/ 06 августа 2020

У меня есть следующий код в NASM, который сокращен для вопроса:

idt_start:
int0:
      dw isr0
      dw 0x0008
      db 0x00
      db 10001110b
      dw 0x0000
idt_end:
idtr:
    dw idt_end - idt_start - 1
    dd idt_start
isr0:

Обычно у меня есть 47 из этих записей, 32 для исключений защищенного режима и 15 для сопоставления IRQ. Я настраиваю IDT для управления прерываниями от моего загрузчика.

Проблема возникает, когда я пытаюсь перенести этот код на встроенную сборку C ++.

У меня 2 файла ядра. cpp :

#include "idt.h"

void kmain(){
    defineIDT();
    halt:;
    asm("hlt");
    goto halt;
}

и idt. cpp:

void defineIDT(){
    asm(
    "idt_start:\n\t"
    "int0:\n\t"
    ".hword isr0\n\t"
    ".hword 0x0008\n\t"
    ".byte 0x00\n\t"
    ".byte 0b10001110\n\t"
    ".hword 0x0000\n\t"
    "idt_end:\n\t"
    "idtr:\n\t"
    ".hword idt_end - idt_start - 1\n\t"
    ".word idt_start\n\t"
    "isr0:\n\t"
    );
    return;
}

Я использую g ++ для компиляции моего кода с g++ -static -ffreestanding -nostdlib -znoexecstack -mno-red-zone -s -m32 kernel.cpp idt.cpp -okernel.o

Я получаю сообщение об ошибке relocation truncated to fit: R_386_16 against `.text'. Это из-за строк .hword isr0, .hword idt_end - idt_start - 1 и .word idt_start. Я не понимаю, как еще это реализовать.

1 Ответ

1 голос
/ 07 августа 2020

В итоге я сделал следующее:

Я инициализировал 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.

...