Page 1 of 3

Reading bad data from keyboard

Posted: Wed Oct 14, 2020 1:44 pm
by austanss
I'm contributing to an OSS osdev project.

Repo: https://github.com/novavita/Novix
[branch is work/rizet+pontaoski/keyboard-input]

I've been working quite a bit into getting keyboard input working. I've gotten help on some botched interrupts, and a broken multiboot header. The project was pretty much a trainwreck. They had written large portions of code without being able to test it. Multiboot header was broken, wouldn't boot. Booted, but triple faulted. Interrupts were all over the place. I've been working for the last week or two on making the OS functional. I've pretty much restored the broken OS, you can boot it and interrupts are working. I set out to create features. I decided to undertake the task of keyboard input. And now, here I am.

Like I said, my interrupts are working, however I feel like I am making some sort of mistake in the keyboard input. When I press a key, something is printed. Pressing different keys results in different things being printed. Cool. I went to the stage to convert the scan codes into characters, and my mistakes were shown to me.

I've linked a screenshot below where I press A on the keyboard.

My interrupt handler(s) (GDT.cpp)

Code: Select all

void InterruptHandler(Registers registers)
{
        if (registers.interruptNumber == 13)
                return;

        Terminal& terminal = Terminal::instance();

        if (registers.interruptNumber == 6)
        {
                uint8_t keycode = inb(0x60);

                if (keycode < 0 || keycode == prevKeyCode || keycode == 32)
                        return;

                writeHex(keycode);

                terminal << ", " << keycode << ", " << getChar(keycode) << Terminal::EOL;

                prevKeyCode = keycode;
        }

        terminal << "Interrupt: ";
        terminal << registers.interruptNumber;
        terminal << Terminal::EOL;
}

void ISRHandler(Registers registers)
{
        outb(0xA0, 0x20);
        InterruptHandler(registers);
        outb(0x20, 0x20);
}

void IRQHandler(Registers registers)
{
        if (registers.interruptNumber >= 40) outb(0xA0, 0x20); /* slave */
        InterruptHandler(registers);
        outb(0x20, 0x20); /* master */
}
writeHex and getChar (KernelUtil.cpp)

Code: Select all

char getChar(uint8_t keycode)
{
        switch (keycode)
        {
                case 0x49101:
                        return 'a';
                case 159:
                        return 's';
                case 160:
                        return 'd';
                case 161:
                        return 'f';
                default:
                        return ' ';
        }
}

void writeHex(int n)
{
        int tmp;

        Terminal::instance().write("0x");

        bool noZeroes = true;

        int i;
        for (i = 28; i > 0; i -= 4)
        {
                tmp = (n >> i) & 0xF;
                if (tmp == 0 && noZeroes)
                {
                        continue;
                }

                if (tmp >= 0xA)
                {
                        noZeroes = false;
                        Terminal::instance().write(tmp-0xA+'a');
                }
                else
                {
                        noZeroes = false;
                        Terminal::instance().write(tmp+'0');
                }
        }

        tmp = n & 0xF;
        if (tmp >= 0xA)
        {
                Terminal::instance().write(tmp-0xA+'a');
        }
        else
        {
                Terminal::instance().write(tmp+'0');
        }

}


Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 3:58 pm
by Octocontrabass
It's time to fix your exception handlers.

The first 32 interrupts are CPU exceptions. If you receive any of those, don't send an EOI, since they're not caused by an IRQ. Instead, print the CPU state at the time of the exception (the contents of the registers struct) and halt the CPU.

Once you've got that working, you can troubleshoot your IRQ handlers.

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 4:15 pm
by austanss
Octocontrabass wrote:It's time to fix your exception handlers.

The first 32 interrupts are CPU exceptions. If you receive any of those, don't send an EOI, since they're not caused by an IRQ. Instead, print the CPU state at the time of the exception (the contents of the registers struct) and halt the CPU.

Once you've got that working, you can troubleshoot your IRQ handlers.
I misconfigured my PIC (I believe). However, these interrupts arise when pressing a key, so is it that these interrupts are exceptions caused by my keyboard handling?

