2016-08-08 2 views
1

작동하지 않습니다 interrupt_manager.asm에서 매크로 :NASM 매크로 내 커널의 IDT를 설정하기 위해 노력하고있어하지만이 연결 오류가있어 제대로

extern void interrupt_handler_1(); 

void setup_idt() 
{ 
    // Set the special idt_pointer 
    idt_pointer.limit = (sizeof(struct InterruptDescriptorTableEntry) * 256) - 1; // Subsract 1 because sizeof doesn't start from 0 
    idt_pointer.address = (uint32)&idt; 

    // Clear the whole idt to zeros 
    memset(&idt, 0, sizeof(struct InterruptDescriptorTableEntry) * 256); 

    for(unsigned int i = 0; i < 256; i++) 
    { 
     idt_set_gate(i, (uint32)&interrupt_handler_1, 0x8, 0x8E); 
    } 

    __asm__ __volatile__("lidt %0": :"m"(idt_pointer)); 

} 

내가 잘못 만든 어떤했다 : 여기

%macro no_error_code_interrupt_handler 1 
global interrupt_handler_%1 
interrupt_handler_%1: 
    cli 
    push dword 0      ; push 0 as error code 
    push dword %1     ; push the interrupt number 
    jmp  common_interrupt_handler ; jump to the common handler 
%endmacro 

는 setyup_idt 기능입니다 ?

추가 질문 : 매크로가/내가 핸들러를 인터럽트에 자동으로 GDT의 전 항목을 연결하는 또 다른 방법은, 내가 더 나은 자신을 설명하려고하자 :

내가 뭘 원하는이 같은 것입니다 : interrupt_handler는 [I] 인터럽트 handler_을 것

for(unsigned int i = 0; i < 256; i++) 
    { 
     idt_set_gate(i, (uint32)&interrupt_handler_[i], 0x8, 0x8E); 
    } 

는 [내가] 당신은 당신의 NASM 코드에서 매크로를 확장하는 데 필요한 NASM 매크로

+1

링커에서 매크로를 볼 수 없습니다. 함수를 사용하십시오. –

+0

매크로가 코드의 일부가 아니므로 매크로가 어셈블 된 실제 코드로 확장되도록 * 사용 *해야합니다. –

+0

@Joachim Pileborg Okey, 추가 질문은 어떻습니까? –

답변

2

로 대체 될 것이다. 매크로 정의 자체는 코드를 생성하지 않습니다. 그것은 NASM 코드에서 명시 적으로 사용되어야합니다.

%rep 지시어를 사용하면 다른 매개 변수로 매크로를 반복적으로 확장 할 수 있습니다. 이런 식으로 뭔가 : 위의 코드는이 같은 C 코드에서 사용할 수있는 모든 인터럽트 핸들러의 테이블을 생성

extern common_interrupt_handler 

%macro error_code_interrupt_handler 1 
global interrupt_handler_%1 
interrupt_handler_%1: 
    push dword %1     ; push the interrupt number 
    jmp  common_interrupt_handler ; jump to the common handler 
%endmacro 

%macro no_error_code_interrupt_handler 1 
global interrupt_handler_%1 
interrupt_handler_%1: 
    push dword 0      ; push 0 as error code 
    push dword %1     ; push the interrupt number 
    jmp  common_interrupt_handler ; jump to the common handler 
%endmacro 

; Some CPU exceptions have error codes, some 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 a table of interrupt handlers for C code to use 

    global interrupt_handler_table 
interrupt_handler_table: 

%assign intnum 0 
%rep 256 
    dd interrupt_handler_ %+ intnum 
    %assign intnum intnum + 1 
%endrep 

: 나는 대한 error_code_interrupt_handler 매크로를 만든

extern uint32 interrupt_handler_table[256]; 

for(unsigned int i = 0; i < 256; i++) 
{ 
    idt_set_gate(i, interrupt_handler_table[i], 0x8, 0x8E); 
} 

주 오류 코드를 생성하는 CPU 예외. 또한 코드에서 불필요한 CLI 명령어를 제거했습니다. IDT에서 인터럽트 게이트를 사용하기 때문에 인터럽트 인 에이블 플래그가 자동으로 지워집니다.

+0

대단히 고맙습니다. –

관련 문제