从零写OS(三十三):阻塞式 TTY —— read 不再忙等
上一章 busybox sh 成功显示了 / # 提示符,但 shell 拿不到任何输入——因为 tty_read 是忙轮询的,没有字符就直接返回 0,shell 以为收到 EOF,立刻退出。这一章实现真正的阻塞式 TTY,让 shell 能等待用户输入。 之前的问题 之前的 tty_read 大概是这样: int tty_read(char *buf, int len) { // 轮询串口状态寄存器 if (!(inb(0x3F8 + 5) & 1)) return 0; // 没数据就返回 0 *buf = inb(0x3F8); return 1; } 这有两个问题: 没有输入时返回 0,上层程序(shell)以为是 EOF 如果上层在循环里调这个,CPU 100% 占用 正确做法:没有输入时挂起进程,等串口中断来了再唤醒。 串口中断(IRQ4) COM1 对应 IRQ4,接在 PIC 主片的 IR4 引脚。要用串口中断,需要两步: 1. 在 PIC 上 unmask IRQ4: // PIC 主片 IMR 寄存器:0 表示开放,1 表示屏蔽 uint8_t mask = inb(0x21); mask &= ~(1 << 4); // 清除 bit4,开放 IRQ4 outb(0x21, mask); 2. 开启串口的接收中断: ...