Also, if I did misconfigure my PIC, could I get advice on how to configure it properly?

I have suspicion that I misconfigured my PIC because keyboard is IRQ 1, and CMOS is IRQ 8. I am constantly spammed with interrupt 13, and when I press the keyboard I get an interrupt 6. This leads me to believe my PIC is misconfigured with an offset of +5.

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 5:03 pm
by Octocontrabass
rizxt wrote:I misconfigured my PIC (I believe). However, these interrupts arise when pressing a key, so is it that these interrupts are exceptions caused by my keyboard handling?
Yes. That's why you need exception handlers: you should not be receiving an exception when an IRQ occurs, so you need to figure out what's causing it so you can fix it.
rizxt wrote:I have suspicion that I misconfigured my PIC because keyboard is IRQ 1, and CMOS is IRQ 8. I am constantly spammed with interrupt 13, and when I press the keyboard I get an interrupt 6. This leads me to believe my PIC is misconfigured with an offset of +5.
The PIC is not capable of an offset of 5. Those are exceptions.

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 6:11 pm
by austanss
Octocontrabass wrote:
rizxt wrote:I misconfigured my PIC (I believe). However, these interrupts arise when pressing a key, so is it that these interrupts are exceptions caused by my keyboard handling?
Yes. That's why you need exception handlers: you should not be receiving an exception when an IRQ occurs, so you need to figure out what's causing it so you can fix it.
rizxt wrote:I have suspicion that I misconfigured my PIC because keyboard is IRQ 1, and CMOS is IRQ 8. I am constantly spammed with interrupt 13, and when I press the keyboard I get an interrupt 6. This leads me to believe my PIC is misconfigured with an offset of +5.
The PIC is not capable of an offset of 5. Those are exceptions.
my vga driver is broken and i have four lines to write once i boot

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 6:25 pm
by Octocontrabass
If you can't display text on the screen then use a serial port or the Bochs/QEMU debug console port.

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 9:38 pm
by austanss
Octocontrabass wrote:If you can't display text on the screen then use a serial port or the Bochs/QEMU debug console port.
Since I am too confused to do a serial port, I fixed my VGA driver instead. xD

The process was painstaking, getting an exception handler. Therefore, this is the input I get, after pressing ENTER in GRUB.
Screenshot_20201014_233536.png
Screenshot_20201014_233536.png (3.61 KiB) Viewed 2661 times
This is the format:
Screenshot_20201014_233910.png

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 9:59 pm
by Octocontrabass
Printing in decimal is an odd choice.

That's #UD caused by the instruction at address 0x1000D. According to your linker script, none of your code is at that address, so you're jumping to nonsense for some reason. One possible explanation is that your C code is clobbering the saved register state on the stack, which is a common issue thanks to one popular tutorial with the same bug. If that's not the issue, you might need a debugger to track it down.

Are you ignoring interrupt 13? That one is pretty important.

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 10:01 pm
by austanss

Re: Reading bad data from keyboard

Posted: Wed Oct 14, 2020 10:03 pm
by Octocontrabass
Well... don't do that. You need to know when it happens so you can fix it.

Re: Reading bad data from keyboard

Posted: Thu Oct 15, 2020 7:08 am
by austanss
Octocontrabass wrote:Well... don't do that. You need to know when it happens so you can fix it.
It happens constantly. Never stops. All the time.

Re: Reading bad data from keyboard

Posted: Thu Oct 15, 2020 7:53 am
by iansjack
If you are receiving constant General Protection exceptions then there is something very wrong with your OS. You need to know which instructions are causing the fault, hence you need an exception handler.

Before you do anything else you need to sort out the initialization of the PIC and you need basic exception handlers. This is very basic stuff.

From what you have said so far the organization of your project sounds abysmal and the knowledge of those involved seems to be minimal. You might be better employed reading the Intel Programmer's Manual and gaining a basic understanding of the processor rather than jumping in at the deep end and trying to write an operating system between you. And get someone who knows what they are doing to act as project leader.

