Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

x86 Linux 內核啟動:分頁機制啟用全過程解析

編輯:Linux 教學

Linux 內核啟動早期運行在實模式,隨後切換到保護模式並啟用分頁機制。本文基於 arch/i386/kernel/head.S 中的 startup_32 入口點,詳細解析頁表初始化、頁目錄構建、CR0/CR3 寄存器設置及從物理地址跳轉到虛擬地址的關鍵過程。

1. 頁表初步初始化(pg0、pg1)

內核在 0x102000(pg0)和 0x103000(pg1)構建兩個頁表,映射物理內存前 8MB(2048 頁):

movl $pg0-__PAGE_OFFSET, %edi   // pg0 物理地址
movl $0x007, %eax               // PRESENT | RW | USER
2: stosl
addl $0x1000, %eax              // 下一個物理頁
cmpl $empty_zero_page-__PAGE_OFFSET, %edi
jne 2b
  • 每個頁表項屬性為 0x007(用戶態、可寫、存在)
  • 映射物理頁框 0、1、2... 對應虛擬地址 0、4KB、8MB...
  • 緊接著是 empty_zero_page(零頁),存放啟動參數

2. 頁目錄構建:swapper_pg_dir

.org 0x1000
ENTRY(swapper_pg_dir)
.long 0x00102007   // 第 0 項 → pg0
.long 0x00103007   // 第 1 項 → pg1
.fill 766, 4, 0    // 第 2-767 項:用戶空間 3GB,暫不映射
.long 0x00102007   // 第 768 項 → pg0(內核空間映射)
.long 0x00103007   // 第 769 項 → pg1
.fill 254, 4, 0    // 第 770-1023 項:內核空間剩餘 1GB

映射佈局:

  • 用戶空間(0-3GB):僅前兩項映射 8MB
  • 內核空間(3-4GB):第 768、769 項同樣映射前 8MB
  • 實現「同一物理內存雙重映射」:用戶空間低 8MB = 內核空間低 8MB

3. 啟用分頁機制

movl $swapper_pg_dir-__PAGE_OFFSET, %eax
movl %eax, %cr3              // 載入頁目錄物理地址
movl %cr0, %eax
orl $0x80000000, %eax        // 設置 PG 位(第 31 位)
movl %eax, %cr0              // 啟用分頁
jmp 1f                       // 刷新預取隊列
1: movl $1f, %eax
jmp *%eax                    // 絕對跳轉到虛擬地址

關鍵點解析

  1. CR3 載入頁目錄物理地址:此時分頁未啟用,地址仍為物理地址
  2. CR0 PG 位置 1:瞬間開啟分頁機制
  3. 雙重跳轉技巧:
    • 第一個 jmp 1f 是短跳轉,僅刷新流水線,EIP 仍是物理地址
    • 第二個 movl $1f, %eax; jmp *%eax 將虛擬地址載入 EIP,完成進入內核虛擬空間
  4. 為什麼映射用戶空間低 8MB?:啟用分頁瞬間 CPU 仍在低物理地址執行,若無用戶空間映射,取指將觸發頁錯誤導致崩潰

總結

Linux 通過精心設計的臨時頁表(swapper_pg_dir),實現了從實模式物理地址執行到保護模式虛擬地址執行的平滑過渡。這 8MB 的身份映射是啟動早期內核安全運行的基石,後續 start_kernel 會根據實際內存大小重建完整頁表。

Copyright © Windows教程網 All Rights Reserved