### 內存地址:
邏輯地址:包含在機器語言指令中用來指定一個操作數或一條指令的地址。
線性地址:一個32位無符號整數,也稱虛擬地址。
物理地址:用于內存芯片級內存單元尋址,與從微處理器的地址引腳發送到內存總線上的電信號相對應。
在多處理器系統中,所有CPU都共享同一內存,這意味著,RAM芯片可以由獨立的CPU并發地訪問。由于RAM芯片上的讀或寫操作必須串行地執行,
因此一種所謂內存仲裁器的硬件電路插在總線和每個RAM芯片之間,其作用是如果某一個RAM芯片空閑,就準予一個CPU訪問,如果該芯片忙于為
另一個處理器提出的請求服務,就延遲這個CPU的訪問。
即使在單處理器上也使用內存仲裁器。因為單處理器系統中包含一個叫做DMA控制器的特殊處理器,而且DMA控制器與CPU并發操作。
### 硬件中的分段:
一個邏輯地址由一個16位段標識符(或稱為段選擇符,如下)和一個32位段內偏移組成。
段選擇符包含13位的索引號、1位TI表指示器以及2位RPL請求者特權級。
每個段由一個8字節的段描述符表示,段描述符存放在全局描述符表(GDT)或者局部描述符表(LDT)中。通常只定義一個GDT,而每個進程都擁
有自己的LDT。
GDT的第一項總是設為0,這就確保空段選擇符的邏輯地址會被認為是無效的,并能引起一個處理器異常。由此,GDT中最大段描述符數目為213-1。
例:如果GDT在0x0020000(這個值保存在gdtr寄存器中),且由段選擇符所指定的索引號為2(即段選擇符高13位的值為2),則由于GDT第一項為0,
由該段選擇符所指定的段描述符地址是0x0020000+2*8或者0x0020010。
邏輯地址轉換成相應線性地址:分段單元先檢查段選擇符的TI字段,決定段描述符的保存位置(GDT或者LDT),若為GDT,分段單元從gdtr寄存器
中得到GDT的線性基址,若為激活的LDT,則分段單元從ldtr寄存器中得到LDT的線性基址;然后,從段選擇符的index字段計劃段描述符的地址,把
這個地址與邏輯地址中的偏移量字段值相加,得到線性地址。
### Linux中的分段:
分段可以給每一個進程分配不同的線性地址空間,而分頁則可以把同一線性地址空間映射到不同的物理空間。與分段相比,Linux更喜歡使用分頁方式,
因為:當所有進程使用相同的段寄存器值時,內存管理變得更加簡單;Linux設計目標之一是可移植到大多數處理器平臺上,而RISC體系結構對分段的
支持很有限。
Linux主要使用了四個段:用戶代碼段、用戶數據段、內核代碼段、內核數據段。相應的段選擇符由宏__USER_CS、__USER_DS、__KERNEL_CS、
__KERNEL_DS定義,內核只需把相應宏產生的值裝入cs段寄存器即可對相應的段尋址。
當對指向指令或者數據結構的指針進行保存時,內核不需為其設置邏輯地址的段選則符,因為cs寄存器就含有當前的段選擇符。
例:當內核調用一個函數時,它執行一條call匯編語言指令,該指令僅指定其邏輯地址的偏移量部分,而段選擇符不用設置,因為“在內核態執行”
的段只有內核代碼段,由__KERNEL_CS定義。
在單處理器系統中只有一個GDT,而多處理器系統中每個CPU對應一個GDT。
Linux中每一個GDT包含18個段描述符,指向下列段:
* 用戶態和內核態下的代碼段和數據段共4個;
* 任務狀態段,每個處理器有1個;
* 1個包含缺省局部描述符表的段,這個段通常被所有進程共享;
* 3個局部線程存儲(TLS)段;
* 3個與高級電池管理相關的段;
* 5個與支持即插即用功能的BIOS服務程序相關的段;
* 1個被內核用來處理“雙重錯誤”異常的特殊TSS段;
注:處理一個異常時可能會引發另一個異常,這咱情況下產生雙重錯誤。
大多數用戶態下的Linux程序不使用LDT,這樣內核就定義了一個缺省的LDT供大多數進程共享。