Alternatively, ditch this doomed project and start off on your own. There's a limit to how many times you can expect hand-holding from forum members with what are very basic problems.

Re: Reading bad data from keyboard

Posted: Thu Oct 15, 2020 8:48 am
by bloodline
iansjack wrote:If you are receiving constant General Protection exceptions then there is something very wrong with your OS. You need to know which instructions are causing the fault, hence you need an exception handler.

Before you do anything else you need to sort out the initialization of the PIC and you need basic exception handlers. This is very basic stuff.

From what you have said so far the organization of your project sounds abysmal and the knowledge of those involved seems to be minimal. You might be better employed reading the Intel Programmer's Manual and gaining a basic understanding of the processor rather than jumping in at the deep end and trying to write an operating system between you. And get someone who knows what they are doing to act as project leader.

Alternatively, ditch this doomed project and start off on your own. There's a limit to how many times you can expect hand-holding from forum members with what are very basic problems.
I agree with iansjack, just start from scratch. You’ll learn much faster, as you will understand exactly what every step is doing.

I started with the barebones example on this site, then added keyboard polling. Then added exception handling, then added interrupts... Then I moved keyboard handling to an interrupt. Do everything on stages made understanding the hardware much easier. Make sure to only make one addition at a time, so you know what has broken when it stops working.

Re: Reading bad data from keyboard

Posted: Thu Oct 15, 2020 9:14 am
by austanss
bloodline wrote:
iansjack wrote:If you are receiving constant General Protection exceptions then there is something very wrong with your OS. You need to know which instructions are causing the fault, hence you need an exception handler.

Before you do anything else you need to sort out the initialization of the PIC and you need basic exception handlers. This is very basic stuff.

From what you have said so far the organization of your project sounds abysmal and the knowledge of those involved seems to be minimal. You might be better employed reading the Intel Programmer's Manual and gaining a basic understanding of the processor rather than jumping in at the deep end and trying to write an operating system between you. And get someone who knows what they are doing to act as project leader.

Alternatively, ditch this doomed project and start off on your own. There's a limit to how many times you can expect hand-holding from forum members with what are very basic problems.
I agree with iansjack, just start from scratch. You’ll learn much faster, as you will understand exactly what every step is doing.

I started with the barebones example on this site, then added keyboard polling. Then added exception handling, then added interrupts... Then I moved keyboard handling to an interrupt. Do everything on stages made understanding the hardware much easier.
I love everyone on this project. I couldn't stand to leave them, not with as much progress as I have contributed to this project. Therefore, we have kicked off a project to clean up and make our code robust and stable.

Re: Reading bad data from keyboard

Posted: Thu Oct 15, 2020 9:28 am
by bloodline
rizxt wrote:
bloodline wrote:
iansjack wrote:If you are receiving constant General Protection exceptions then there is something very wrong with your OS. You need to know which instructions are causing the fault, hence you need an exception handler.

Before you do anything else you need to sort out the initialization of the PIC and you need basic exception handlers. This is very basic stuff.

From what you have said so far the organization of your project sounds abysmal and the knowledge of those involved seems to be minimal. You might be better employed reading the Intel Programmer's Manual and gaining a basic understanding of the processor rather than jumping in at the deep end and trying to write an operating system between you. And get someone who knows what they are doing to act as project leader.

Alternatively, ditch this doomed project and start off on your own. There's a limit to how many times you can expect hand-holding from forum members with what are very basic problems.
I agree with iansjack, just start from scratch. You’ll learn much faster, as you will understand exactly what every step is doing.

I started with the barebones example on this site, then added keyboard polling. Then added exception handling, then added interrupts... Then I moved keyboard handling to an interrupt. Do everything on stages made understanding the hardware much easier.
I love everyone on this project. I couldn't stand to leave them, not with as much progress as I have contributed to this project. Therefore, we have kicked off a project to clean up and make our code robust and stable.
If you start with the barebones example, you can add parts of the code from your existing project one functional part at a time, that way you can see if each part is doing what you expect it to!

-edit- and use version control. :D