diff --git a/asm.vp b/asm.vp index dd47a24..798fcb7 100644 --- a/asm.vp +++ b/asm.vp @@ -52,8 +52,18 @@ def outl(port: uint16, value: uint32): op = [ASM_DESCR.CLOBBER_RDX, ASM_DESCR.CLOBBER_RAX]) def io_wait(): - __asm__(f"mov dx, 0x80; out dx, al", - op = [ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_DX]) + # ATA 规范的 I/O 延时:**连续 4 次读备选状态寄存器 0x3F6**。它是真实设备端口,每次 in + # 都是一次真实 I/O 往返,稳定给出 ≥400ns(规范要求命令块寄存器两次写之间至少 400ns)。 + # 原先写的是诊断端口 0x80 —— 该端口背后没有设备,在 QEMU 上几乎不消耗时间,等于**没有 + # 延时**:IDE 命令块寄存器(0x1F2..0x1F7)连写会丢写 ⇒ LBA 寄存器残留上一次的值 ⇒ 读到 + # **别的扇区**的数据。现场(参见 0ee5ec5 与 serial.log):读根目录扇区 8192 却读回 ELF + # 文件头 ⇒ 目录项全是垃圾 ⇒ app spawn 失败;或 waitDataReady 超时 ⇒ diskio.read 报错。 + __asm__(f"""mov dx, 0x3F6 + in al, dx + in al, dx + in al, dx + in al, dx""", + op = [ASM_DESCR.CLOBBER_MEMORY, ASM_DESCR.CLOBBER_DX, ASM_DESCR.CLOBBER_RAX]) inline def pushall():