Linux-Kernel

為什麼 Linux 中數據和程式碼段完全重疊?

  • February 6, 2018

上下文:我正在閱讀使用 2.6.11 核心的“Understanding the Linux kernel, 3d ed”。

問題:據我了解,物理地址是通過翻譯線性地址得到的,線性地址是通過翻譯邏輯地址得到的。邏輯地址由一個段選擇器組成,它標識描述表中的一個段

Linux 全域描述表包括使用者程式碼和數據段等。但是兩個段的基地址都是0x0,它們的大小也是一樣的。所以它們完全重疊。據我了解,邏輯地址cs + offset與邏輯地址相同ds + offset,其中csds是分別保存程式碼段選擇器和數據段選擇器的 CPU 寄存器。我認為是這種情況,因為兩個段具有相同的基地址,該基地址隨著偏移量遞增以獲得線性地址。

如果是這種情況,並且它們都映射到相同的線性地址,它們不也映射到相同的物理地址嗎?如果是這樣,擁有單獨的csds寄存器有什麼用?

分段寄存器是 x86 處理器早期的遺留物,當時offset它還不足以處理處理器可以定址的所有記憶體。最初的8086有 20 位地址空間,但只能使用 16 位偏移量。您必須使用段寄存器來指定您想要的 1024KB 地址空間中的哪 64KB。段寄存器實際上是 20 位寄存器,其中最低 4 位被強制為 0。載入段寄存器設置寄存器的高 16 位。這允許segment + offset覆蓋整個 20 位地址空間。

段寄存器仍然存在,但 Linux 將它們設置為 0,因此它可以假裝它們不存在。現代 x86 處理器(即80386和更新版本)可以使用足夠大的偏移量來覆蓋其所有地址空間,從而使記憶體分段成為不再需要的複雜操作。閱讀x86 記憶體分段平面記憶體模型了解更多詳細資訊。

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