段表和页表【转】
轉自:http://www.cnblogs.com/worldisimple/articles/2447577.html
一、概述處理器(CPU)
1.1?處理器位數
在intel處理器的X86系列中,包含8086和8088的16位處理器,以及從80386(即i386)開始的32位處理器,而如今又有X86-64架構的64位處理器。
那這些16位,32位和64位又有什么意義了?位數越高,處理器的尋址能力越強,則可以支持越大的物理內存。具體如下表(可見對于64位處理器的尋址范圍已經是非常之大):
| 處理器位數 | 可支持的物理內存大小 | 尋址范圍 |
| 16 | 2^16?= 64K | 0x0000?~ 0xffff |
| 32 | 2^32?= 4G | 0x00000000?~ 0xffffffff |
| 64 | 2^64 | ? |
在平時安裝操作系統時候,經常會問是要裝32位系統還是64位系統?對于32位處理器,只能安裝32位的系統,不能安裝64位系統。對于64位處理,既能夠安裝32位的系統,也可以安裝64位的系統。在Linux下可以通過下面的方面查詢系統裝的是幾位的:
(1)?查看根目錄下是否有有lib64目錄。32位系統只有/lib一個目錄,64位的系統會有/lib64和/lib兩個目錄。
(2)?執行getconf?LONG_BIT命令查看返回結果。32位的系統中long類型是4字節(32位),64位的系統中long類型已變成了8字節(64位)。
(3)?執行uname?-i命令。32位的系統返回i386,64位的系統放回x86_64。
(4)?執行file /bin/ls命令。
32位系統返回如下結果:
/bin/ls: ELF?32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5,dynamically linked (uses shared?libs), stripped
64位系統返回如下結果:
/bin/ls: ELF?64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9,dynamically linked (uses shared?libs), for GNU/Linux?2.6.9, stripped
1.2?處理器的寄存器
寄存器是處理器的組成部分,是有限存貯容量的高速存貯部件,它們可用來暫存指令、數據和位址。寄存器的訪問速度在所有存儲階層(見下圖)是最快的。
在大學學習匯編時候,還用寄存器來寫匯編程序,現在也忘記差不多了,這邊就大致記錄一下處理器分別有哪些寄存器。
在8086中,所有的寄存器都是16位的。
在80386中,寄存器的發生的變化如下:
(1)?把16位的通用寄存器、指令指針寄存器以及標志寄存器擴充為32位的寄存器。
(2)?段寄存器仍然為16位,并增加2個16位的段寄存器。
| 寄存器的分類 | 32位CPU寄存器 | 16位CPU寄存器 | 主要用途 | |
| 通 用 寄 存 器 | 數據 寄存器 | EAX | AX | 乘、除運算,字的輸入輸出,中間結果的緩存 |
| EBX | BX | 存儲器指針 | ||
| ECX | CX | 串操作、循環控制的計數器 | ||
| EDX | DX | 字的乘、除運算,間接的輸入輸出 | ||
| 變址 寄存器 | ESI | SI | 存儲器指針、串指令中的源操作數指針 | |
| EDI | DI | 存儲器指針、串指令中的目的操作數指針 | ||
| 變址 寄存器 | EBP | BP | 存儲器指針、存取堆棧的指針 | |
| ESP | SP | 堆棧的棧頂指針 | ||
| 指令指針寄存器 | EIP | IP | 存放下一條將要執行指令的偏移量,偏移量加上當前代碼段的基地址,就形成了下一條指令的地址。 | |
| 標志位寄存器 | EFLAG | FLAG | ? | |
| 段寄存器 | CS | CS | 代碼段寄存器 | |
| DS | DS | 數據段寄存器 | ||
| SS | SS | 堆棧段寄存器 | ||
| ES | ES | 附加數據段寄存器 | ||
| FS | - | 32位CPU新增加的附加數據段寄存器 | ||
| GS | - | 32位CPU新增加的附加數據段寄存器 | ||
(3)?增加4個32位的控制寄存器(CR0、CR1、CR2?和CR3),在進程管理及虛擬內存管理中會涉及到CR0(其中有2位分別用于指示運行在實模式/保護模式和是否開啟分頁機制)、CR2以及CR3(是頁目錄基址寄存器,保存頁目錄表的物理地址)這幾個寄存器。
(4)?增加4個系統地址寄存器,具體如下:
全局描述符表寄存器GDTR(Global?Descriptor Table Register),是48位寄存器,用來保存全局描述符表(GDT)的32位基地址和16位GDT的界限。
中斷描述符表寄存器IDTR(Interrupt?Descriptor Table Register),是48位寄存器,用來保存中斷描述符表(IDT)的32位基地址和16位IDT的界限。
局部描述符表寄存器LDTR(Global?Descriptor Table Register),是16位寄存器,保存局部描述符表LDT段的選擇符。
任務狀態寄存器TR(Task State?Register)是16位寄存器,用于保存任務狀態段TSS段的16位選擇符。
(5)?增加8個32位調式寄存器DR0~DR7。
(6)?增加2個32位測試寄存器TR6和TR7。
?
二、內存管理
?
下面的內容主要依賴于80386的32位處理器的保護模式下。
2.1?內存地址
物理內存單元的實際地址即物理地址。32位的處理器尋址范圍為0x00000000?~ 0xffffffff,支持4G的物理內存大小。
程序產生的段選擇符與段相關的偏移地址部分構成了邏輯地址。在實模式下,沒有分段或分頁機制,邏輯地址和物理地址是相等的,不需要地址轉換可以直接訪問物理內存。但是在保護模式下,邏輯地址需要轉換成物理地址,才能訪問物理內存。那么,這個時候需要處理器中的內存管理單元(MMU)將邏輯地址映射為物理地址,來進行地址轉換(如下圖)。
那么,MMU是怎么將邏輯地址轉換成物理地址?
MMU是一種硬件電路,它包含兩個部件,一個是分段部件,一個是分頁部件,通過分段機制(把一個邏輯地址轉換為線性地址,線性地址也是32位,其地址取值范圍為0x00000000~0xffffffff)和分頁機制(把一個線性地址轉換為物理地址),最終將邏輯地址映射為物理地址。如下圖:
2.2?分段機制
在操作系統原理關于分段的說明:段的分配時為了更好的滿足用戶,段的長度不固定,由用戶定義,每個段都有自己的地址空間(通過基址包含某物理內存的地址,和長度值來表示段的長度),表示一個地址需要給出段部分(選擇符)和偏移部分。如下圖,如果沒有分頁的話,那么圖中的線性地址也就是物理地址,這種方式對于段的離散分配就很容易導致碎片問題(進而使用分頁機制來提高內存利用率):
在Linux中,主要設置了:內核代碼段,內核數據段,用戶代碼段,用戶數據段。而且每個段的基地址對應線性地址都是為0,而且都可以使用4G的地址空間,相當與繞過了邏輯地址和線性地址的映射,從而完全利用了分頁機制。另外,分段中怎樣使用段寄存器可以參考:http://book.51cto.com/art/200812/103305.htm
2.3?分頁機制
通過使用分頁機制可以很好的提高內存利用率。分頁機制把一個線性地址轉換為物理地址。Linux下一個頁大小為4K,把線性地址(32位)和物理地址(32位,2^32=4G物理內存)都按照4K(2^12)頁大小來進行劃分,那么,一共有4G/4K=1M的頁面,如果只是簡單的進行線性地址和物理地址一對一記錄映射的話,這樣在映射表建立的就會占用比較大的物理內存。這個時候就引入了頁表和頁目錄表,地址轉換過程見下圖:
(1)?通過對32位線性地址劃分:第31~22這10位(2^10=1024)定位頁目錄項,第21~12這10位定位頁表項,第11~0這12位(2^12=4K)為頁內偏移值。
(2)?對于頁目錄表,有1024個頁目錄項,每個頁目錄項(又含有1024個頁表項)指向下一級頁表的物理地址(32位=4個字節),那么一共需要1024*4(=4K)字節,即只要分配一頁就可以完全存放。
(3)?對于頁表,原理和頁目錄表一樣,那么一共需要1024(1024個頁目錄項)*1024(每個頁目錄項含有1024個頁表項)*4(=1M)字節。
(4)?對于頁目錄的物理地址,就存放在CR3寄存器中。
所以,這樣可以尋址1024*1024*4K=4G的物理內存。另外,在Linux的X86架構引入了3級頁表機制(包括了頁全局目錄、頁中間目錄和頁表)。
【參考】
1、深入分析Linux內核源碼
2、OReilly.Understanding.the.Linux.Kernel.3rd.Edition
3、PPT:?http://www.docin.com/p-54896290.html
4、http://www.ibm.com/developerworks/cn/linux/l-memmod/
-----------------------------------------------------------------
zzfrom:?http://chenxu.yo2.cn/articles/linux_memory.html
總結
- 上一篇: Cisco路由器配置命令之模式转换命令
- 下一篇: Flume NG 简介及配置实战