<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Ring Buffer on 大飞的博客</title>
    <link>https://www.dafei.me/tags/ring-buffer/</link>
    <description>Recent content in Ring Buffer on 大飞的博客</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Thu, 14 May 2026 05:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.dafei.me/tags/ring-buffer/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>从零写OS（二十五）：TTY 终端输入</title>
      <link>https://www.dafei.me/posts/os-25-tty/</link>
      <pubDate>Thu, 14 May 2026 05:00:00 +0000</pubDate>
      <guid>https://www.dafei.me/posts/os-25-tty/</guid>
      <description>&lt;p&gt;到目前为止，进程只能输出，没有办法接收用户输入。&lt;code&gt;SYS_READ&lt;/code&gt; 形同虚设，键盘按了也没反应。&lt;/p&gt;
&lt;p&gt;这一章实现 &lt;strong&gt;TTY&lt;/strong&gt;——Unix 对终端设备的最初抽象，让进程能以行为单位从串口读取输入。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;tty-是什么&#34;&gt;TTY 是什么&lt;/h2&gt;
&lt;p&gt;TTY 原本是 teletypewriter（电传打字机）的缩写。在 Unix 里，它泛指&amp;quot;终端&amp;quot;——一个字符设备，既能接收键盘输入，又能输出文字。&lt;/p&gt;
&lt;p&gt;现代 Linux 里的 &lt;code&gt;/dev/tty&lt;/code&gt;、&lt;code&gt;/dev/pts/0&lt;/code&gt; 都是 TTY 的后代。我们这里用串口 COM1 模拟一个最简单的 TTY。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;整体架构&#34;&gt;整体架构&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;用户键盘输入
   ↓ 串口硬件触发 IRQ4
isr_handler → tty_recv(c)   ← 回显 + 写入 ring buffer
                ↓ 遇到 &amp;#39;\n&amp;#39;
           line_ready = 1
                ↓ 进程 syscall SYS_READ(fd=0)
           tty_read(buf, len)  ← 把一行搬到用户 buf
                ↓
           用户程序处理输入
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;三个关键组件：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Ring Buffer&lt;/strong&gt;：固定大小的环形缓冲区，存放还未被读走的字符&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;行规程（line discipline）&lt;/strong&gt;：积累字符，遇 &lt;code&gt;\n&lt;/code&gt; 才通知&amp;quot;行就绪&amp;quot;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IRQ4 中断处理&lt;/strong&gt;：从串口读一个字节，交给 TTY&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&#34;ring-buffer&#34;&gt;Ring Buffer&lt;/h2&gt;
&lt;p&gt;环形缓冲区是一个固定数组，加上读指针和写指针：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[ _ _ _ _ h e l l o \n _ _ ]
           ↑                 ↑
         rx_read          rx_write
rx_len = 6
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;写字符：&lt;code&gt;rx_buf[rx_write] = c; rx_write = (rx_write + 1) % TTY_BUF_SIZE; rx_len++&lt;/code&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
