Memory

x86 Linux 中的物理地址 0 包含什麼?

  • October 8, 2018

我不確定這個問題應該放在這裡還是在reverseengineering.stackexchange.com

引用維基百科

在 8086 處理器中,中斷表稱為 IVT(中斷向量表)。IVT 始終駐留在記憶體中的同一位置,範圍從 0x0000 到 0x03ff,由 256 個四字節實模式遠指針(256 × 4 = 1024 字節記憶體)組成。

這是我在 qemu 監視器中發現的:

(qemu) xp/128xw 0
0000000000000000: 0xf000ff53 0xf000ff53 0xf000e2c3 0xf000ff53
0000000000000010: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000020: 0xf000fea5 0xf000e987 0xf000d62c 0xf000d62c
0000000000000030: 0xf000d62c 0xf000d62c 0xf000ef57 0xf000d62c
0000000000000040: 0xc0005526 0xf000f84d 0xf000f841 0xf000e3fe
0000000000000050: 0xf000e739 0xf000f859 0xf000e82e 0xf000efd2
0000000000000060: 0xf000d648 0xf000e6f2 0xf000fe6e 0xf000ff53
0000000000000070: 0xf000ff53 0xf000ff53 0xf0006aa4 0xc0008930
0000000000000080: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000090: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000c0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000d0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000e0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000100: 0xf000ec59 0xf000ff53 0xf000ff53 0xc0006730
0000000000000110: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000120: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000130: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000140: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000150: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000160: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000170: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000180: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000000190: 0x00000000 0x00000000 0x00000000 0xf000ff53
00000000000001a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001c0: 0xf000d611 0xf000ec4e 0xf000ec4e 0xf000ec4e
00000000000001d0: 0xf000d61a 0xf000d623 0xf000d608 0xf000ec4e
00000000000001e0: 0xf000ff53 0x00000000 0xf000ff53 0xf000ff53
00000000000001f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53

我不確定如何理解這些價值觀。它看起來不像一個中斷描述符表(取消引用這些值會給出所有空值)。那麼我到底在看什麼?

無論您的韌體包含什麼。

在理想的現代系統上,處理器根本不會進入實模式,正如我在這篇題為“現代 64 位英特爾晶片 PC 以何種模式執行引導扇區? ”的 SU 問答中所解釋的那樣?,物理記憶體的第一個 KiB 與 Johan Myréen 在這裡的另一個答案中所說的一樣無關緊要。但是許多現代韌體(仍然)具有兼容性支持,這意味著

  • 他們可以從保護模式退回(是的,退回,因為他們直接從虛幻模式轉到保護模式)從保護模式退回到實模式,以便執行為實模式編寫的系統軟體,例如舊式 PC/AT 引導程序MBR 和 VBR;和
  • 它們提供了舊的實模式韌體 API,並為這些 API 設置了上述系統軟體所依賴的所有資料結構。

這些資料結構之一是實模式 IVT。舊的實模式韌體 API 基於int指令,實模式 IVT 由韌體填充,作為其初始化的一部分,並帶有指向這些指令的各種韌體處理常式的指針。

保護模式系統軟體不需要舊的實模式韌體API,並且從不以實模式執行處理器,因此物理記憶體的前1KiB中的實模式IVT未被使用。(記住,v8086 保護模式不定址物理地址 00000000 及以上。它定址邏輯地址 00000000 及以上,由頁表轉換。)在現代 EFI 系統中,韌體將物理記憶體的記憶體映射移交給作業系統引導程序,告訴它哪些部分保留給韌體用於其自身的保護模式 API 目的,以及作業系統可以自由繼續使用哪些部分並用於其物理記憶體池。理論上,物理記憶體的第一頁可以屬於後一類。

在實踐中,首先,韌體通常將物理記憶體的第一頁標記為“引導服務程式碼”,這意味著作業系統可以聲明它並繼續將其用作其物理記憶體池的一部分,但僅在引導之後- EFI 韌體的時間服務已被作業系統關閉,韌體減少為僅提供其執行時服務。add_efi_memmap在Finnbarr P. Murphy 顯示的 Linux 核心日誌(帶有選項)中可以看到一個範例:

[0.000000] efi:mem00:類型=3,attr=0xf,範圍=[0x0000000000000000-0x0000000000001000)(0MB)

xe 用另一個程序以更易於閱讀的形式解碼為:

[#00] 類型:EfiBootServicesCode Attr:0xF
物理:0000000000000000-0000000000001000
虛擬:0000000000000000-0000000000001000

其次,在實踐中,Linux 明確忽略了這個物理記憶體範圍,即使韌體說它可以繼續使用它。您會發現,在 EFI 和非 EFI 韌體上,一旦 Linux 擁有物理記憶體映射,它就會對其進行修補(在名為 的函式中trim_bios_range),從而產生核心日誌消息,例如:

[ 0.000000] e820: 更新 [mem 0x00000000-0x00000fff] 可用 ==> 保留

這不是為了應對現代 EFI 韌體,實模式 IVT 不是韌體 API 的一部分,而是為了應對舊的 PC98 韌體,它是韌體 API 的一部分,但韌體會報告它(通過相同的 API)作為物理記憶體,可以被作業系統輕鬆覆蓋。

因此,雖然從理論上講,物理記憶體範圍可以包含任意程式碼或數據,具體取決於核心記憶體分配器和按需分頁虛擬記憶體的瞬時需求;實際上,Linux 只是保持不變,因為韌體最初設置它。

在您的系統上,韌體已經用實模式 IVT 條目填充它。當然,實模式 IVT 條目只是 16:16 遠指針,如果您使用 2 字節 hexdump 查看記憶體,您實際上可以非常清楚地看到這一點。一些例子:

  • 大多數 IVT 條目指向 F000:FF53,這是實模式韌體 ROM 區域中的地址。這可能是一個虛擬的常式,只不過是一個iret.
  • IVT 條目 1E指向 F000:6AA4,這是同一 ROM 區域中的一個表。
  • IVT 條目 1F指向 C000:8930,實模式影片 ROM 韌體區域中的一個表。
  • IVT 條目 43指向 C000:6730,實模式影片 ROM 韌體區域中的另一個表。

進一步閱讀

引用自:https://unix.stackexchange.com/questions/461689