OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Jun 26, 2019 2:35 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: Keystroke crashes real PC
PostPosted: Mon May 06, 2019 11:59 am 
Offline

Joined: Sun Apr 21, 2019 7:39 am
Posts: 15
I have a problem with my keyboard. Every time I press any key, the computer reboots. Doesn't matter if I'm using a real PS/2 keyboard or emulating it, still reboots.
Tested on 3 PCs so far.

I have a suspicion it's somehow linked to keyboard interrupts, but I have no idea how keyboard interrupts work (I'll have to read up on them).
I tried using 'ret' instead of 'iretd', but the code never returns to the program (which is expected, seeing as 'iretd' seems to be an interrupt-specific instruction).
The code works fine in QEMU, haven't tested in VBox or VMware. Will test soon.

Here's the minimal code (still crashes after that).
I've supplied a multiboot ELF file so you can test.
https://github.com/iProgramMC/osdev-example


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Mon May 06, 2019 12:38 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1548
When an interrupt occurs, the CPU loads the CS segment selector from the IDT, and uses that selector to load the segment descriptor from the GDT. When the IRET instruction executes, the CPU pops the CS segment selector from the stack, and uses that selector to load the segment descriptor from the GDT.

Where did you define your GDT?


There are also several places where your code doesn't follow the ABI. It's not a good thing when your interrupt handler clobbers registers.


(On an unrelated note, why do you have so much code in your header files? Headers should be used primarily for declarations, add a few .c files for function definitions.)


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Mon May 06, 2019 1:05 pm 
Offline

Joined: Sun Apr 21, 2019 7:39 am
Posts: 15
Octocontrabass wrote:
Where did you define your GDT?

I thought it wouldn't be required for grub.

Octocontrabass wrote:
There are also several places where your code doesn't follow the ABI. It's not a good thing when your interrupt handler clobbers registers.

What do you mean?

Octocontrabass wrote:
(On an unrelated note, why do you have so much code in your header files? Headers should be used primarily for declarations, add a few .c files for function definitions.)

I don't want to bother with Makefiles.
Plus, it gives the advantage that you can essentially store all the code in one file (with a few exceptions, such as assembly code)


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Mon May 06, 2019 1:25 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 1548
iProgramInCpp wrote:
I thought it wouldn't be required for grub.

GRUB makes no guarantee about the presence or contents of the GDT. You must define your own GDT before you can do things that rely on the GDT.

iProgramInCpp wrote:
What do you mean?

The System V ABI guarantees that C functions will preserve EBX, ESI, EDI, EBP, and ESP, but functions can and will change EAX, ECX, and EDX. Since your interrupt handler calls a C function, it can modify EAX/ECX/EDX, potentially corrupting the state of whatever was running at the time the interrupt occurred. You must ensure your interrupt handler saves and restores those registers, or it will cause issues in the future.

Additionally, the ABI requires that the Direction flag is clear when any C function is called. Since your interrupt handler may interrupt a function that was not written in C, you must clear the Direction flag. (However, you don't need to worry about saving or restoring it: the CPU saves the flags when an interrupt occurs, and the IRET instruction restores them.)

iProgramInCpp wrote:
I don't want to bother with Makefiles.

You don't need to use a makefile. You can keep using a batch script, or find another build system.

iProgramInCpp wrote:
Plus, it gives the advantage that you can essentially store all the code in one file (with a few exceptions, such as assembly code)

I don't see how that's an advantage.


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Mon May 06, 2019 1:51 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 426
iProgramInCpp wrote:
Octocontrabass wrote:
Where did you define your GDT?

I thought it wouldn't be required for grub.
This is just to clarify what Octo is saying. The multiboot spec has a warning about this when it says:
Quote:
‘GDTR’
Even though the segment registers are set up as described above, the ‘GDTR’ may be invalid, so the OS image must not load any segment registers (even just reloading the same values!) until it sets up its own ‘GDT’.
The moment the first IRQ fires CS will be reloaded and if there isn't a valid GDTR or GDT you will have problems. You may find that with a real version of GRUB (booting from an ISO for example) and running QEMU with the `-kernel` option to test may behave differently. If it worked it was just by luck.

The Multiboot spec also puts no guarantee on what the selector values for the Code Segment and Data Segment actually are. It does tell you how they will be laid out but doesn't say that selectors have to be a particular value. A Multiboot compliant loader could use CS as 0x08 and another version uses 0x10 (or any other legal values). The same applies to all the data segments as well. The spec says:
Quote:
‘CS’
Must be a 32-bit read/execute code segment with an offset of ‘0’ and a limit of ‘0xFFFFFFFF’. The exact value is undefined.
‘DS’
‘ES’
‘FS’
‘GS’
‘SS’
Must be a 32-bit read/write data segment with an offset of ‘0’ and a limit of ‘0xFFFFFFFF’. The exact values are all undefined.
You'll note that it says specifically "The exact value is undefined". When you create an IDT you need to specify the value of CS in each IDT entry. If you don't set up your own GDT with the descriptors you need you won't know for certain what CS value to use.

Ultimately this basically means with a Multiboot loader you need to use your own GDT the moment you want to use interrupts in protected mode.


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Mon May 06, 2019 1:57 pm 
Offline

Joined: Sun Apr 21, 2019 7:39 am
Posts: 15
I'm currently trying to figure out how I can set up the GDT, however my attempt (most recent commit to that code) fails and triple faults on the InitGDT line.

The part I'm stuck in is the "access byte" and "flags" (found it on Wikipedia)


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Mon May 06, 2019 2:41 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 426
I wrote a Stackoveflow answer about this Multiboot/GDT issue and I posted some NASM code that sets up a basic GDT. https://stackoverflow.com/a/43171871/3857942


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Tue May 07, 2019 12:51 am 
Offline

Joined: Sun Apr 21, 2019 7:39 am
Posts: 15
MichaelPetch wrote:
I wrote a Stackoveflow answer about this Multiboot/GDT issue and I posted some NASM code that sets up a basic GDT. https://stackoverflow.com/a/43171871/3857942

I'm currently busy with school, I'll try it when I get home. Thanks!


Top
 Profile  
 
 Post subject: Re: Keystroke crashes real PC
PostPosted: Tue May 07, 2019 6:21 am 
Offline

Joined: Sun Apr 21, 2019 7:39 am
Posts: 15
It now works. Thank you very much for your help!


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

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 9 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