<?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>Kernel on 大飞的博客</title>
    <link>https://www.dafei.me/tags/kernel/</link>
    <description>Recent content in Kernel on 大飞的博客</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Wed, 03 Jun 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.dafei.me/tags/kernel/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>自制 x86-64 内核（46）：mmap 文件映射</title>
      <link>https://www.dafei.me/posts/os-46-mmap/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://www.dafei.me/posts/os-46-mmap/</guid>
      <description>&lt;p&gt;上一章实现了 TCP 服务端，这章来实现一个经典的内存管理功能：&lt;strong&gt;mmap 文件映射&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id=&#34;什么是-mmap-文件映射&#34;&gt;什么是 mmap 文件映射&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;mmap&lt;/code&gt; 把文件的一段内容映射到进程的虚拟地址空间。映射后可以像读内存一样读文件——不需要 &lt;code&gt;read()&lt;/code&gt; 系统调用，直接解引用指针。&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;int&lt;/span&gt; fd &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;open&lt;/span&gt;(&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;/bin/busybox&amp;#34;&lt;/span&gt;, O_RDONLY);
&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;char&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt;p &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;mmap&lt;/span&gt;(NULL, &lt;span style=&#34;color:#ae81ff&#34;&gt;4096&lt;/span&gt;, PROT_READ, MAP_PRIVATE, fd, &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 style=&#34;color:#75715e&#34;&gt;// p[0..3] 就是文件的前 4 字节（ELF magic: 7f 45 4c 46）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;关键设计vma-和-lazy-分配&#34;&gt;关键设计：VMA 和 Lazy 分配&lt;/h2&gt;
&lt;p&gt;mmap 不会立刻分配物理内存，而是&lt;strong&gt;登记一个 VMA（虚拟内存区域）&lt;/strong&gt;，等到进程真正访问这段地址时，才通过&lt;strong&gt;缺页异常&lt;/strong&gt;按需读取文件内容并建立页表映射。&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mmap(fd) → 注册 VMA（vaddr, len, inum, offset） → 返回虚拟地址
                        ↓ 进程访问该地址
              #PF not-present → 找到 VMA → 分配物理页
                              → ext2_read(inum, offset, page)
                              → 建立页表 → 重试指令
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这就是操作系统课上说的&amp;quot;按需分页&amp;quot;（demand paging）。&lt;/p&gt;
&lt;h2 id=&#34;实现步骤&#34;&gt;实现步骤&lt;/h2&gt;
&lt;h3 id=&#34;1-定义-vma-结构&#34;&gt;1. 定义 VMA 结构&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;process_t&lt;/code&gt; 中加入 VMA 数组：&lt;/p&gt;</description>
    </item>
    <item>
      <title>自制 x86-64 内核（47）：动态链接器基础</title>
      <link>https://www.dafei.me/posts/os-47-dynlink/</link>
      <pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate>
      <guid>https://www.dafei.me/posts/os-47-dynlink/</guid>
      <description>&lt;p&gt;这一章实现了对 PIE（Position-Independent Executable）程序的支持，也就是不加 &lt;code&gt;-static&lt;/code&gt; 编译出来的&amp;quot;动态&amp;quot;程序。&lt;/p&gt;
&lt;h2 id=&#34;问题pie-和静态-elf-的区别&#34;&gt;问题：PIE 和静态 ELF 的区别&lt;/h2&gt;
&lt;p&gt;用 musl-gcc 编译一个简单的 hello world：&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-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&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;musl-gcc -static -O2 -o hello hello.c
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# 动态（PIE）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;musl-gcc -O2 -o hello_pie hello.c
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;file&lt;/code&gt; 查看：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;hello:     ELF 64-bit LSB executable, x86-64, statically linked
hello_pie: ELF 64-bit LSB pie executable, x86-64, dynamically linked
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;区别在于：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;属性&lt;/th&gt;
          &lt;th&gt;静态 (ET_EXEC)&lt;/th&gt;
          &lt;th&gt;PIE (ET_DYN)&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;e_type&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;虚地址&lt;/td&gt;
          &lt;td&gt;固定（如 0x400000）&lt;/td&gt;
          &lt;td&gt;从 0 开始，需加载时指定 base&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;重定位&lt;/td&gt;
          &lt;td&gt;无&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;.rela.dyn&lt;/code&gt; 表&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;外部依赖&lt;/td&gt;
          &lt;td&gt;无&lt;/td&gt;
          &lt;td&gt;通常有（但 musl PIE 已内嵌 libc）&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;为什么-musl-pie-没有真正的动态链接&#34;&gt;为什么 musl PIE 没有&amp;quot;真正的&amp;quot;动态链接？&lt;/h2&gt;
&lt;p&gt;musl-gcc 默认把所有 libc 代码&lt;strong&gt;静态链接&lt;/strong&gt;进去，只是编译为 PIE 格式（支持 ASLR）。所以运行时：&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
