Неопределенные ссылки на isr0 через isr9 при связывании ядра

#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 и код, но я не вижу, где вы когда-либо вызывали эти макросы.