Page 1 of 1

What is the valid IDT descriptor for hardware interrupts?

Posted: Sat Jun 20, 2020 1:23 pm
by antoni
I have set_intr_gate function to set some interrupts. In general, I predicted three functions: set_intr_gate, set_trap_gate and set_system_gate. set_intr_gate looks like this:

Code: Select all

void set_intr_gate(s32int n,void *addr)
{

        idt[n].offset_low = (u64int) addr & 0xFFFF;
        idt[n].selector = 8;
        idt[n].ist = 0;
        idt[n].type_attr = 142;
        idt[n].offset_middle = ( (u64int) addr & 0xFFFF0000) >> 16;
        idt[n].offset_high = ( (u64int) addr & 0xFFFFFFFF00000000) >> 32;
        idt[n].zero = 0;

}
When I use this function to set the interrupt like below it works:

Code: Select all

extern void int_handler(void);
set_system_gate(49, &int_handler);

asm("int $49");
But when I try to set a hardware interrupt like this:

Code: Select all

set_intr_gate(0x21, &irq1); //irq1
enable_irq(1);
This results in the processor halt after pressing any key. Of course irq1 is not called what I checked in GDB.

Re: What is the valid IDT descriptor for hardware interrupts

Posted: Sun Jun 21, 2020 7:38 am
by Octocontrabass
I see no problems with this code (although you really should use stdint.h instead of defining your own integer types).

Do you perhaps have your code available on an online repository so I can look at all of it?

Re: What is the valid IDT descriptor for hardware interrupts

Posted: Sun Jun 21, 2020 9:08 am
by antoni
CORRECTION:

It's not true that my handler is not even called. I checked it in GDB again. I probably had the wrong symbol file loaded at the time.

SHORT DESCRIPTION HOW MY CODE WORKS:

My code is well written, but kernel.c, idt.c, intr.c are chaotic because I have been debugging IDT for a long time and have tried many things. idttest.s, idttest.asm and structs.c files are junk that I also used to test IDT and are now unnecessary.

My code works something like this:
kernel.h - file with many extern expressions. All functions that I want to use in other files are defined there. I attach this file to each file.

init.asm - loads GDT, enters 64-bit mode and calls the main function "kernel_start" in the kernel.c file. It has a multiboot header.

kernel.c - Contains only one function - "kernel_start". It's similar to main function.

make.sh - A script that builds the project. Used with the "-b" option builds only the symbol file for GDB. Used with the "-i" option builds an ISO image that can be run, for example with "qemu-system-x86_64 -hda kernel.iso" command. If no option is used, the default is "-i".

kernel.ld - Linker script.

Other files have some functions that you can use with kernel_start. You are only interested in a fragment from 24'th to 28'th line in kernel_start. It looks like this:

Code: Select all

idt_init();

//keyboard init
set_intr_gate(0x21, &irq1); //irq1
enable_irq(1);
Functions in this fragment:

idt_init - Reroutes hardware interrupts and loads IDT. And also executes "sti".
set_intr_gate - Sets entry in IDT
enable_irq - Enables interrupt

WHAT'S THE PROBLEM?


When I press any key, the irq1 function from irqs.asm file is called, irq1 function calls kbd_irq function from kbd.c file. Then the kbd_irq function returns, but irq1 does not. GDB writes something like this to me:

Code: Select all

(gdb) n
0x00000000001257b1 in irq1 ()
(gdb) n
Single stepping until exit from function irq1,
which has no line number information.
0x000000000000e05b in ?? ()
In this moment processor halts. You can find compressed archive with code here: https://ufile.io/i0j1e2k7

Re: What is the valid IDT descriptor for hardware interrupts

Posted: Sun Jun 21, 2020 9:19 am
by Octocontrabass
When assembling 64-bit code, NASM assumes IRET refers to the 32-bit form (IRETD). You must specify IRETQ to get the 64-bit instruction.

Keep in mind your IRQ handler may interrupt your code at any point, so you must preserve any registers that it may clobber.You must also ensure the stack is aligned correctly and the direction flag is cleared before calling any C code. Refer to the appropriate System V ABI Processor Supplement for details.

Re: What is the valid IDT descriptor for hardware interrupts

Posted: Sun Jun 21, 2020 12:20 pm
by antoni
I corrected what you wrote and now irqs.asm code looks like below. Unfortunately it still doesn't work. Error is the same.

Code: Select all

BITS 64

global irq1 ;keyboard
irq1:

        push rax
        push rbx
        push rcx
        push rdx
        push rsi
        push rdi
        push rbp
        push rsp
        push r8
        push r9
        push r10
        push r11
        push r12
        push r13
        push r14
        push r15

        extern kbd_irq
        call kbd_irq

        pop r15
        pop r14
        pop r13
        pop r12
        pop r11
        pop r10
        pop r9
        pop r8
        pop rsp
        pop rbp
        pop rdi
        pop rsi
        pop rdx
        pop rcx
        pop rbx
        pop rax

        cld ;clear direction flag

iretq

Re: What is the valid IDT descriptor for hardware interrupts

Posted: Mon Jun 22, 2020 12:18 pm
by Octocontrabass
antoni wrote:0x000000000000e05b
This address is the second instruction of the BIOS ROM. Your code is triple faulting. Try installing exception handlers to see what's going wrong, or have your emulator log the fault.

Re: What is the valid IDT descriptor for hardware interrupts

Posted: Tue Jun 23, 2020 7:16 am
by antoni
It looks like I'm receiving general protection fault with error code 24.

EDIT:

It's interesting cause I only have 3 descriptors in my GDT: zero, data and code.

Re: What is the valid IDT descriptor for hardware interrupts

Posted: Tue Jun 23, 2020 9:53 am
by Octocontrabass
Which instruction is causing the fault? You should be able to locate it by the return address on the stack, if you've written your own #GP handler.