Keystroke crashes real PC

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
iProgramInCpp
Member
Member
Posts: 81
Joined: Sun Apr 21, 2019 7:39 am

Keystroke crashes real PC

Post by iProgramInCpp »

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
Hey! I'm developing two operating systems:

NanoShell --- A 32-bit operating system whose GUI takes inspiration from Windows 9x and early UNIX desktop managers.
Boron --- A portable SMP operating system taking inspiration from the design of the Windows NT kernel.
Octocontrabass
Member
Member
Posts: 5584
Joined: Mon Mar 25, 2013 7:01 pm

Re: Keystroke crashes real PC

Post by Octocontrabass »

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.)
iProgramInCpp
Member
Member
Posts: 81
Joined: Sun Apr 21, 2019 7:39 am

Re: Keystroke crashes real PC

Post by iProgramInCpp »

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)
Hey! I'm developing two operating systems:

NanoShell --- A 32-bit operating system whose GUI takes inspiration from Windows 9x and early UNIX desktop managers.
Boron --- A portable SMP operating system taking inspiration from the design of the Windows NT kernel.
Octocontrabass
Member
Member
Posts: 5584
Joined: Mon Mar 25, 2013 7:01 pm

Re: Keystroke crashes real PC

Post by Octocontrabass »

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.
MichaelPetch
Member
Member
Posts: 798
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Keystroke crashes real PC

Post by MichaelPetch »

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:
‘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:
‘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.
iProgramInCpp
Member
Member
Posts: 81
Joined: Sun Apr 21, 2019 7:39 am

Re: Keystroke crashes real PC

Post by iProgramInCpp »

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)
Hey! I'm developing two operating systems:

NanoShell --- A 32-bit operating system whose GUI takes inspiration from Windows 9x and early UNIX desktop managers.
Boron --- A portable SMP operating system taking inspiration from the design of the Windows NT kernel.
MichaelPetch
Member
Member
Posts: 798
Joined: Fri Aug 26, 2016 1:41 pm
Libera.chat IRC: mpetch

Re: Keystroke crashes real PC

Post by MichaelPetch »

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
iProgramInCpp
Member
Member
Posts: 81
Joined: Sun Apr 21, 2019 7:39 am

Re: Keystroke crashes real PC

Post by iProgramInCpp »

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!
Hey! I'm developing two operating systems:

NanoShell --- A 32-bit operating system whose GUI takes inspiration from Windows 9x and early UNIX desktop managers.
Boron --- A portable SMP operating system taking inspiration from the design of the Windows NT kernel.
iProgramInCpp
Member
Member
Posts: 81
Joined: Sun Apr 21, 2019 7:39 am

Re: Keystroke crashes real PC

Post by iProgramInCpp »

It now works. Thank you very much for your help!
Hey! I'm developing two operating systems:

NanoShell --- A 32-bit operating system whose GUI takes inspiration from Windows 9x and early UNIX desktop managers.
Boron --- A portable SMP operating system taking inspiration from the design of the Windows NT kernel.
Post Reply