kernel - Asm volatile ("int $0x3") call restarts the machine -
i studying kernel development. test interrupt handler need run asm volatile ("idt $0x3") command. whenever command called in main.c, machine restarts. tried remove interrupt handler. nothing changed. should do?
gdt assembly:
[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 } interrupt.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
i converted descriptor_tables.c c code assembly code , used following macro:
%macro idt_entry 1 dw _isr%1 dw 0x08 db 0x0 db 0x8e dw 0x0000 %endmacro now, works. not sure why did not accept c code. moreover, following macro did not work either:
%macro idt_entry 1 dw (_isr%1 - $$) & 0xffff dw 0x08 db 0x0 db 0x8e dw ((_isr%1 - $$) >> 16) & 0xffff %endmacro again, not sure why second macro not working.
Comments
Post a Comment