OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 3:22 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: my keyboard interrupt not working when run with qemu
PostPosted: Thu Oct 20, 2022 12:09 am 
Offline

Joined: Thu Oct 20, 2022 12:05 am
Posts: 3
I am learning to develop a small os, it now can initialise GDT, IDT, display some text at screen, I am now trying to get keyboard interrupt, the example code I got from 30days diy OS by OSASK on day6 harib03e works. But my implementation not working, source code is at https://github.com/Lewis-Liu-1/myos/tree/main/day6/daye.

From web search, I realise I only load GDT, IDT, load kernel, not configuring keyboard, to enable PS/2 interrupt somehow. But I don't know how to do that.


Top
 Profile  
 
 Post subject: Re: my keyboard interrupt not working when run with qemu
PostPosted: Thu Oct 20, 2022 9:06 am 
Offline
Member
Member

Joined: Fri Feb 11, 2022 4:55 am
Posts: 435
Location: behind the keyboard
I guess you have remapped the pic right ?
The wiki has the answers, however here is the code to unmask keyboard interrupts :

Code:
#define PIC1                0x20                /* IO base address for master PIC */
#define PIC2                0xA0                /* IO base address for slave PIC */
#define PIC1_COMMAND        PIC1
#define PIC1_DATA        (PIC1+1)
#define PIC2_COMMAND        PIC2
#define PIC2_DATA        (PIC2+1)
#define PIC_EOI                0x20                /* End-of-interrupt command code */


void init_ps2_keyboard(){
        OutPortB(PIC1_DATA,0b11111000);
        OutPortB(PIC2_DATA,0b11101111);
}


To handle the interrupt, you must first read the keypress value from the 0x60 port : "inb 0x60".

When you are about to return from the interrupt you must signal EOI to the pic (End of interrupt) to the master, call this function at the end :

Code:
void pic_end_master(){
        OutPortB(PIC1_COMMAND,PIC_EOI);
}


Top
 Profile  
 
 Post subject: Re: my keyboard interrupt not working when run with qemu
PostPosted: Thu Oct 20, 2022 10:09 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
yyiu002 wrote:
From web search, I realise I only load GDT, IDT, load kernel, not configuring keyboard, to enable PS/2 interrupt somehow. But I don't know how to do that.

When you initialize the IDT, you also initialize the PIC. Initializing the PIC causes the PIC to lose any pending interrupts. If there is a pending PS/2 interrupt when you initialize the PIC, the PS/2 controller will be waiting for you to acknowledge the interrupt by reading port 0x60, but the PIC won't deliver the interrupt.

Try reading port 0x60 after you initialize the PIC.

devc1 wrote:
When you are about to return from the interrupt you must signal EOI to the pic

The PIC has an auto-EOI mode.


Top
 Profile  
 
 Post subject: Re: my keyboard interrupt not working when run with qemu
PostPosted: Thu Oct 20, 2022 6:28 pm 
Offline

Joined: Thu Oct 20, 2022 12:05 am
Posts: 3
Thanks all for your help.

I tried not initialise GDT, seems working, like following:

Code:
#define ADR_IDT         0x0026f800
#define LIMIT_IDT      0x000007ff
#define ADR_GDT         0x00270000
#define LIMIT_GDT      0x0000ffff
#define ADR_BOTPAK      0x00280000
#define LIMIT_BOTPAK   0x0007ffff
#define AR_DATA32_RW   0x4092
#define AR_CODE32_ER   0x409a
#define AR_INTGATE32   0x008e

void init_gdt_idt(void)
{
   struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT;
   struct GATE_DESCRIPTOR    *idt = (struct GATE_DESCRIPTOR    *) ADR_IDT;
   int i;

#if 0
   for (i = 0; i <= LIMIT_GDT / 8; i++) {
      set_segmdesc(gdt + i, 0, 0, 0);
   }
   set_segmdesc(gdt + 1, 0xffffffff,   0x00000000, AR_DATA32_RW);
   set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER);
   load_gdtr(LIMIT_GDT, ADR_GDT);
#endif
   /* IDT�̏����� */
   for (i = 0; i <= LIMIT_IDT / 8; i++) {
      set_gatedesc(idt + i, 0, 0, 0);
   }
   load_idtr2(LIMIT_IDT, ADR_IDT);

   set_gatedesc(idt + 0x21, (int) asm_inthandler21, 1 * 8, AR_INTGATE32);
   set_gatedesc(idt + 0x27, (int) asm_inthandler27, 1 * 8, AR_INTGATE32);
   set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 1 * 8, AR_INTGATE32);

   initialize_pic();
   io_sti();

}


initialise GDT will set code and data to new location, does it mean I have to move code to those location, before initialise IDT?

I also saw following code:

Code:
   set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32);
   set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32);
   set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32);


previous pat is "1*8", this time selector is "2*8", why?


Top
 Profile  
 
 Post subject: Re: my keyboard interrupt not working when run with qemu
PostPosted: Thu Oct 20, 2022 6:39 pm 
Offline

Joined: Thu Oct 20, 2022 12:05 am
Posts: 3
Continue my question.
at entry.S I have a called LGDT instruction, which loads GDT tables etc. Therefore at above function init_gdt_idt, initialise GDT is not necessary anymore.

Initialise GDT twice will cause issues, why?


Top
 Profile  
 
 Post subject: Re: my keyboard interrupt not working when run with qemu
PostPosted: Thu Oct 20, 2022 6:43 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
yyiu002 wrote:
initialise GDT will set code and data to new location, does it mean I have to move code to those location, before initialise IDT?

You should set the base to 0 and the limit to 0xFFFFFFFF for your code and data segments.

yyiu002 wrote:
previous pat is "1*8", this time selector is "2*8", why?

That's the code segment selector. The correct selector depends on where you put the code segment in your GDT.

yyiu002 wrote:
Initialise GDT twice will cause issues, why?

You didn't set the base to 0 and the limit to 0xFFFFFFFF.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: DotBot [Bot] and 71 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group