衛(wèi)一芃,李運喜
(中航工業(yè)西安計算技術(shù)研究所 陜西 西安 710068)
隨著微電子、容錯、軟件技術(shù)的發(fā)展,航空電子系統(tǒng)已逐步從原有的體系結(jié)構(gòu)向綜合化模塊化航空電子系統(tǒng)(IMA)發(fā)展,以提高未來飛機(jī)的作戰(zhàn)能力[1]。上世紀(jì)末,美國就已經(jīng)開始研制新一代飛機(jī),并制定了滿足新一代飛機(jī)綜合化要求的技術(shù)標(biāo)準(zhǔn)ARINC。其中,ARINC 653是美國航電委員會針對數(shù)據(jù)綜合化的要求提出的應(yīng)用程序接口標(biāo)準(zhǔn)[2-3]。新一代飛機(jī)的航電系統(tǒng)將是高度模塊化、綜合化的,其操作系統(tǒng)需采用專用的航電實時操作系統(tǒng),在滿足綜合化要求以及保證實時性的前提下,對安全性要求非常高。在高安全性的實時操作系統(tǒng)中支持兩種運行形態(tài):系統(tǒng)態(tài)和用戶態(tài)。用戶態(tài)的程序在運行過程中可能需要使用系統(tǒng)態(tài)的功能,由于跨兩態(tài),用戶態(tài)的應(yīng)用不能直接調(diào)用系統(tǒng)態(tài)下的服務(wù),因此需要使用系統(tǒng)調(diào)用機(jī)制為用戶態(tài)的應(yīng)用訪問系統(tǒng)態(tài)的服務(wù)提供解決途徑。
筆者詳細(xì)討論了某嵌入式實時操作系統(tǒng)中系統(tǒng)調(diào)用的機(jī)制以及實現(xiàn)方法。
某嵌入式實時操作系統(tǒng)是滿足ARINC 653標(biāo)準(zhǔn)要求的嵌入式實時操作系統(tǒng),其軟件結(jié)構(gòu)如圖1所示。
圖1 某嵌入式實時操作系統(tǒng)軟件結(jié)構(gòu)圖Fig.1 Software structure diagram of an embedded real-time operating system
ARINC 653為保證IMA系統(tǒng)中運行的多個航電應(yīng)用程序執(zhí)行時不相互影響,提出分區(qū)的概念。分區(qū)是IMA系統(tǒng)中的一組功能相關(guān)的應(yīng)用軟件,這些軟件在配置和執(zhí)行時作為一個單一的軟件來對待[4]。相當(dāng)于通用操作系統(tǒng)中的進(jìn)程,包含自己的存儲器,上下文以及配置屬性。分區(qū)OS運行在用戶態(tài),提供分區(qū)管理、分區(qū)間及分區(qū)內(nèi)通信、時間管理、進(jìn)程管理等功能。核心OS運行系統(tǒng)態(tài),提供任務(wù)管理、任務(wù)間通信、信號管理、系統(tǒng)調(diào)用管理等功能。位于用戶態(tài)下的程序不能直接訪問系統(tǒng)態(tài)下的服務(wù),系統(tǒng)調(diào)用機(jī)制為應(yīng)用分區(qū)訪問核心OS的服務(wù)提供解決途徑,有效保護(hù)核心OS的安全[5-6]。
內(nèi)核提供應(yīng)用的服務(wù)需統(tǒng)一編號,使用表方式統(tǒng)一管理。當(dāng)用戶態(tài)的應(yīng)用需要調(diào)用內(nèi)核提供的服務(wù)時,首先要執(zhí)行一組特殊的指令使系統(tǒng)進(jìn)入系統(tǒng)態(tài),通過系統(tǒng)調(diào)用號查表得到函數(shù)的入口地址,執(zhí)行內(nèi)核服務(wù),當(dāng)調(diào)用完成后,內(nèi)核將執(zhí)行另一組特征指令將系統(tǒng)返回到用戶態(tài)。這里將從系統(tǒng)調(diào)用號、系統(tǒng)調(diào)用表、系統(tǒng)調(diào)用生成及工作過程4個方面描述系統(tǒng)調(diào)用機(jī)制。
核心OS為每個系統(tǒng)調(diào)用定義一個唯一的編號,編號的定義方式如下:
#define__NR_函數(shù)名 X
其中,X代表系統(tǒng)調(diào)用號,系統(tǒng)調(diào)用號定義的部分代碼如下:
#define__NR_SysCallInit 1
#define__NR_RegisterDynamicLibrary 2
#define__NR_fstat 18
#define__NR_creat 19
#define__NR_hmEventDispatch 20
通過這個獨一無二的編號可以關(guān)聯(lián)到一個特定的系統(tǒng)調(diào)用。當(dāng)用戶空間的進(jìn)程執(zhí)行一個系統(tǒng)調(diào)用的時候,這個系統(tǒng)調(diào)用號就被用來指定要執(zhí)行的系統(tǒng)調(diào)用,進(jìn)程不會提及系統(tǒng)調(diào)用的名稱。
系統(tǒng)調(diào)用號一旦分配且完成編譯,就不能有任何變更。
系統(tǒng)調(diào)用表(syscall_table)用于記錄各個系統(tǒng)調(diào)用處理函數(shù)的入口地址,以系統(tǒng)調(diào)用號為偏移量能夠很容易在該表中找到對應(yīng)處理函數(shù)地址,部分代碼如下:
.long SYM(syscall_entry) /*0*/
.long SYM(SysCallInit) /*1*/
.long SYM(fstat) /*18*/
.long SYM(creat) /*19*/
.long SYM(hmEventDispatch) /*20*/
核心OS內(nèi)的syscall.h文件中定義了所有核心OS提供給上層應(yīng)用的函數(shù)。通過編譯,系統(tǒng)生成系統(tǒng)調(diào)用號及系統(tǒng)調(diào)用表項,同時為每一個函數(shù)生成一個文件名為XXX_trap.c的文件,XXX代表函數(shù)名。該文件中記錄用_syscallN()封裝后的函數(shù)。
應(yīng)用程序本身無法直接執(zhí)行內(nèi)核代碼,而是通過引發(fā)一個異常來促使系統(tǒng)切換到系統(tǒng)態(tài)執(zhí)行系統(tǒng)調(diào)用處理程序_syscallN(),其中N表示參數(shù)個數(shù),在X86體系結(jié)構(gòu)上支持函數(shù)最多帶5個參數(shù),PPC體系結(jié)構(gòu)上支持函數(shù)最多帶7個參數(shù)。
在陷入核心OS時,_syscallN()將系統(tǒng)調(diào)用號傳給核心OS。在PPC體系結(jié)構(gòu)中,系統(tǒng)調(diào)用號通過通用寄存器傳入,系統(tǒng)調(diào)用處理程序一旦執(zhí)行,可以從通用寄存器中獲得數(shù)據(jù),以下為PPC體系結(jié)構(gòu)的_syscall2()代碼片段:
#define_syscall2(type,name,type1,arg1,type2,arg2)
type name(type1 arg1, type2 arg2)
{
unsigned long__sc_ret;
{
register unsigned long__sc_0__asm__ ("r0");
register unsigned long__sc_3__asm__ ("r3");
register unsigned long__sc_4__asm__ ("r4");
__sc_3= (unsigned long) (arg1);
__sc_4= (unsigned long) (arg2);
__sc_0=__NR_##name;
__asm____volatile__
("sc "
: "=&r" (__sc_3)
: "0" (__sc_3), "r" (__sc_0),
"r" (__sc_4)
: __syscall_clobbers);
__sc_ret=__sc_3;
}
__syscall_return (type);
}
由上述代碼片段可以看出,系統(tǒng)調(diào)用帶有2個參數(shù),分別通過寄存器r3和r4傳遞,系統(tǒng)調(diào)用號通過寄存器r0傳遞。
以打開文件函數(shù)creat()為例,通過編譯后將生成creat_trap.c文件,該文件中記錄通過系統(tǒng)調(diào)用處理程序封裝后的creat()函數(shù)。應(yīng)用程序調(diào)用creat()時,實際就是通過執(zhí)行用_syscall2()封裝后的函數(shù)從用戶態(tài)進(jìn)入系統(tǒng)態(tài),完成系統(tǒng)調(diào)用功能。creat_trap.c文件中代碼片段如下:
_syscall2(T_WORD,creat,T_CONST T_BYTE*,name,T_WORD,mode)
系統(tǒng)調(diào)用的工作步驟如下:
1)保存所有當(dāng)前上下文(即用戶態(tài)上下文);
2)應(yīng)用程序通過軟中斷方式通知核心OS需要執(zhí)行一個系統(tǒng)調(diào)用。X86體系結(jié)構(gòu)上的軟中斷由int 0x80指令產(chǎn)生,PPC體系結(jié)構(gòu)上的軟中斷由sc指令產(chǎn)生。
3)引起0x0c00中斷(系統(tǒng)調(diào)用中斷),進(jìn)行異常處理,進(jìn)入核心OS;
4)判斷系統(tǒng)調(diào)用號是否合法,如果為非法系統(tǒng)調(diào)用號,則退出;否則根據(jù)系統(tǒng)調(diào)用號在系統(tǒng)調(diào)用表syscall_table中查找函數(shù)的入口地址,并跳轉(zhuǎn)到該地址。
5)執(zhí)行完畢后返回。
圖2以creat()為例反映了系統(tǒng)調(diào)用的工作步驟。
圖2 系統(tǒng)調(diào)用工作步驟Fig.2 Work steps of system call
分區(qū)OS中的進(jìn)程通過系統(tǒng)調(diào)用產(chǎn)生阻塞性請求的時候,進(jìn)程因等待系統(tǒng)調(diào)用的返回而阻塞。當(dāng)分區(qū)OS中一個進(jìn)程阻塞的時候,將導(dǎo)致整個分區(qū)阻塞,影響應(yīng)用分區(qū)的正常執(zhí)行。為解決阻塞性系統(tǒng)調(diào)用帶來的問題,引入worker任務(wù)機(jī)制進(jìn)行處理。
當(dāng)應(yīng)用請求了阻塞性的服務(wù)時,核心OS中將會啟動相應(yīng)的系統(tǒng)任務(wù)來進(jìn)行應(yīng)用請求的操作,通過這樣的方法實現(xiàn)異步IO機(jī)制。這種為實現(xiàn)異步IO操作而創(chuàng)建的系統(tǒng)任務(wù)稱為worker任務(wù)。筆者將從worker任務(wù)創(chuàng)建、分派及清理3方面描述worker任務(wù)。
3.1.1 worker任務(wù)創(chuàng)建
每個分區(qū)可支持的worker任務(wù)數(shù)在配置數(shù)據(jù)中定義。在分區(qū)創(chuàng)建的過程中,將根據(jù)配置的worker任務(wù)數(shù)創(chuàng)建任務(wù),這些任務(wù)隸屬于對應(yīng)的應(yīng)用分區(qū)。所有創(chuàng)建的worker任務(wù)都處于worker任務(wù)空閑隊列中。
3.1.2 worker任務(wù)分派
分區(qū)OS根據(jù)調(diào)用的服務(wù)是否為阻塞服務(wù)決定是否分派worker任務(wù),分派worker任務(wù)前,首先從可用的worker任務(wù)隊列中取得一個worker任務(wù)并激活該任務(wù),將系統(tǒng)調(diào)用的方法交由worker任務(wù)處理,當(dāng)worker任務(wù)能夠獲得資源則直接處理,完成后發(fā)送系統(tǒng)調(diào)用完成的事件,否則worker任務(wù)將阻塞在等待的資源上,直到資源被釋放,方可啟動運行,并通知應(yīng)用分區(qū)。
3.1.3 worker任務(wù)清理
worker任務(wù)在處理阻塞性系統(tǒng)調(diào)用過程中,如果處于等待狀態(tài),那么在應(yīng)用分區(qū)設(shè)置為IDLE模式、應(yīng)用分區(qū)重啟動過程中,需要對未完成的系統(tǒng)調(diào)用進(jìn)行刷新操作,在對系統(tǒng)調(diào)用進(jìn)行清理的同時,還需要對阻塞的worker任務(wù)進(jìn)行清理,將阻塞在資源等待鏈上的worker任務(wù)摘除,并停止worker任務(wù)的執(zhí)行。
采用worker任務(wù)機(jī)制可以有效地解決應(yīng)用分區(qū)因阻塞性系統(tǒng)調(diào)用而無法繼續(xù)運行的問題。當(dāng)系統(tǒng)調(diào)用發(fā)生阻塞時,啟動worker任務(wù)去等待資源,而當(dāng)前系統(tǒng)調(diào)用返回特定的狀態(tài)給應(yīng)用分區(qū),應(yīng)用分區(qū)經(jīng)過狀態(tài)判斷,掛起分區(qū)內(nèi)相應(yīng)的應(yīng)用進(jìn)程,從而產(chǎn)生進(jìn)程切換,執(zhí)行其他應(yīng)用進(jìn)程,當(dāng)worker任務(wù)等待的資源得到滿足時,則解掛worker任務(wù)執(zhí)行,并通過發(fā)送信號通知應(yīng)用分區(qū)阻塞狀態(tài)的解除。worker任務(wù)機(jī)制示意圖如圖3所示。
圖3 worker任務(wù)處理機(jī)制示意圖Fig.3 Schematic diagram of worker task processing mechanism
筆者深入研究了嵌入式實時操作系統(tǒng)中系統(tǒng)調(diào)用原理、參考國內(nèi)外先進(jìn)嵌入式實時操作系統(tǒng)中系統(tǒng)調(diào)用的實現(xiàn)方法,設(shè)計并實現(xiàn)了一種有效的系統(tǒng)調(diào)用方法,解決阻塞性系統(tǒng)調(diào)用給分區(qū)正常運行帶來的影響,保證分區(qū)的正常運行。通過在某嵌入式實時操作系統(tǒng)中的實現(xiàn),文中涉及的設(shè)計和實現(xiàn)方法是安全的、可行的、有效的。在今后的工作中,將著重于更進(jìn)一步提高系統(tǒng)調(diào)用的訪問效率及安全性方面的研究。
[1]王樹紅.嵌入式系統(tǒng)的現(xiàn)狀及發(fā)展趨勢[J].太原大學(xué)學(xué)報,2007,8(2):121-122,139.WANG Shu-hong,The present situation and developing trend of embedded system[J]Journal of Taiyuan university,2007,8(2):121-122,139.
[2]王麗杰.嵌入式實時操作系統(tǒng)設(shè)計探討[J].軟件世界,2007(20):51-53.WANG Li-jie.Discussion of embedded real time operating system design[J].Software World,2007(20):51-53.
[3]徐曉光,葉宏.分區(qū)間通信在航空電子系統(tǒng)中的設(shè)計與實現(xiàn)[J].航空計算技術(shù),2005,35(1):45-47,58.XU Xiao-guang,YE Hong.The design and implementation of inter-partition communication in avionics systems[J].Aeronautical Computing Technique,2005,35(1):45-47,58.
[4]ARINC.Specification 653-1,avionics application software standard interface[S].2003.
[5]Rushby J.Partitioning in avionics architectures requirements mechanisms and assurance[R].NASA,2000.
[6]葛仁北.系統(tǒng)調(diào)用與操作系統(tǒng)安全[J].計算機(jī)工程與應(yīng)用,2002(19):97-99.GE Ren-bei.System call and computer operation system security [J].Computer Engineering and Applications,2002(19):97-99.