在保护模式下读取键盘
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, ...".
我正在尝试做一个 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, ...".