接上文:
http://www.cnblogs.com/SuperXJ/archive/2010/12/02/1894639.htmlxiongjian
2010.12.22 msn:[email protected]
10 下面開始程序,首先引入幾個基本原則:
1)程序表A用來儲存程序A的資訊和程序A切換時,儲存目前A運作時寄存器資訊。定義為: PROCESSproc_table[1024]; 表示系統最多可以有1024個程序,PROCESS裡面就儲存了本程序運作時的各個寄存器資訊(這樣可以在程序切換回來的時候傳回寄存器資訊),該程序對應的LDT描述符(一般指向代碼段和資料段),最後還有一個指向GDT中該程序位置的描述符。
實作一個最簡單的程序切換系統,需要下面3個子子產品:
時鐘中斷處理程式/程序排程子產品/至少1個主程序和2個子程序
一個程序(ring1)的最小需要的元素為程序執行體,堆棧大小和位置。另外需要GDT中有一個選擇符指向一個該程序的LDT。在時鐘中斷發生時,時鐘中斷處理函數(ring0)将esp指向将要運作的程序在程序表中的位置。
當做到這裡,系統應該可以定時觸發時間中斷處理函數,時間中斷處理函數會輪流的調用程序A和B了。(這也是個ring0到ring1直接互相切換的過程)
到此為止,作業系統的啟動可以高于段落。
其他需要注意的是:系統調用
系統調用的簡單實作就是程序(ring1)将參數例如:num,儲存在寄存器中,然後自己産生一個中斷,例如int 100h.表示軟體發生100H号中斷(假設中斷處理函數為sys_call)。
I/O system(注意以下都是微核心形态)
IO首先第一個想到的就是鍵盤,其實鍵盤驅動非常簡單,隻要注意以下幾個方面即可:
1 建立鍵盤中斷處理函數
2 打開8259a的鍵盤中斷
3 解析中斷發生時的資料以确定使用者按下的具體按鍵
4 鍵盤有一個緩沖區,用于儲存使用者按鍵資訊,驅動需要及時的吧這個緩沖區的資料讀取出來,如果不是一個完整資料,需要做臨時緩存。
系統有一個固定的顯存記憶體位置,顯示的最基本原理就是N個位元組裡面儲存字元和顔色資訊,最常見的是的565色。Linux的多終端機制的一般規則為多個終端對應一個螢幕,使用者在使用一個螢幕的時候,可以随時切換到其他螢幕而好像是切換了使用者一樣。實作這樣機制的一個程序叫做TTY程序,他作為第一個微核心以為的系統程序而存在,已差別于一般的使用者程序。下面就來看看他的大概實作思路:
Tty_task()
{
Init_keyboard();
For(循環3次) init_tty(i);
While(1)
{
//依次周遊每一個tty
For(I= 0; i<3 ; i++)
{
Tty_read(i);//如果目前活躍的tty是我,則從鍵盤驅動中讀取鍵盤緩存
In_process(i,key); //将讀出的緩存存放到目前tty的緩存中,另外處理alt+Fn的切換控制台指令(即Fn)
Tty_write(i);
}
}
}
微核心有MM和FS,分别為記憶體管理程序和檔案系統程序,下面看看一個微核心是如何實作程序建立的。
² 1 使用者調用fork函數
² 2 fork調用sys_call(MM, FORK); //表示消息要發給MM程序,消息内容為FORK,内部通過send_recv實作,即先發送在接收消息
² 3 send_recv内部使用int觸發IDT中的一個中斷,假設中斷處理函數為s_call(ring0)
² 4 s_call内部會将消息從寄存器中取出,并向MM程序發送消息(msg_send() ).
² 5 msg_send(sender, dest, msg) //發送者/接收者/要發送的消息體 ××發送消息××
{
檢查發送者和接收者不能相等
檢查是否會發生死鎖,例如A->B->A 即A和B在同時互相發送消息,AB程序都會堵死在發送程式處。
If(接收者是處理RECEIVE狀态)
線上性位址(實體位址)層面将要發送的消息複制到接收者的緩存中(虛拟位址-)線性位址)。因為發送者的消息是存放在實體位址裡面的,是以必須要找到消息的實體位置才能将消息複制到接收者程序。
}
Else 發送者處于SEND狀态,并等待一直到接收者處于RECEIVE為止,通過調用程序排程程序實作。
}
² 6 通過msg_send的調用,在實體位址層面,消息就被複制到了接收程序中(消息可以保持在接收程序的程序表項中)。下面看看接受程序:接收程序調用msg_recv來阻塞的接收消息
msg_recv(接收者,發送者,接收消息的指針m)
{
If(接收者有來自硬體的消息)
If(接收者隊列裡有消息) 将接收到的消息複制到m裡。
Else (沒有消息) 阻塞
}
² 7 到目前為止,程序可以實作發送和接收消息了。實作的根本原理還是通過實體位址的消息複制。 現在的程序有了以下狀态:發送(消息)狀态,接收(消息)狀态,運作狀态,休眠狀态。 其中 發送/接收/休眠狀态都不會獲得CPU運作機會。
,同時MM程序會不停的查詢,如果有消息,則調用do_fork真正建立程序。
從這一系列流程可以看出,微核心僅僅給上層發送和接收消息2個接口,而不關心具體實作。具體的實作是他們通過參數傳給具體的ring1程序(例如FS,MM……)來實作。
以上就是微核心的思想,同時也是一個簡單同步IPC思想。
未完待續(檔案系統+記憶體管理)