<?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>Arch_prctl on 大飞的博客</title>
    <link>https://www.dafei.me/tags/arch_prctl/</link>
    <description>Recent content in Arch_prctl on 大飞的博客</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Fri, 22 May 2026 02:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.dafei.me/tags/arch_prctl/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>从零写OS（三十一）：运行 musl libc 程序 —— 两个隐藏的寄存器 Bug</title>
      <link>https://www.dafei.me/posts/os-31-musl-libc/</link>
      <pubDate>Fri, 22 May 2026 02:00:00 +0000</pubDate>
      <guid>https://www.dafei.me/posts/os-31-musl-libc/</guid>
      <description>&lt;p&gt;上一章对齐了 Linux syscall ABI，现在试着跑一个真正用 musl libc 静态编译的 C 程序。目标很简单：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#include&lt;/span&gt; &lt;span style=&#34;color:#75715e&#34;&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;main&lt;/span&gt;(&lt;span style=&#34;color:#66d9ef&#34;&gt;int&lt;/span&gt; argc, &lt;span style=&#34;color:#66d9ef&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;**&lt;/span&gt;argv) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;printf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;hello from musl libc!&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#a6e22e&#34;&gt;printf&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;argc=%d&lt;/span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;&lt;/span&gt;, argc);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;编译：&lt;code&gt;musl-gcc -static -O2 -o hello.elf hello.c&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;结果踩了两个隐藏很深的寄存器 bug，花了不少时间才找出来。&lt;/p&gt;
&lt;h2 id=&#34;新增的-syscall&#34;&gt;新增的 syscall&lt;/h2&gt;
&lt;p&gt;musl libc 启动时会调用一批 syscall，其中有三个是绕不过的：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;syscall&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;arch_prctl(ARCH_SET_FS, addr)&lt;/td&gt;
          &lt;td&gt;158&lt;/td&gt;
          &lt;td&gt;设置 TLS base（FS 寄存器）&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;set_tid_address(tidptr)&lt;/td&gt;
          &lt;td&gt;218&lt;/td&gt;
          &lt;td&gt;设置线程 ID 地址，返回 pid&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;writev(fd, iov, iovcnt)&lt;/td&gt;
          &lt;td&gt;20&lt;/td&gt;
          &lt;td&gt;向量写，musl 的 stdio 用它输出&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;code&gt;arch_prctl&lt;/code&gt; 需要写 MSR &lt;code&gt;0xC0000100&lt;/code&gt;（FS.base），这是 TLS 的基地址，musl 用来存放线程局部变量：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;case&lt;/span&gt; SYS_ARCH_PRCTL:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;if&lt;/span&gt; (a1 &lt;span style=&#34;color:#f92672&#34;&gt;==&lt;/span&gt; ARCH_SET_FS) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#a6e22e&#34;&gt;wrmsr&lt;/span&gt;(&lt;span style=&#34;color:#ae81ff&#34;&gt;0xC0000100&lt;/span&gt;, a2);   &lt;span style=&#34;color:#75715e&#34;&gt;// FS.base MSR
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#66d9ef&#34;&gt;return&lt;/span&gt; (&lt;span style=&#34;color:#66d9ef&#34;&gt;uint64_t&lt;/span&gt;)(&lt;span style=&#34;color:#f92672&#34;&gt;-&lt;/span&gt;EINVAL);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;writev&lt;/code&gt; 需要遍历 iov 数组，把多段数据拼起来写到 tty：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
