進來忙得不得了,這時才體會出工作和在學校真的不同.有時候自己想做的事,很難如願.不過我這一段時間沒有太偷懶.對於Linux 的386 保護模式,內存管理,作了一個初步的學習.當初學習操作系統課時老覺得理論沒用. 如今,真的時間了,才知道理論知識是多麼的缺乏.也許是書到用時方恨少
閒話少說
目前,linux 被移植到了各種機器上.如apple 等.但我個人認為linux的真正魅力.還是在i386機器上.因為llinus前輩在寫linux 時的初衷,就是在386 平台上實現類unix的os
linux使用了intel 80386系列處理器的”保護模式”.操作系統的資源的管理和分配.由80386硬件存儲管理和保護機制實現
虛擬存儲器,是一種擴種內存的設計方案.他來源於當初主存非常昂貴的年代.用到了程序的局部性原則,即程序在運行時沒有必要全部裝入內存.支部當前要運行的那一部分調入內存即可
實際上,整個存儲系統是 由 高速緩存--- 內存--- 硬盤 等多級存儲介質構成的,但這對程序原始透明的,比如我們在程序中執行這樣一天指令
mov bx ,1997mov ax ,[bx]
這樣地址是1997 的內容背拷貝到了ax ,這樣由程序產生的地址時虛地址.這個地址與實際的物理地址是不同的.要有這個地址轉換到實際的物理地址,就需要有一個轉換機制.通常叫做MMU的硬件單元完成這個任務
所謂的保護機制就是在這個基礎上進行的.它的目的是要使不同的程序段互不干涉.系統進程與用戶進程嚴格分開已達到系統安全與多用戶多進程的要求.在linux 中通過給不同的任務分配不同的虛擬地址到物理地址的映射.來實現不同任務的切換與保護.同時.linux “可能”是把系統進程與用戶進程分開(我不太確定,可能是把系統進程的地址控制在100000以內?,當然在iipv通行中的共享內存,由於操作不當可能產生不可預料的後果).
另外,linux對統一任務也進行了不同程度的保護.它使用優先級來決定的.比如內核的優先級是0,系統調用 :1 庫:2 用戶進程3.在程序對某一個數據段進行讀寫的時候,.應縣檢查優先級,.在決定它運行的優先級或存取權限.
我想,這個優先級一定會和strUCt_task 的某些表示調度優先級的參數關聯.
對於內存管理,通常是有段式,頁式和段頁式三種方式.在這裡討論的使者兩種方式的虛擬-物理轉換機制的不同.因為linux實行的是段頁式內存管理.因此這兩種映射機制,也就必須都存在
段式管理,使用了一系列的可改變大小的地址集合進行管理.它的好處是,可以充分利用物理內存.缺點是難以管理,
通常在c 中 我們可以這樣定義一個段(此定義只是解釋段的概念,linux中絕不是如此)
typedef stucrt duan
{
struct duan * next ,*pre ;/*所所需指針*/
int tag;
iint begin ,end /*始末點*/
int size;
data data ; /*內容*/
……..
}
以上實在是實際內存中可能用到的段的數據結構.而我們在保護模式中,所謂的段是保護管理.大體上和匯編語言中基址尋址有些相似:他是實現虛擬-物理地址轉換的基礎(說白了,我個人認為,把所有的段定義成一樣大就是頁,不過實際上我還沒看linux 是怎樣做的,所以千萬不要被我誤導)
段 有一個基址 (base address)規定了在線性物理內存中的開始地址
有一個限制位,(limit) 表示段內最大偏移量,(也就是大小)
段的屬性 (attribute) 表示該段是否會被讀寫
這3 個屬性,包含在段的描述符中
所謂的描述符.是一個8個子節的存儲單元,其結構大概如下:
字節0 -----0—7 位描述苻
字節1 ------8—15位描述符
字節2 -----0—7 位基址
字節3 -----8—15 位基址
字節4 -----16—24 段基址
字節5 -----存儲權限的字節
字節6 -----G D00 16-19位段界限
字節7 -----31-—24 段基址
其中第五個字節,是存取權字節,它包含有好幾個標志位,用來標志該段是在內存中,還是沒有.後者該段是用戶段或者是系統段之類的.被人水平有限.在此不一一說明.希望有興趣的朋友可以查一下資料,將給我們大家聽
在系統段中.有一個字節.可以來定義系統段的類型,好像是有16類 像標志為有效的386.TSS,386中斷門,386陷阱門等等,在此不一一介紹.在此要弄清楚兩個名次 TSS(系統狀態標) LDT(局部描述標),在相關的資料中,經常會碰到
在LINUX的內核中有一系列的描述苻表.像全局描述苻表(GDT),中斷描述苻表(IDT)還有上面介紹的LDT等等,在他們中間.定義了系統可用的描述苻,中斷門,等等.它的作用是使得機器的兼容性得到保證
在LDT 中.則定義了一些和具體的任務相聯系的代碼段,數據段等等.描述苻表的內數據結構大致如下:
typedef struct desc_struct
{
unsigned long a,b;
}
後面用以下兩行完成了描述苻表的定義以及外部描述苻的定義:
desc_table[256]; //定義了可以在局部描述苻表中的最大描述苻量
extern dessc_table idt,gdt //外部的描述變量
至此,關於linux的分段機制大體上節講解完畢了,剩下的就是在寄存器與選擇器之間的映射,還有一些尋址方法
這部分內容,大概和<<匯編語言>>中講的大同小異,在此不多費唇舌