From 89907682ec9527919cb3c702907384e916b8557e Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 16 Oct 2026 14:14:51 +0800 Subject: [PATCH] =?UTF-8?q?fix(keyboard):=20init()=20=E5=AF=B9=E9=BD=90=20?= =?UTF-8?q?mouse=20=E5=86=99=E6=B3=95=20-=20=E5=8E=BB=E6=8E=89=200xAD/0xAE?= =?UTF-8?q?=20=E9=94=AE=E7=9B=98=E6=8E=A5=E5=8F=A3=E7=A6=81=E7=94=A8?= =?UTF-8?q?=E5=BA=8F=E5=88=97(CCB=20=E5=9B=9E=E5=86=99=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E4=BC=9A=E5=81=9C=E5=9C=A8=E7=A6=81=E7=94=A8=E6=80=81)?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E8=A1=A5=20pic.clearMask(1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Kernel/drivers/input/keyboard/keyboard.vp | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp index 6cce3a0..69b3481 100644 --- a/VKernel/Kernel/drivers/input/keyboard/keyboard.vp +++ b/VKernel/Kernel/drivers/input/keyboard/keyboard.vp @@ -1,6 +1,7 @@ import asm import intr.idt as idt import drivers.serial.uart.serial as serial +import platform.pch.pic as pic import string import viperlib import t, c @@ -116,12 +117,12 @@ def has_data() -> int: def init(): global _kbd_inited # 幂等:init() 有两个调用点(devfs 注册 /dev/input/keyboard、kbd_svc.start), - # 重复执行会再次发 0xAD 禁用键盘接口,而那次 CCB 写入往往失败(键盘数据串入 - # CCB 读取,回读为 0)⇒ 0xAE 恢复不了 ⇒ 接口停在禁用态 ⇒ 按键不再产生任何字节 - # (现场:ki 恒为 2/3,desktop 轮询永远看不到键盘字节,键盘完全无法输入)。 + # 硬件初始化只允许做一次。 if _kbd_inited != 0: return _kbd_inited = 1 + + # 清空控制器输出缓冲(上电自检字节 / 上一次遗留的 ACK 等) drain: uint32 drain = 0 while (asm.inb(KBD_STATUS) & 0x01) != 0: @@ -129,15 +130,12 @@ def init(): drain += 1 if drain > 1000: break - _wait_write() - asm.outb(KBD_COMMAND, 0xAD) - - drain = 0 - while (asm.inb(KBD_STATUS) & 0x01) != 0: - asm.inb(KBD_DATA) - drain += 1 - if drain > 1000: break - + # 读-改-写 CCB(与 mouse.init 同款写法): + # bit0=1 使能键盘 IRQ1;bit6=1 启用 scancode set1 翻译;bit4=0 使能键盘时钟。 + # 这里**不再发 0xAD/0xAE**(禁用 / 启用键盘接口):QEMU 下 0xAD 之后那次 CCB 回写 + # 经常失败(键盘数据串入 CCB 读取、回读为 0),0xAE 便恢复不了 ⇒ 键盘接口停在 + # 禁用态 ⇒ 之后按键完全不产生任何字节/IRQ1(现场:ki 恒为 2/3、无任何键盘字节)。 + # 鼠标没有这个序列,所以它一直正常 —— 键盘对齐鼠标的写法即可。 _wait_write() asm.outb(KBD_COMMAND, 0x20) _wait_read() @@ -152,18 +150,12 @@ def init(): _wait_write() asm.outb(KBD_DATA, ccb) - _wait_write() - asm.outb(KBD_COMMAND, 0xAE) - - drain = 0 - while (asm.inb(KBD_STATUS) & 0x01) != 0: - asm.inb(KBD_DATA) - drain += 1 - if drain > 1000: break - + # 使能键盘扫描(0xF4),并读走 ACK _wait_write() asm.outb(KBD_DATA, 0xF4) _wait_read() asm.inb(KBD_DATA) + # 解屏蔽 IRQ1(对齐 mouse.init 的 pic.clearMask(12)),再装 handler + pic.clearMask(1) idt.irqInstallHandler(1, irq_handler, "keyboard")