<?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>Brk on 大飞的博客</title>
    <link>https://www.dafei.me/tags/brk/</link>
    <description>Recent content in Brk on 大飞的博客</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Fri, 22 May 2026 01:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.dafei.me/tags/brk/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>从零写OS（三十）：对齐 Linux syscall ABI，让 musl libc 能跑起来</title>
      <link>https://www.dafei.me/posts/os-30-syscall-abi/</link>
      <pubDate>Fri, 22 May 2026 01:00:00 +0000</pubDate>
      <guid>https://www.dafei.me/posts/os-30-syscall-abi/</guid>
      <description>&lt;p&gt;musl libc 编译出来的程序会直接用 &lt;code&gt;syscall&lt;/code&gt; 指令，传的是 Linux x86-64 标准调用号。我们之前的调用号是自己编的，如果不对齐，musl 程序一个 syscall 都跑不通。这一章把内核的 syscall 接口全面对齐 Linux ABI。&lt;/p&gt;
&lt;h2 id=&#34;linux-x86-64-syscall-约定&#34;&gt;Linux x86-64 syscall 约定&lt;/h2&gt;
&lt;p&gt;Linux 的 x86-64 syscall 约定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;调用：&lt;code&gt;rax&lt;/code&gt;=syscall号，&lt;code&gt;rdi&lt;/code&gt;=a1，&lt;code&gt;rsi&lt;/code&gt;=a2，&lt;code&gt;rdx&lt;/code&gt;=a3，&lt;code&gt;r10&lt;/code&gt;=a4，&lt;code&gt;r8&lt;/code&gt;=a5，&lt;code&gt;r9&lt;/code&gt;=a6&lt;/li&gt;
&lt;li&gt;返回：&lt;code&gt;rax&lt;/code&gt;（负数表示错误，如 &lt;code&gt;-ENOENT&lt;/code&gt; = -2）&lt;/li&gt;
&lt;li&gt;CPU 自动保存：&lt;code&gt;rcx&lt;/code&gt;=用户 rip，&lt;code&gt;r11&lt;/code&gt;=用户 rflags&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意第 4 个参数是 &lt;code&gt;r10&lt;/code&gt;，不是 &lt;code&gt;rcx&lt;/code&gt;。原因是 &lt;code&gt;syscall&lt;/code&gt; 指令会把用户 &lt;code&gt;rip&lt;/code&gt; 存进 &lt;code&gt;rcx&lt;/code&gt;，所以 &lt;code&gt;r10&lt;/code&gt; 顶替了 &lt;code&gt;rcx&lt;/code&gt; 的位置。这一点非常容易踩坑。&lt;/p&gt;
&lt;h2 id=&#34;关键改动&#34;&gt;关键改动&lt;/h2&gt;
&lt;h3 id=&#34;1-syscall-号全部换成-linux-标准&#34;&gt;1. syscall 号全部换成 Linux 标准&lt;/h3&gt;
&lt;p&gt;之前的调用号是自己定义的，现在全部换成 Linux 标准值：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;功能&lt;/th&gt;
          &lt;th&gt;之前&lt;/th&gt;
          &lt;th&gt;现在&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;read&lt;/td&gt;
          &lt;td&gt;6&lt;/td&gt;
          &lt;td&gt;0&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;write&lt;/td&gt;
          &lt;td&gt;1&lt;/td&gt;
          &lt;td&gt;1 ✓&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;open&lt;/td&gt;
          &lt;td&gt;5&lt;/td&gt;
          &lt;td&gt;2&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;close&lt;/td&gt;
          &lt;td&gt;7&lt;/td&gt;
          &lt;td&gt;3&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;fork&lt;/td&gt;
          &lt;td&gt;3&lt;/td&gt;
          &lt;td&gt;57&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;exit&lt;/td&gt;
          &lt;td&gt;2&lt;/td&gt;
          &lt;td&gt;60&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;kill&lt;/td&gt;
          &lt;td&gt;12&lt;/td&gt;
          &lt;td&gt;62&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;write 碰巧没变，其他大部分都不一样。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
