<?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>X86_64 on 大飞的博客</title>
    <link>https://www.dafei.me/tags/x86_64/</link>
    <description>Recent content in X86_64 on 大飞的博客</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Wed, 06 May 2026 03:00:00 +0000</lastBuildDate>
    <atom:link href="https://www.dafei.me/tags/x86_64/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>从零写OS（三）：进入 64 位，CPU 真正醒了</title>
      <link>https://www.dafei.me/posts/os-03-long-mode/</link>
      <pubDate>Wed, 06 May 2026 03:00:00 +0000</pubDate>
      <guid>https://www.dafei.me/posts/os-03-long-mode/</guid>
      <description>&lt;p&gt;上一章切到了保护模式，32 位，最多 4GB 内存。&lt;/p&gt;
&lt;p&gt;听起来挺多，但现代系统动不动就几十 GB 内存，4GB 根本不够用。所以还得再往前走一步：进入&lt;strong&gt;长模式&lt;/strong&gt;（Long Mode，x86_64 的 64 位工作模式，支持 128TB 虚拟地址空间）。&lt;/p&gt;
&lt;p&gt;现在跑在你电脑上的 Linux、macOS、Windows，全都在长模式里。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;长模式比保护模式多了什么&#34;&gt;长模式比保护模式多了什么&lt;/h2&gt;
&lt;p&gt;最直接的：寻址空间从 4GB 扩展到理论上的 16EB（16 × 10¹⁸ 字节），实际当前 CPU 支持 128TB，够用很久了。&lt;/p&gt;
&lt;p&gt;但更重要的变化是强制引入了&lt;strong&gt;分页&lt;/strong&gt;（Paging，把物理内存切成固定大小的页，通过页表做虚拟地址到物理地址的映射）。&lt;/p&gt;
&lt;p&gt;保护模式下分页是可选的，长模式下分页是必须开启的。没有页表，CPU 根本不让你进长模式。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;先建页表&#34;&gt;先建页表&lt;/h2&gt;
&lt;p&gt;切换之前，必须在内存里建好&lt;strong&gt;页表&lt;/strong&gt;（Page Table，记录虚拟地址到物理地址映射关系的数据结构）。&lt;/p&gt;
&lt;p&gt;x86_64 用四级页表，一个虚拟地址的翻译路径是：&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;虚拟地址 → PML4 → PDPT → PD → PT → 物理地址
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;每级都是一张表，每张表 512 项，每项 8 字节。&lt;/p&gt;
&lt;p&gt;启动阶段不需要映射所有内存，先映射前 2MB 就够了——把四张表放在物理地址 &lt;code&gt;0x1000&lt;/code&gt; 开始的位置，让虚拟地址和物理地址一一对应（&lt;strong&gt;恒等映射&lt;/strong&gt;，虚拟地址和物理地址相同，是启动阶段最简单的映射策略）。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;切换步骤&#34;&gt;切换步骤&lt;/h2&gt;
&lt;p&gt;在 32 位保护模式下，按顺序操作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;建好页表&lt;/strong&gt;，把 PML4 地址写入 &lt;code&gt;CR3&lt;/code&gt;（页表根寄存器）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开启 PAE&lt;/strong&gt;（Physical Address Extension，物理地址扩展，让 32 位系统支持超过 4GB 的物理地址，长模式必须开启）：&lt;code&gt;CR4.PAE=1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;设置 EFER.LME=1&lt;/strong&gt;（通过 &lt;strong&gt;MSR&lt;/strong&gt; 寄存器（Model Specific Register，CPU 内部的特殊寄存器，用 rdmsr/wrmsr 读写）开启长模式使能位）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开启分页&lt;/strong&gt;：&lt;code&gt;CR0.PG=1&lt;/code&gt;，CPU 正式进入长模式兼容态&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;far jump&lt;/strong&gt; 跳入 64 位代码段，彻底进入 64 位模式&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;顺序不能乱。尤其是第 3 步必须在开启分页之前，不然 CPU 会拒绝。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
