Вызов Asm volatile (int $0x3) перезапускает машину

Я изучаю разработку ядра. Чтобы протестировать мой обработчик прерываний, мне нужно запустить команду asm volatile ("idt $0x3"). Всякий раз, когда эта команда вызывается в моем main.c, машина всегда перезагружается. Я даже пытался удалить обработчик прерывания. Ничего не изменилось. Что я должен делать?

сборка гдт:

[extern _start]

lgdt [gdt_descriptor]
jmp CODE_SEG:initgdt

initgdt:
mov ax, DATA_SEG     
mov ds, ax       
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
mov ebp, 0x90000
mov esp, ebp
call _start ;main.c function
jmp $

gdt_star:

gdt_null:
dd 0x0      
dd 0x0      

gdt_code:
dw 0xffff   
dw 0x0010
db 0x00     
db 10011011b
db 01001111b
db 0x00 

gdt_data:
dw 0xffff
dw 0x0020
db 0x00
db 10010010b
db 01001111b
db 0x0              


gdt_end:

gdt_descriptor:
dw gdt_end - gdt_star - 1
dd gdt_star

CODE_SEG equ gdt_code - gdt_star
DATA_SEG equ gdt_data - gdt_star

descriptor_tables.c:

extern void idt_flush(uint32_t);
extern void isr0();
extern void isr1();
....
extern void isr31();


static void init_idt()
{
    idt_ptr.limit = sizeof(idt_entry_t) * 256 -1;
    idt_ptr.base  = (uint32_t)&idt_entries;

    memset((uint8_t*)&idt_entries, 0, sizeof(idt_entry_t)*256);

    idt_set_gate(0, (uint32_t)isr0, 0x08, 0x8E);
    idt_set_gate(1, (uint32_t)isr1, 0x08, 0x8E);
    ....
    idt_set_gate(31, (uint32_t)isr31, 0x08, 0x8E);

    idt_flush((uint32_t)&idt_ptr);
}

static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
{
   idt_entries[num].base_lo = base & 0xFFFF;
   idt_entries[num].base_hi = (base >> 16) & 0xFFFF;

   idt_entries[num].sel     = sel;
   idt_entries[num].always0 = 0;
   idt_entries[num].flags   = flags
}

прерывание.asm:

%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

ISR_NOERRCODE 0
ISR_NOERRCODE 1
....
ISR_NOERRCODE 31

[EXTERN _isr_handler]

isr_common_stub:
pusha                    

mov ax, ds               
push eax                

mov ax, 0x10 
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

call _isr_handler

pop eax        
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

popa                    
add esp, 8     
sti
iret  

isr.c:

void isr_handler(registers_t regs)
{
   uint8_t str[12] = "\ninterrupt:";
   str[11] = 0;
   puts(str, FALSE);
   itoa(str, 10, regs.int_no);
   puts(str, FALSE);
   str[0] = '\n';
   str[1] = 0;
   puts(str, TRUE);
}

kernel_entry.asm:

....
[global _idt_flush]
_idt_flush:
   mov eax, [esp+4]  
   lidt [eax]       
   ret

person user2972185    schedule 19.08.2014    source источник
comment
Вы настроили GDT и IDT? Без этих прерываний ничего не получится. Также, если вы можете, пожалуйста, ссылку на соответствующий код. Я подозреваю, что вы неправильно настроили таблицы GDT и IDT.   -  person Jesus Ramos    schedule 19.08.2014
comment
Без соответствующего кода трудно угадать проблему. Можете ли вы опубликовать некоторые фрагменты вашей настройки IDT/GDT, а также код обработки прерываний.   -  person Jesus Ramos    schedule 19.08.2014
comment
Я вижу, что ваш ISR настроен, но нет соответствующего кода для настройки IRQ. Не уверен, что это вызовет это. Также вы пробовали, чтобы ваш isr_handler ничего не делал? Я просто хочу убедиться, что ваши функции put и itoa не вызывают исключения процессора.   -  person Jesus Ramos    schedule 19.08.2014
comment
Нет, проблема не в этом. Вы бы прочитали мой ответ? Я решил проблему, но у меня остались вопросы. Спасибо.   -  person user2972185    schedule 20.08.2014


Ответы (1)


Я преобразовал код C descriptor_tables.c в код сборки и использовал следующий макрос:

%macro IDT_ENTRY 1
dw _isr%1
dw 0x08
db 0x0
db 0x8E
dw 0x0000
%endmacro

Теперь это работает. Но я не уверен, почему он не принял код C. Более того, следующий макрос также не сработал:

%macro IDT_ENTRY 1
dw (_isr%1 - $$) & 0xFFFF
dw 0x08
db 0x0
db 0x8E
dw ((_isr%1 - $$) >> 16) & 0xFFFF
%endmacro

Опять же, я не уверен, почему второй макрос не работает.

person user2972185    schedule 19.08.2014