OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 23, 2024 8:05 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: OS crashes whenever I press a key
PostPosted: Wed Apr 05, 2017 8:16 am 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2017 12:15 pm
Posts: 149
Location: Belgium
Whenever I press a key, instead of sending irq 1, it crashes my os with a triple fault. It does the same with the PIT, so I have disabled it for now. I have tried to do it manually with asm("int $1"), but it still crashes. I am compiling with gcc & nasm. Here are my codes:

irq.c:
Code:

#include "irq.h"

void* irq_routines[16] = {
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0
   
};

void irq_add_handler(int irq, void (*handler) (struct registers* r)) {
   irq_routines[irq] = handler;
   
}

void irq_remove_handler(int irq) {
   irq_routines[irq] = 0;
   
}

void irq_remap(void) {
   outportb(0x20, 0x11);
   outportb(0xA0, 0x11);
   
   outportb(0x21, 0x20);
   outportb(0xA1, 0x28);
   outportb(0x21, 0x04);
   outportb(0xA1, 0x02);
   outportb(0x21, 0x01);
   outportb(0xA1, 0x01);
   outportb(0x21, 0x0);
   outportb(0xA1, 0x0);
   
}

void irq_init(void) {
   irq_remap();
   
   set_idt_gate(32, (unsigned) irq0);
   set_idt_gate(33, (unsigned) irq1);
   set_idt_gate(34, (unsigned) irq2);
   set_idt_gate(35, (unsigned) irq3);
   set_idt_gate(36, (unsigned) irq4);
   set_idt_gate(37, (unsigned) irq5);
   set_idt_gate(38, (unsigned) irq6);
   set_idt_gate(39, (unsigned) irq7);
   set_idt_gate(40, (unsigned) irq8);
   set_idt_gate(41, (unsigned) irq9);
   set_idt_gate(42, (unsigned) irq10);
   set_idt_gate(43, (unsigned) irq11);
   set_idt_gate(44, (unsigned) irq12);
   set_idt_gate(45, (unsigned) irq13);
   set_idt_gate(46, (unsigned) irq14);
   set_idt_gate(47, (unsigned) irq15);
   
}

void irq_handler(struct registers* r) {
   void (*handler) (struct registers* r);
   handler = irq_routines[r->num - 32];
   
   if (handler) {
      handler(r);
      
   } if (r->num >= 40) {
      outportb(0xA0, 0x20);
      
   }
   
   outportb(0x20, 0x20);
   
}


I don't think irq.h is important. Its just some
Code:
extern void irq ... ();
.

keyboard.c
Code:

#include "keyboard_driver.h"

static uint8 press;
static uint8 release;

void keyboard_handler(struct registers* r) {
   uint8 scancode;
   scancode = inportb(0x60);
   
   println("Keypress", 0x07);
   
   if (scancode & 0x80) release = scancode;
   else press = scancode;
   
}

void keyboard_install(void) {
   while (inportb(0x64) & 0x1) {
      inportb(0x60);
      
   }
   
   outportb(0x64, 0xae);
   outportb(0x64, 0x20);
   
   uint8 status = (inportb(0x60) | 1) & ~0x10;
   
   outportb(0x64, 0x60);
   outportb(0x60, status);
   outportb(0x60, 0xf4);
   
   //irq_add_handler(33, keyboard_handler);
   irq_add_handler(1, keyboard_handler);
   
}

uint8 poll_key(void) {
   uint8 temp = press;
   press = 127;
   return temp;
   
}

uint8 poll_key_release(void) {
   uint8 temp = release;
   release = 127;
   return temp;
   
}

idt.c
Code:

static uint8 flags = 0x8E;

void set_idt_gate(int n, uint32 handler) {
   idt[n].high_offset = high_16(handler);
   idt[n].low_offset = low_16(handler);
   idt[n].sel = KERNEL_CS;
   
   idt[n].always0 = 0;
   idt[n].flags = flags;
   
}

void set_idt(void) {
   idt_reg.limit = (uint32) &idt;
   idt_reg.base = IDT_ENTRIES * sizeof(idt_gate_t) - 1;
   __asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg));
   
}

