羅 斌
【摘要】文章介紹了一個基于PC體系結構的嵌入式操作系統(tǒng),從CPU的16位實模式切換到32位保護模式,包括中斷控制器、系統(tǒng)時鐘等在內的系統(tǒng)硬件初始化過程,全局描述符表、中斷描述符表等內核運行環(huán)境的建立,進程的定義以及調度算法,進程切換方面介紹了一個具備基本功能的嵌入式操作系統(tǒng)。
【關鍵詞】PC;嵌入式操作系統(tǒng);CPU保護模式
當前,嵌入式操作系統(tǒng)已經獲得非常廣泛的應用,涉及的領域包括通信、軍事、航空航天、以及生活等方方面面。目前市場上比較有名且占有一定市場分額的操作系統(tǒng)有VxWork、uLinux、uC/OS-II、eCos等,他們有各自的優(yōu)點,VxWork經過了長時間的發(fā)展和實際應用的考驗,在關鍵應用領域仍是一支獨秀。uLinux則可以利用廣泛的Linux資源,便于開發(fā)等等。
由于操作系統(tǒng)的基本功能是硬件無關的,因此這部分可以使用C語言進行開發(fā),而平臺相關的部分只需要使用匯編語言,但是只要設計好代碼框架,就可以做到方便移植。選擇了PC作為最初的目標平臺,是因為x86體系結構應用范圍越來越廣,而且可以在開發(fā)x86版本后再移植到其他平臺。
一、操作系統(tǒng)簡介
操作系統(tǒng)在功能上主要是負責管理計算機的資源,這些資源包括CPU、內存、外部存儲器、還有一些其他的外設。
從結構上則分為單一內核和微內核結構,單一內核的代表就是UNIX、Linux,這類操作系統(tǒng)的內核是一個整體,功能都包含在內核里面,有點“大雜燴”的味道,其優(yōu)點就是由于功能都包含在內核中,因此內核很緊湊,且效率較高。而且?guī)淼娜秉c就是當一個功能模塊需要修改時,就必須將內核全部編譯一次。微內核結構的代表就是windows系列,其內核提供的功能很少,僅有一些基本的功能,其他的功能全部作為擴展模塊連接進入核心,這樣的好處就是各個功能模塊在接口不變的時候,可以很方便的更新而不影響系統(tǒng),給系統(tǒng)提供了最大的靈活性。帶來的缺點是結構不夠緊湊,造成一定的資源浪費,同時也對運行效率產生一定影響。本系統(tǒng)采用的是單一內核結構。
操作系統(tǒng)的開發(fā)通常是在UNIX、Linux下使用GNU Compiler Collection(GCC)進行開發(fā)編譯。一般認為不能在Windows下開發(fā),并且認為微軟提供的開發(fā)工具不能進行此類開發(fā)。但是本操作系統(tǒng)是在Windows下開發(fā)使用Microsoft Visual C/C++ 6(VC6)進行開發(fā)。
二、CPU保護模式初始化
PC在通電后運行于16位實模式,其尋址能力為64K,而嵌入式系統(tǒng)的配置范圍非常廣泛,僅僅考慮16位的尋址范圍顯然不適合當前的發(fā)展要求。而i386及其以上的CPU的尋址能力都達到了4G,因此需要設計能支持4G內存的操作系統(tǒng)。
在系統(tǒng)引導時,首先建立一個臨時的全局描述符表(GDT),這個全局描述符表中有5個描述符,第一個必須設為0,這是x86處理器規(guī)定的,稱為啞描述符。其中兩個是16位保護模式代碼段和數(shù)據(jù)段的描述符,用于在切換CPU運行模式的時候,保證初始化代碼仍然能夠正常運行。另外兩個是32位保護模式下的代碼段和數(shù)據(jù)的描述符,用于CPU內核運行。
由于CPU在復位時是處于16位實模式,所以初始化代碼是16位實模式下的代碼,這部分的代碼的作用是為切換到16位保護模式準備運行環(huán)境,主要的工作是設置GDT。具體地做法是根據(jù)當前的段寄存器計算GDT中相應段描述符的值。
再設置好GDT后,就可以將CPU切換到保護模式下運行。將CPU切換到保護模式的方法是,將cr0寄存器的0位設置為1,代碼為:
……
mov eax,cr0
or eax,1
mov cr0,eax
……
再切換到保護模式運行后,由于CPU有指令預取機制,所以在指令隊列中已經存在了下一跳指令,而且需要刷新代碼段寄存器,為了防止運行出錯,必須刷新指令隊列已近代碼段寄存器。由于需要在一條指令中同時刷新段寄存器和指令隊列,所有需要手動構造一條段間轉移指令。代碼為:
……
db0eah
dwoffset init
dwtemp_code_sel
init:
……
完成后CPU即進入16位保護模式運行。
三、建立內核運行環(huán)境
進入內核后,首先必須建立運行環(huán)境,對于INTEL的CPU來說,就是建立兩個系統(tǒng)表,一個是全局描述符表(GDT),一個是中斷描述符表(IDT)。
(一)全局描述符表初始化
在CPU由16位實模式切換到32位保護模式的時候,建立了一個臨時的GDT。但是進入內核后,需要一個真正的描述符表,不能在繼續(xù)使用這個臨時的GDT,否則在以后的任務切換中將會遇到麻煩。
由于假設系統(tǒng)運行在單一地址空間,因此全局描述符表僅需要3個描述符,可以使用數(shù)組定義如下:
DESC gdt[4] = { {0,0,0,0,0,0},
{0xffff,0x0000,0x00,0x9a,0xcf,0x00}, // 代碼段
{0xffff,0x0000,0x00,0x92,0xcf,0x00} // 數(shù)據(jù)段
};
定義了新的全局表述附表后,就可以將GDT更換為新的描述符表,并且將段寄存器CS的值更換為新的段選擇子的值。
(二)中斷描述符表初始化
運行環(huán)境的另一個重要的系統(tǒng)表就是中斷描述符表,他決定了由哪個程序來響應系統(tǒng)的中斷或者陷阱。在保護模式初始化時,并沒有對IDT進行初始化,甚至沒有定義中斷描述符表,那是因為在進行保護模式切換時,可以保證系統(tǒng)運行于關中段狀態(tài),保證初始化本身也不使用任何的軟中斷指令,這樣就可以在沒有對IDT初始化的情況下,確保不會發(fā)生因中斷描述符表沒有設置而導致的錯誤。
由于INETL的CPU可以響應256個中斷,因此系統(tǒng)IDT最大有256個描述符,但是實際系統(tǒng)中并不需要那么多,所以可以根據(jù)需要進行設置,在本系統(tǒng)中,為了節(jié)約空間,僅定義了64個。
定義后并將其初始化,使用一個默認過程來初始化,這個默認的過程什么工作都不作,僅僅是簡單的返回。默認過程定義如下:
__declspec( naked )
void default_int()
{
__asm iretd ;
}
這里使用了__declspec( naked )這個由VC6提供的特有關鍵字,它可以讓編譯器不生成函數(shù)的環(huán)境初始化代碼,所有的操作都交由程序員來完成。因此可以使用VC6來編寫中斷處理程序,這也是為什么選擇VC6來編寫這個操作系統(tǒng)的原因。
(三)系統(tǒng)基本硬件初始化
系統(tǒng)環(huán)境建立后,需要對硬件設備進行初始化,為了保證通用性,僅初始化大多數(shù)系統(tǒng)都會有的硬件,就是系統(tǒng)時鐘。
在PC系統(tǒng)中要初始化系統(tǒng)時鐘,必須首先初始化中斷控制器,因為系統(tǒng)時鐘是通過中斷控制器接入系統(tǒng)的。由于INTEL已經保留了CPU的0-31號中斷,因此中斷控制器的中斷只能從32號中斷開始。在本系統(tǒng)中,中斷控制器接入CPU的中斷號從32開始,到47,一共16個,另外保留16個中斷門作為系統(tǒng)調用的入口,為以后擴展功能留下一定的余地。
四、 進程定義及調度
(一)進程定義
任何操作系統(tǒng),最重要的概念就是進程,進程通常表示一個執(zhí)行的程序,它包括可執(zhí)行的程序、程序數(shù)據(jù)、棧、程序計數(shù)器等等程序運行需要的信息。在本系統(tǒng)中,由于并沒有涉及復雜的功能,所以進程結構的定義比較簡單。僅包含調度相關的信息和一些基本進程信息
struct _task
{
struct _node task_node;
char task_cputime;
BYTEtask_stat;
BYTEtask_pri;
BYTEtask_pril;
DWORD task_prinum;
int task_sleep;
void *task_sp;
char *task_name;
int task_id;
int task_pid;
unsigned int task_errcode;
};
(二)調度算法
本系統(tǒng)采用的調度算法是以優(yōu)先級為主,輔以時間片輪轉的調度算法。以優(yōu)先級為主的調度算法,可以保證高優(yōu)先級的進程可以搶占CPU,以保證實時任務得到及時響應,而輔以時間片輪轉,則可以保證優(yōu)先級相同時,各進程公平的獲得CPU時間。
系統(tǒng)調度過程是調度器根據(jù)優(yōu)先級從高到低的原則掃描系統(tǒng)進程表,在發(fā)現(xiàn)某個優(yōu)先級存在可調度進程的時候,就轉入掃描該優(yōu)先級的進程表,如果該優(yōu)先級中存在多個任務,就根據(jù)時間片輪轉的原則挑選出進程,然后將CPU的控制權交給挑選出來的進程。
五、結語
這僅僅是一個最簡單的操作系統(tǒng)內核,沒有提供任何額外的系統(tǒng)服務,包括一些類似系統(tǒng)延時、互斥對象、定時器這樣的基本功能,但是有了基本的內核后,就可以在其上發(fā)展,使其逐漸發(fā)展壯大。
【參考文獻】
[1]John Lions. Lion's Commentary on UNIX 6th Edition with Source Code [M].機械工業(yè)出版社,2000.
[2]Andrew S. Tanenbaum. Modern Operating Systems [M].機械工業(yè)出版社,1999.
[3]Jean J. Labrosse. MicroC/OS_II The Real-Time Kernel Sec-
ond Edition [M].北京航空航天大學出版社,2003.
[4]楊季文.80X86匯編語言程序設計教程[M].清華大學出版社,1998.
【作者簡介】羅斌(1978- ), 男 ,廣西馬山人,廣西電網(wǎng)公司南寧供電局助理工程師。