在保护模式下读取键盘

Read the keyboard in protected mode

我正在尝试做一个 PS/2 键盘控制器,但我无法让它工作。

outb(0x60, 0xED);
outb(0x60, 2); /* Turn on CapsLock LED (doesn't works)*/
char c = 0;
while (c != 1)
{
    if (inb(0x60) != c)
    {
        c = inb(0x60);
        if (c > 0)
            putch(scan2char(c));
    }
}

scan2char函数:

char scan2char(char scn)
{
    char keych;
    switch (scn)
    {
        case 0x15:
            keych = 'q';
            break;
        case 0x1D:
            keych = 'w';
            break;
        case 0x24:
            keych = 'e';
            break;
        case 0x2D:
            keych = 'r';
            break;
        case 0x2C:
            keych = 't';
            break;
        case 0x35:
            keych = 'y';
            break;
    }
    return keych;
}

它读取按键,但键盘布局以一种奇怪的方式移动; e.x:如果我按9我得到q,如果我按0我得到w,你懂的。 起初我以为可能是putch函数,但做了一些测试,我发现putch不是问题。

涉及 2 个或更多独立的硬件:

  • PS/2 控制器(主要是一个美化的串口控制器)
  • 任何恰好插入第一个 PS/2 端口的东西(键盘、鼠标、触摸屏、条形码扫描仪……)
  • 随便插入第二个PS/2端口

当涉及单独的硬件时,最好有单独的驱动程序:

  • 处理PS/2控制器的东西;包括处理 "hot-insert device"、设备识别和为识别的设备启动适当的驱动程序;并包括提供“get_byte()/send_byte()”接口供其他驱动程序使用。

  • 可能插入的每种设备的驱动程序(键盘、鼠标、触摸屏、条形码扫描仪……);它不接触任何 PS/2 控制器的 IO 端口,只与 PS/2 控制器驱动程序通信(通过 get_byte()/send_byte()" 接口提供 PS/2控制器驱动).

请注意(一般来说,不包括 "hard-wired device" 笔记本电脑的情况)绝对没有理由不能插入两个 PS/2 键盘(有 2 个完全相同的独立实例"PS/2 keyboard driver" 运行);或两个 PS/2 鼠标,或一个条形码扫描仪和一个触摸屏(没有键盘和鼠标),或任何 PS/2 端口中任何类型设备的任何其他组合。另外(如果你喜欢可移植性)没有理由为什么相同的 PS/2 keyboard/mouse/whatever 设备驱动程序不能工作 "as is" (重新编译,仅此而已)在完全不同的架构上完全不同 PS/2 控制器(例如某些 ARM 系统具有的 PL050 PS/2 控制器),仅仅是因为完全不同的 PS/2 控制器的驱动程序可以提供完全相同的“get_byte()/send_byte()”界面。

对于 80x86 PC 上的“8042”PS/2 控制器;您可能应该阅读(如果不遵循)此处描述的初始化序列:https://wiki.osdev.org/%228042%22_PS/2_Controller#Initialising_the_PS.2F2_Controller

如果你没有正确地初始化 PS/2 控制器(例如只使用 "random whatever state the thing happened to be left in by boot loader")那么它可能已经启用了一个糟糕的翻译功能,来自设备的数据被故意破坏用于向后兼容原始 IBM XT 机器的控制器(在扫描代码集 2 存在之前);现代键盘发送扫描码集 2 的字节,但 PS/2 控制器将它们转换为 "scan code set 1 compatible" 值,导致(例如)"if you press 9 you get q, if you press 0 you get w, ...".