2.1 內存編址
我們通過 memory address 來得到內存的內容,對於8086處理器,需要區分三種地址:
1. 邏輯地址:每個邏輯地址包含一個 段 和一個 偏移
2. 線性地址:又稱虛地址:一個32位的無符號整數,4G
3. 物理地址:
內存管理單元,Memory Management Unit - MMU,通過一個被稱爲段單元的硬件電路,將邏輯地址轉換爲線性地址,頁單元 將線性地址轉換爲物理地址。(可參考操作系統書籍,內存管理部分)
Memory arbiter 被插在 bus 和每個 RAM芯片之間,用於同步,當芯片忙時讓請求等待。
2.2 段機制-硬件
Intel的處理器,分爲實模式和保護模式。Real mode exists mostly to maintain processor compatibility with older models and to allow the operating system to bootstrap
2.2.1 段選擇器和段寄存器
一個邏輯地址包含一個 segment identifier 和一個 偏移,segment identifier是一個16位的段選擇器
爲了更方便地得到段選擇器,處理器指定來一些段寄存器來保存它。
cs, ss, ds, es, fs, gs
cs
: 代碼段 code segment, 包含了2-bit的CPL,current privilege level當前優先級等級,0代表最高級,內核態kernel mode,3代表最低,用戶態
ss
: stack segment
ds
: data segment
2.2.2 段描述符
每個段都用一個8-bit的段描述符,它被保存在 GDT 全局描述符表,LDT local
The address and size of the GDT in main memory are contained in the gdtr control register, while the address and size of the currently used LDT are contained in the ldtr control register
2.2.3 Fast Access to Segment Descriptors
2.2.4 Segmentation Unit
根據段選擇器段 TI
來判斷哪個 描述符表 存儲了 段描述符,根據段選擇器 的 index
計算出段描述符的地址,(乘8 再加上 gdtr
or ldtr
),段描述符的 base
加上邏輯地址的 offset
得到線性地址。
2.3 Segmentation in Linux
linux的段機制
segmentation can assign a different linear address space to each process, while paging can map the same linear address space into different physical address spaces.
所有的用戶態的進程,使用相同的段來尋址,內核態一樣
All Linux processes running in User Mode use the same pair of segments to address instructions and data. These segments are called user code segment and user data segment , respectively. Similarly, all Linux processes running in Kernel Mode use the same pair of segments to address instructions and data: they are called kernel code segment and kernel data segment , respectively. Table 2-3 shows the values of the Segment Descriptor fields for these four crucial segments.
對應的段選擇器定義爲 __USER_CS, __USER_DS, __KERNEL_CS, __KERNEL_DS
,例如爲來得到 kernel code segment,只需要取出 __KERNEL_CS
的值到 cs
段寄存器中。