void set_idt_flags(uint8 _flags) {
   flags = _flags;
   
}


and the assembly for interrupts:

Code:
global irq0
continues up to...
global irq15

irq0:
   cli
   push byte 0
   push byte 32
   jmp irq_common

irq1:
   cli
   push byte 0
   push byte 33
   jmp irq_common .. and so on...

extern irq_handler
irq_common:
   pusha
   push ds
   push es
   push fs
   push gs
   
   mov ax, 0x10
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   
   mov eax, esp
   push eax
   mov eax, irq_handler
   call eax
   pop eax
   
   pop gs
   pop fs
   pop es
   pop ds
   popa
      
   add esp, 8
   iret


Thanks in advance!

_________________
AQUA OS: https://obiwac.wordpress.com/aqua-os/


Last edited by obiwac on Wed Apr 05, 2017 11:36 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Wed Apr 05, 2017 8:20 am 
Offline
Member
Member

Joined: Thu Aug 13, 2015 4:57 pm
Posts: 384
Did I read this wrong or did you mix these two up?
Code:
   idt_reg.limit = (uint32) &idt;
   idt_reg.base = IDT_ENTRIES * sizeof(idt_gate_t) - 1;


Also, would be useful if you'd do some troubleshooting first and tell us what you found, like single stepping with a debugger.. To some debuggers are intimidating but with OS dev you pretty much have to get used to it.


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Wed Apr 05, 2017 10:15 am 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2017 12:15 pm
Posts: 149
Location: Belgium
Thanks for your help!

Code:
dbf event: Fatal error! (hyper)
.eax=00000000 .ebx=00000000 .ecx=00000000 .edx=00000000 .esi=00000000 .edi=00000000
.eip=00000000 .esp=ff920000 .ebp=00000000 .iopl=0 nv up di pl nz na pe nc
.cs=0000 .ds=0000 .es=0000 .fs=0000 .gs=0000 .ss=0000              .eflags=00000000
u: error: DBGCCmdHlpVarToDbgfAddr failed on '0000:00000000 L 0': VERR_SELECTOR_NOT_PRESENT


So I get this in the virtualbox debugger. I don't really know what this means though.

_________________
AQUA OS: https://obiwac.wordpress.com/aqua-os/


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Wed Apr 05, 2017 12:54 pm 
Offline
Member
Member

Joined: Thu Aug 13, 2015 4:57 pm
Posts: 384
obiwac wrote:
Thanks for your help!

Code:
dbf event: Fatal error! (hyper)
.eax=00000000 .ebx=00000000 .ecx=00000000 .edx=00000000 .esi=00000000 .edi=00000000
.eip=00000000 .esp=ff920000 .ebp=00000000 .iopl=0 nv up di pl nz na pe nc
.cs=0000 .ds=0000 .es=0000 .fs=0000 .gs=0000 .ss=0000              .eflags=00000000
u: error: DBGCCmdHlpVarToDbgfAddr failed on '0000:00000000 L 0': VERR_SELECTOR_NOT_PRESENT


So I get this in the virtualbox debugger. I don't really know what this means though.

Don't know much about vbox, I prefer qemu and bochs. What exactly did you do and what happens?

Based on the error I would assume it's because your seg registers are all 0x0 (I'm assuming you're using protected mode):
.cs=0000 .ds=0000 .es=0000 .fs=0000 .gs=0000 .ss=0000 .eflags=00000000

You need use valid segment descriptors, not sure why they're all zero, did you set them all to zero?

Also, if this is your first go at osdev, I might recommend going thru the bare bones tutorial to get something working and then moving from there and when ever you get an issue you can easily roll back a couple of small changes getting back to working code and then figure out what exactly you did wrong. That is assuming you use version control, which you should =)


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Wed Apr 05, 2017 2:25 pm 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2017 12:15 pm
Posts: 149
Location: Belgium
But I do set them in the assembly irq_common label... And I don't set them to 0, I set them to ax which is set to 16.

_________________
AQUA OS: https://obiwac.wordpress.com/aqua-os/


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Wed Apr 05, 2017 3:11 pm 
Offline
Member
Member

Joined: Tue Feb 28, 2017 10:22 am
Posts: 25
In irq_common :
Code:
add esp, 8
iret

