Keyboard interrupt handler not working on iso system

I am trying to write an operating system using osdev and others. Now I'm stuck in a keyboard interrupt handler. When I compile my OS and start only the kernel with qemu-system-i386 -kernel kernel/myos.kernel, everything works fine, but when I put everything in the ISO and try to start it with qemu-system-i386 -cdrom myos.iso, it loads, but when I press any button on the keyboard, it restarts. I think this is caused by some problems in the address of the interrupt handler in the IDT record.

Here:

-my-handler (gnu as syntax):

.globl   keyboard_handler
.align   4

keyboard_handler:

    pushal
    cld 
    call keyboard_handler_main
    popal
    iret

-my main handler (c):

void keyboard_handler_main(void) {
    unsigned char status;
  char keycode;
    /* write EOI */
    write_port(0x20, 0x20);

    status = read_port(KEYBOARD_STATUS_PORT);
    /* Lowest bit of status will be set if buffer is not empty */
    if (status & 0x01) {
        keycode = read_port(KEYBOARD_DATA_PORT);
        if(keycode < 0)
            return;

        if(keycode == ENTER_KEY_CODE) {
            printf("\n");
            return;
        }
        printf("%c", keyboard_map[(unsigned char) keycode]);
    }
}

-function, I use to download IDT (c):

void idt_init(void)
{
    //unsigned long keyboard_address;
    unsigned long idt_address;
    unsigned long idt_ptr[2];

    auto keyboard_address = (*keyboard_handler);

    IDT[0x21].offset_lowerbits = keyboard_address & 0xffff;
    IDT[0x21].selector = KERNEL_CODE_SEGMENT_OFFSET;
    IDT[0x21].zero = 0;
    IDT[0x21].type_attr = INTERRUPT_GATE;
    IDT[0x21].offset_higherbits = (keyboard_address & 0xffff0000) >> 16;

    /*     Ports
    *    PIC1   PIC2
    *Command 0x20   0xA0
    *Data    0x21   0xA1
    */

    write_port(0x20 , 0x11);
    write_port(0xA0 , 0x11);

    write_port(0x21 , 0x20);
    write_port(0xA1 , 0x28);

    write_port(0x21 , 0x00);
    write_port(0xA1 , 0x00);

    write_port(0x21 , 0x01);
    write_port(0xA1 , 0x01);

    write_port(0x21 , 0xff);
    write_port(0xA1 , 0xff);

    idt_address = (unsigned long)IDT ;
    idt_ptr[0] = (sizeof (struct IDT_entry) * IDT_SIZE) + ((idt_address & 0xffff) << 16);
    idt_ptr[1] = idt_address >> 16 ;

    load_idt(idt_ptr);

    printf("%s\n", "loadd");
}

The files are organized like this: http://wiki.osdev.org/Meaty_Skeleton , but I have another bootloader.

, - , . , 13 , , .

+4
1

, , , GDT . , - , QEMU -kernel, GRUB, , GDT. Mulitboot :

‘GDTR’ , , , "GDTR , ( !), " GDT ".

QEMU -kernel GDTR , . GRUB ( , , ISO ..) , GDTR . , ( ), . (CS) , .

, Multiboot , . GDT Multiboot, IDT. IDT , .

Meaty Skeleton OSDev , , , QEMU -kernel GRUB. IDT , , , GRUB. , GDT , Multiboot.

+2
source

Source: https://habr.com/ru/post/1692501/


All Articles