i'm trying set idt of kernel i'm getting linking error:
bin/obj/idt.o: in function `setup_idt': idt.c:(.text+0x9b): undefined reference `interrupt_handler_1'
the error says interrupt_handler_1 isn't defined macro in interrupt_manager.asm:
%macro no_error_code_interrupt_handler 1 global interrupt_handler_%1 interrupt_handler_%1: cli push dword 0 ; push 0 error code push dword %1 ; push interrupt number jmp common_interrupt_handler ; jump common handler %endmacro
here setyup_idt function:
extern void interrupt_handler_1(); void setup_idt() { // set special idt_pointer idt_pointer.limit = ( sizeof(struct interruptdescriptortableentry) * 256 ) - 1; // subsract 1 because sizeof doesn't start 0 idt_pointer.address = (uint32)&idt; // clear whole idt zeros memset(&idt, 0, sizeof(struct interruptdescriptortableentry) * 256 ); for(unsigned int = 0; < 256; i++) { idt_set_gate(i, (uint32)&interrupt_handler_1, 0x8, 0x8e); } __asm__ __volatile__("lidt %0": :"m"(idt_pointer)); }
what did made wrong?
extra question: there macro/another way link automatically entry of gdt interrupt handler, let me try explain myself better:
what want this:
for(unsigned int = 0; < 256; i++) { idt_set_gate(i, (uint32)&interrupt_handler_[i], 0x8, 0x8e); }
where interrupt_handler[i] interrupt handler_[i] replaced nasm macro
you need expand macro in nasm code. macro definition doesn't generate code. needs explicitly used in nasm code.
you can use %rep
directive repeatedly expand macro different parameters. this:
extern common_interrupt_handler %macro error_code_interrupt_handler 1 global interrupt_handler_%1 interrupt_handler_%1: push dword %1 ; push interrupt number jmp common_interrupt_handler ; jump common handler %endmacro %macro no_error_code_interrupt_handler 1 global interrupt_handler_%1 interrupt_handler_%1: push dword 0 ; push 0 error code push dword %1 ; push interrupt number jmp common_interrupt_handler ; jump common handler %endmacro ; cpu exceptions have error codes, don't %assign intnum 0 %rep 8 - intnum no_error_code_interrupt_handler intnum %assign intnum intnum + 1 %endrep error_code_interrupt_handler 8 no_error_code_interrupt_handler 9 %assign intnum 10 %rep 16 - intnum error_code_interrupt_handler intnum %assign intnum intnum + 1 %endrep no_error_code_interrupt_handler 16 error_code_interrupt_handler 17 no_error_code_interrupt_handler 18 no_error_code_interrupt_handler 19 no_error_code_interrupt_handler 20 %assign intnum 21 ; first (currently) unassigned cpu exception %rep 32 - intnum no_error_code_interrupt_handler intnum %assign intnum intnum + 1 %endrep %assign intnum 32 ; first user defined interrupt %rep 256 - intnum no_error_code_interrupt_handler intnum %assign intnum intnum + 1 %endrep ; define table of interrupt handlers c code use global interrupt_handler_table interrupt_handler_table: %assign intnum 0 %rep 256 dd interrupt_handler_ %+ intnum %assign intnum intnum + 1 %endrep
the code above creates table of interrupt handlers can use in c code this:
extern uint32 interrupt_handler_table[256]; for(unsigned int = 0; < 256; i++) { idt_set_gate(i, interrupt_handler_table[i], 0x8, 0x8e); }
note i've created error_code_interrupt_handler
macro cpu exceptions generate error codes. also, i've removed unnecessary cli instruction code. since you're using interrupt gates in idt, interrupt enable flag automatically cleared.
Comments
Post a Comment