You forgot to send end of interrupt to the PIC before IRET !

I don't think this will solve the problem.
You should implement int0 - int31 handlers and display the called int number to the screen then sticks in an infinite loop to know what is the first called exception handler, which will tell you what goes wrong according to this page.


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Wed Apr 05, 2017 6:00 pm 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2017 12:15 pm
Posts: 149
Location: Belgium
Thanks! I do have ints 0-31 , and so I get a General Protection fault, and then a triple fault, and then my os crashes.

_________________
AQUA OS: https://obiwac.wordpress.com/aqua-os/


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Thu Apr 06, 2017 12:17 am 
Offline
Member
Member

Joined: Wed Sep 19, 2012 3:43 am
Posts: 91
Location: The Netherlands
Sounds to me like your IDT isn't set up properly.
Are you sure it's valid and loaded correctly? Could you post a dump (on bochs it's the 'info idt' debugger command)?


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Thu Apr 06, 2017 1:26 am 
Offline
Member
Member

Joined: Tue Feb 28, 2017 10:22 am
Posts: 25
Quote:
A General Protection Fault may occur for various reasons. The most common are:
- Segment error (privilege, type, limit, read/write rights).
- Executing a privileged instruction while CPL != 0.
- Writing a 1 in a reserved register field.
--> Referencing or accessing a null-descriptor.
The saved instruction pointer points to the instruction which caused the exception.


As LtG said, all of your segment registers are pointing to the null gdt entry. This could be your problem.


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Thu Apr 06, 2017 2:02 am 
Offline
Member
Member
User avatar

Joined: Sat Nov 22, 2014 6:33 pm
Posts: 934
Location: USA
obiwac wrote:
Code:
void irq_handler(struct registers* r) {
   void (*handler) (struct registers* r);
   handler = irq_routines[r->num - 32];


I don't think irq.h is important. Its just some
Code:
extern void irq ... ();
.

I think irq.h is important. It probably shows us the 'struct registers' definition.

In your code, the stack looks like:
Code:
push byte 0  [dword]
push byte 32 [dword]
pusha        [8 words]  (note, probably not dwords)
    ; should this be 'pushad'?
push ds  [dword]
push es  [dword]
push fs  [dword]
push gs  [dword]
push eax [dword]
call handler return value [dword]

You save the value in eax of the current stack location before calling the handler. The handler assumes the above format.
What does 'struct registers' look like?
Code:
struct registers {
  dword gs;
  dword fs;
  dword es;
  dword ds;
  word  pusha[8];
  dword num;
  dword zero;
};

I am guessing that you have modified the 'struct registers' and/or the 'push'es in the .asm code and they no longer match.

Then, here is the error I believe you have:
Code:
   handler = irq_routines[r->num - 32];

r->num = 0, so 'handler' above now has a value of 'undefined' since it grabs a value 32 dwords before the list of IRQ handlers you have.
i.e.:
Code:
   handler = irq_routines[0 - 32];
is the same as
Code:
   handler = irq_routines[-32];

which is in error...

Make sure your structure matches your pushes, and check whether the assembler is pushing words or dwords with the 'pusha' instruction. Then make sure your structure matches the pusha/pushad instruction.

Just my guess,
Ben
http://www.fysnet.net/osdesign_book_series.htm


Top
 Profile  
 
 Post subject: Re: OS crashes whenever I press a key
PostPosted: Thu Apr 06, 2017 2:28 am 
Offline
Member
Member
User avatar

Joined: Fri Jan 27, 2017 12:15 pm
Posts: 149
Location: Belgium
Thank you to everyone for having helped! I found out it was just a stupid little mistake. I was messing around once, and I remapped the keyboard interrupt to something else. Sorry for wasting your time! But maybe I should still look more in depth for the registers.

Code:
struct __attribute__((packed)) registers {
   unsigned int gs, fs, es, ds;
   unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax;
   unsigned int num, err_code;
   unsigned int eip, cs, eflags, useresp, ss;
   
};

_________________
AQUA OS: https://obiwac.wordpress.com/aqua-os/


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], SemrushBot [Bot] and 102 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