#c #nasm #osdev
Вопрос:
Я пытаюсь реализовать IDT для операционной системы хобби, однако при связывании компоновщик говорит, что существуют неопределенные ссылки для isr0 через isr9 и с функциями Idt_IdtFlush.
idt.h
#ifndef __IDT_H__ #define __IDT_H__ #include "../stdlib/types.h" #include "../stdlib/string.h" #include "./isr.h" //Assembly ISR handlers externed in a seperate file (also includes flush function) struct IDT_ENTRY_STRUCT { //Struct for a interrupt gate uint16_t baseLow; //Lower 16 bits of a address uint16_t sel; //Segment selector uint8_t zero; //Always zero uint8_t flags; //Flags. uint16_t baseHigh; //Upper 16 bits of a address } __attribute__((packed)); struct IDT_PTR_STRUCT { //Pointer to a array of int handlers uint16_t limit; // uint32_t base; // } __attribute__((packed)); typedef struct IDT_ENTRY_STRUCT idt_entry_t; typedef struct IDT_PTR_STRUCT idt_ptr_t; idt_entry_t idt_entries[256]; idt_ptr_t idt_ptr; static void idt_SetGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) { idt_entries[num].baseLow = base amp; 0xFFFF; idt_entries[num].baseHigh = (base gt;gt; 16) amp; 0xFFFF; idt_entries[num].sel = sel; idt_entries[num].zero = 0; idt_entries[num].flags = flags; } static void idt_Init() { idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1; idt_ptr.base = (uint32_t)amp;idt_entries; memset(amp;idt_entries, 0, sizeof(idt_entry_t) * 256); idt_SetGate( 0, (uint32_t)isr0, 0x08, 0x8E); idt_SetGate( 1, (uint32_t)isr1, 0x08, 0x8E); idt_SetGate( 2, (uint32_t)isr2, 0x08, 0x8E); ... idt_SetGate( 31, (uint32_t)isr1, 0x08, 0x8E); Idt_IdtFlush((uint32_t)amp;idt_ptr); } #endif
isr.h
#ifndef __ISR_H__ #define __ISR_H__ //Assembly ISR handlers extern void isr0 (); extern void isr1 (); ... extern void isr31 (); extern void Idt_IdtFlush(uint32_t); //Flush the IDT (this is in assembly) #endif
boot.asm
[extern kernel] [GLOBAL idt_flush] [global gdt_GdtFlush] MULTIBOOT_MODULE_ALIGN equ 1 lt;lt; 0 MULTIBOOT_MEMORY_MAP equ 1 lt;lt; 1 MULTIBOOT_GRAPHICS_FIELDS equ 1 lt;lt; 2 MULTIBOOT_ADDRESS_FIELDS equ 1 lt;lt; 16 MULTIBOOT_HEADER_MAGIC equ 0x1BADB002 MULTIBOOT_HEADER_FLAGS equ MULTIBOOT_MODULE_ALIGN | MULTIBOOT_MEMORY_MAP MULTIBOOT_HEADER_CHECKSUM equ -(MULTIBOOT_HEADER_MAGIC MULTIBOOT_HEADER_FLAGS) KERNEL_STACKSIZE equ 0x4000 section .multiboot align 4 dd MULTIBOOT_HEADER_MAGIC dd MULTIBOOT_HEADER_FLAGS dd MULTIBOOT_HEADER_CHECKSUM section .text jmp kernelStart gdt_GdtFlush: mov eax, [esp 4] lgdt [eax] mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax jmp 0x08:flush2 flush2: ret kernelStart: mov esp, KERNEL_STACK KERNEL_STACKSIZE push eax push ebx call kernel cli hlt Idt_IdtFlush: mov eax, [esp 4] lidt [eax] ret %macro ISR_NOERRCODE 1 [GLOBAL isr%1] isr%1: cli push byte 0 push byte %1 jmp isr_common_stub %endmacro %macro ISR_ERRCODE 1 [GLOBAL isr%1] isr%1: cli push byte %1 jmp isr_common_stub %endmacro section .bss align 32 KERNEL_STACK: resb KERNEL_STACKSIZE
Я не понимаю, почему это происходит, так как функции isr определены в загрузчике и отображаются в файле isr.h.
Комментарии:
1. Вы определяете макросы
ISR_ERRCODE
иISR_NOERRCODE
которые должны расширяться, чтобы определить соответствующую метку isr и код, но я не вижу, где вы когда-либо вызывали эти макросы.