真實模式和保護模式

FreeeLinux發表於2017-03-14

保護模式的起源

最開始的程式定址是直接的“段:偏移”模式,這樣的好處是所見即所得,程式設計師指定的地址就是實體地址,實體地址對程式設計師是可見的。但是,由此也帶來兩個問題:

  1. 無法支援多工(程式設計師多個程式可能指定執行的實體地址一樣)
  2. 程式的安全性無法得到保證(使用者程式可以改寫系統空間或者其他使用者的程式內容)

真實模式將整個實體記憶體看成分段的區域,程式程式碼和使用者程式沒有區別對待,而且每一個指標都是指向“實在”的實體地址。這樣一來,使用者程式的一個指標如果指向了系統程式區域或其他使用者程式區域,並且改變了值,那麼對於這個被修改的系統程式或使用者程式,其後果很可能是災難性的。為了克服這種低劣的記憶體管理方式,處理器廠商開發出保護模式。這樣,實體記憶體地址不能直接被程式訪問,程式內部的地址(虛擬地址)要由作業系統轉化為實體地址去訪問,程式對此一無所知。

在保護模式下,全部32條地址線有效,可定址高達4G位元組的實體地址空間;擴充的儲存器分段管理機制和可選的儲存器分頁管理機制,不僅為儲存器共享和保護提供了硬體支援,而且為實現虛擬儲存器提供了硬體支援。支援多工,能夠快速地進行任務切換和保護任務環境。4個特權級和完善的特權檢查機制,既能實現資源共享又能保證程式碼和資料的安全和保密及任務的隔離;支援虛擬8086方式,便於執行8086程式。

**保護模式出現的原因是:保護程式地址空間。這樣,就產生了一個結果:兩種模式下程式的定址方式發生了變化。

從80386開始,cpu有三種工作方式:真實模式,保護模式和虛擬8086模式。只有在剛剛啟動的時候是真實模式,到linux作業系統執行起來以後就執行在保護模式。虛擬8086模式是執行在保護模式中的真實模式,為了在32位保護模式下執行純16位程式。它不是一個真正的CPU模式,還屬於保護模式。CPU啟動環境為16位真實模式,之後可以切換到保護模式。但從保護模式無法切換回真實模式。

保護模式和真實模式區別

2.1

1)真實模式的定址方式與工作原理

8086是16位的CPU,只能訪問地址在1M以下的記憶體成為常規記憶體,我們把地址在1M以上的記憶體成為擴充套件記憶體。真實模式有著16位的暫存器/16位資料匯流排/20位地址匯流排。一個地址有段和偏移兩部分組成,實體地址的計算公式為:

physicaladdress=segment16+offset
physical address = segment * 16 + offset

通過上述分段技術,能夠表示的最大記憶體為:

FFFFh : FFFFh
= FFFF0h(左移)+ FFFFh
= 10FFEFh
= 1M + 64K - 16Bytes

1M多餘出來的部分被稱作高階記憶體區HMA。但8086/8088只有20位地址線,只能夠訪問1M地址範圍的資料,所以如果訪問100000h~10FFEFh之間的記憶體(大於1M空間),必須有第21根地址線來參與定址(8086/8088沒有)。因此,當程式設計師給出超過1M(100000H-10FFEFH)的地址時,因為邏輯上正常,系統並不認為其訪問越界而產生異常,而是自動從0開始計算,也就是說系統計算實際地址的時候是按照對1M求模的方式進行的,這種技術成為wrap-around

對於80286或以上的CPU通過A20GATE來控制A20地址線。技術發展到了80286,雖然系統的地址匯流排由原來的20根發展為24根,這樣能夠訪問的記憶體可以達到2^24=16M,但是Intel在設計80286時提出的目標是向下相容,所以在真實模式下,系統所表現的行為應該和8086/8088所表現的完全一樣,也就是說,在真實模式下,80386以及後續系列應該和8086/8088完全相容仍然使用A20地址線。所以說80286晶片存在一個BUG:它開設A20地址線。如果程式設計師訪問100000H-10FFEFH之間的記憶體,系統將實際訪問這塊記憶體(沒有wrap-around技術),而不是像8086、8088一樣從0開始。我們來看一幅圖:

為了解決上述相容性問題,IBM使用鍵盤控制器上剩餘的一些輸出線來管理第21根地址線(從0開始數是第20根)的有效性,被稱為A20Gate;

  1. 如果A20Gate被開啟,則當程式設計師給出100000H-10FFEFH之間的地址的時候,系統將真正訪問這塊記憶體區域;
  2. 如果A20Gate被禁止,則當程式設計師給出100000H-10FFEF之間的地址的時候,系統仍然使用8086/8088的方式即取模方式(8086模擬)。絕大多數IBMPC相容機預設的A20Gate都是被禁止的。現在許多新型PC上存在直接通過BIOS功能呼叫來公職A20Gate的功能。
    上面的記憶體訪問模式都是真實模式,在80286以及更高系列的PC中,即使A20Gate被開啟,在真實模式下所能夠訪問的記憶體最大也只能為10FFEFH,儘管他們的地址匯流排所能夠訪問的能力都大大超過這個限制。

嗯,為了能夠訪問10FFEFH以上的記憶體,則必須進入保護模式

2)保護模式定址

從80386開始,進入32位CPU時代,有32位地址匯流排。但是,地址並沒有用暫存器直接指定,仍然採用“段+偏移”的模式。雖然段值仍由原來的16位cs/ds等暫存器指定,但此時這些暫存器中存放的不再是段基址,而是一個索引:從這個索引,可以找到一個表項,裡面存放了段基址等很多屬性,這個表項稱為段描述符,這個表就成為GDT。

2.2段大小

真實模式下面段的大小是固定的64k,而保護模式則不是固定的。關於段基址,真實模式下,第16位是0;保護模式下堅持4K對齊,就是說第12b是0。(??,沒搞懂這句話意思,應該是後12位為0)

2.3段地址的存放地點

真實模式下在cs/ds等暫存器中,保護模式在段描述符中,而要取得段描述符號,又需要取得cs等中的段選擇符。

2.4對段的保護機制

真實模式下沒有提供對段的保護,保護模式下面提供了對段的保護機制。

原文連結:真實模式與保護模式解惑之(一)——二者的起源與區別

相關文章