高安全性操作系統要求系統在任何環境下安全可靠地運行,需要系統設計工程師對系統資源進行有效配置和管理。本文中將從存儲器保護、訪問控制和資源可用性保障等幾個方面介紹高安全性操作系統的一些設計思想和方法。
高安全性系統的設計極為復雜,通過加強操作系統安全保護和資源保障可以減輕應用開發人員的設計負擔。無論設計遠程通信交換機還是醫療器械或航天器上的復雜系統,系統中關鍵部件必須能在任何條件下正常工作。實際上,在處理器速率穩步增長條件下,出于節省成本的考慮,設計工程師往往期望同一處理器能運行多個關鍵程度不同的應用系統,但是相應的風險也將增加。
例如,重病特別護理使用的血液氣體分析儀具有兩種截然不同的功能。首先分析儀需要實時監控病人血流中氧氣及其它氣體的含量。如果某種受監控氣體低于或高于某個危險值,分析儀應發出告警或采取某些更為直接的干涉措施。但該設備還具有另一項功能,即顯示氣體含量的變化曲線,以便于脫機分析。在這樣的系統中,數據記錄、數據顯示和用戶接口線程可通過處理器或其它資源的監控和告警線程來實現。
為了使同一系統中不同重要程度的線程“和平共處”,管理處理器和其它資源的操作系統必須能對軟件進行適當的分區,以保證資源的有效配置。操作系統必須在此刻加以保障,而不能依賴于設計之后或實現之后的測試。高安全性系統應當在任何時刻都是安全的。
在本文中,線程是程序的基本執行單位;進程是一個由地址空間組成的程序執行單元,通常包含一個或多個線程;內核是操作系統中提供核心系統服務(如調度、線程同步和進程間通信)的部分。
存儲器保護
初的容錯設計為存儲器保護。多年以來,微處理器一直帶有片上存儲器管理單元(MMU),MMU能使單個軟件線程工作于硬件保護地址空間。但是在許多商用實時操作系統中,即使系統中含有這些硬件也沒采用MMU。
當應用程序的所有線程共享同一存儲器空間時,任何一個線程將有意或無意地破壞其它線程的代碼、數據或堆棧。異常線程甚至可能破壞內核代碼或內部數據結構。例如線程中的指針錯誤就能輕易使整個系統崩潰,或至少導致系統工作異常。
就安全性和可靠性而言,基于進程的實時操作系統(RTOS)的性能更為優越。為生成具有單獨地址空間的進程,RTOS只需要生成一些基于RAM的數據結構并使MMU加強對這些數據結構的保護?;舅悸肥窃诿總€關聯轉換中“接入”一組新的邏輯地址。MMU利用當前映射,將在指令調用或數據讀寫過程中使用的邏輯地址映射為存儲器物理地址。MMU還標記對非法邏輯地址進行的訪問,這些非法邏輯地址并沒有映射到任何物理地址。
這些進程雖然增加了利用查詢表訪問存儲器所固有的系統開銷,但其實現的效益很高。在進程邊界處,疏忽或錯誤操作將不會出現,用戶接口線程中的缺陷并不會導致其它更關鍵線程的代碼或數據遭到破壞。目前在可靠性和安全性要求很高的復雜嵌入式系統中,仍然存在采無存儲器保護的操作系統的情況,這實在有些不可思議。
采用MMU還有利于選擇性地將頁面映射或解映射到邏輯地址空間。物理存儲器頁面映射至邏輯空間,以保持當前進程的代碼,其余頁面則用于數據映射。類似地,物理存儲器頁面通過映射可保持進程的線程堆棧。RTOS可以在每個線程堆棧解映射之后,很容易地保留邏輯地址所對應的頁面內容。這樣,如果任何線程分配的堆棧發生溢出,將產生硬件存儲器保護故障,內核將掛起該線程,而不使其破壞位于該地址空間中的其它重要存儲器區,如另一線程堆棧。這不僅在線程之間,還在同一地址空間之間增加了存儲器保護。
存儲器保護(包括這類堆棧溢出檢測)在應用程序開發中通常非常有效。采用了存儲器保護,程序錯誤將產生異常并能被立即檢測,它由源代碼進行跟蹤。如果沒有存儲器保護,程序錯誤將導致一些細微的難以跟蹤的故障。實際上,由于在扁平存儲器模型中,RAM通常位于物理地址的零頁面,因此甚至NULL指針引用的解除都無法檢測到。
系統調用
另一個問題是內核必須保護自己免受不適當的系統調用影響。許多內核將新創建的內核對象的實際指針以句柄(handle)形式返回至創建該對象的線程。當該指針在后續系統調用中傳回內核時,將直接解除引用。但是,如果線程使用該指針直接修改內核對象,或者用指向其它存儲器的指針簡單地覆蓋該句柄時,將可能帶來嚴重的后果。
錯誤的系統調用不應使整個內核崩潰,因此RTOS應對內核對象采用不透明句柄,并驗證所有系統調用的參數。
容錯和高可用性
即使的軟件也可能存在缺陷。隨著應用程序的日益復雜,以及在軟件支持不足條件下處理功能的增加,使得現場系統中的缺陷也不斷增多。因此,系統設計工程師必須考慮到這些潛在的故障并在應用系統中采用故障恢復技術。當然,故障恢復的效果取決于應用系統本身:故障發生后,用戶接口可重新啟動,而對于飛行控制系統則可能無法重啟。
進行故障恢復的一種方法是為每個地址空間設立一個管理線程。當出現線程故障(如堆棧溢出)時,內核應提供某些機制使故障信息傳送至管理線程。如有必要,管理線程通過系統調用關閉該故障線程或整個進程,然后重新啟動。管理線程還可掛靠在軟件“看門狗”設置中,由此檢測線程死鎖和空閑問題。
在許多關鍵系統中,往往利用系統中的多個冗余節點來保障高可用性。在這些系統中,工作于冗余節點上的內核必須能檢測出工作節點中的故障。一種方法是在RTOS各處理器之間的消息傳遞機制中添加內置“心跳信息”(見圖1)。一旦系統啟動,將打開冗余節點和每個工作節點之間的通信信道。正常工作條件下,冗余節點不斷收到工作節點的心跳信息。如果心跳信息無法抵達,冗余節點將自行控制。
強制訪問控制和自主訪問控制
Unix文件是自主訪問控制的一個范例:進程或線程可自行修改文件的權限,因而允許系統中的另一進程訪問該文件。自主訪問控制對于某些系統中的特定對象非常適用。
應用于高安全性系統的RTOS必須更進一步,對關鍵系統對象進行強制訪問控制。例如,在由飛行控制程序控制的飛機傳感器中,系統設計工程師必須能靜態地配置系統,以保證只有飛行控制程序才能操作該設備。系統中的其它應用程序均不能動態請求對該器件進行操作,而且飛行控制程序不能動態地使系統中的任何其它應用程序操作該器件,訪問控制還得到了內核的進一步加強。強制訪問控制帶來了可靠保障,自主訪問控制只對使用該方式的應用程序特別有效,而且必須假定這些應用程序存在一些缺陷。
空間域上保障資源的可用性
在高安全性系統中,關鍵應用程序不能占用全部的存儲器資源。在大多數實時操作系統中,存儲器通常用于保持線程控制塊及其它中央存儲區的內核對象。
當一個線程創建新線程、信號燈或其它內核對象時,內核將占用中心存儲區中的一塊存儲器以保持對象的數據。因此,一個線程中的錯誤將可能導致程序創建過多的內核對象而耗盡所有的中心存儲區(見圖2a),對于更為關鍵的線程甚至有可能帶來災難性的后果。
為了確保這種情況不會發生,RTOS可采用存儲器配額系統,在該系統中,系統設計工程師靜態規定每個進程占有的物理存儲器份額(見圖2b)。例如,用戶接口進程可占有128KB,而飛行控制程序為196KB。如果用戶接口進程中的某個線程發生了上述錯誤,接口進程將耗盡所占有的128KB存儲器,但飛行控制程序及其分配的196KB存儲器則完全不受影響。
在高安全性系統中:當線程請求創建內核對象時,父進程必須提供相應的存儲器配額以滿足請求,這類空間域的保護應作為RTOS設計的一部分。當需要提供存儲器保障時,中央存儲區和自主分配限額顯然不再夠用。
如果RTOS提供存儲器配額系統,那么低關鍵性應用程序可以采用動態加載,而已運行的高關鍵性應用程序必須提供所需的物理存儲器。此外,用來保持任何新進程的存儲器應來自創建進程的存儲器配額。如果該存儲器來自中央存儲區,當惡意或無意的寫應用程序試圖創建太多新進程時,進程創建很可能失敗。在大多數高安全性系統中,不用擔憂動態進程的創建,而RTOS應當可以重配置以使該功能可從系統中去除。
保證資源的時域可用性
絕大多數RTOS采用了基于優先級的占先調度程序。在這種機制下,系統中優先級的線程總是占用處理器。如果多個線程具有同等優先級,這些線程一般通過時間片(timeslicing)占用方式實現對處理器的平均分配。在給定的優先級條件下,時間片占用方式并不能保證處理器時間被關鍵線程占用。
考慮如下情形:系統包含兩個具有同等優先級的線程,線程A是不重要的后臺線程,而線程B則是至少需要40%處理器時間才能運行完成的關鍵線程。由于線程A和線程B分配了同等優先級,典型的調度程序將分割時間片,以保證每個進程都獲得50%的處理器時間。此時,線程B能順利運行完成?,F在假定線程A創建了一個具有同等優先級的新線程,這樣3個具有優先級的進程將共享處理器。線程B由于突然只獲得33%的處理器時間,因而無法完成其關鍵任務。這種情形下,如果線程A的代碼本身存在缺陷或受到病毒影響,進程A可能會創建數十個乃至數百個“聯合”線程,而使線程B只能占用很少一部分運行時間。
在調度程序中,采用特定優先級條件下某個線程的“權重”參數可以解決這個問題(見圖3)。當一個線程創建另一具有同等優先級的線程時,該進程必須轉讓自身的部分權重給新創建的線程。在上例中,假定系統設計工程師預先分配線程A和線程B的權重,使得線程A占用60%的運行時間,而線程B占用40%的運行時間。當線程A創建第三個線程時,必須轉讓部分權重,在此設為30%?,F在線程A和新線程均占用30%的處理器時間,而關鍵線程B的40%則維持不變。線程A可創建許多聯合進程而不影響線程B的運行,由此保證了線程B的處理器資源預留。某些重要的嵌入式系統,尤其是航天系統中需要能提供這類資源可用性的保障,并采用基于標準調度技術的調度程序。
所有調度程序固有的一個問題是調度程序并不了解線程所駐留的進程。還是在上例中,假定線程A在用戶接口進程中運行,而關鍵線程B則在飛行控制進程中運行。這兩個應用程序均在空間域而非時域中劃分并受保護,高安全性系統的設計工程師需要確保用戶接口的運行參數不影響飛行控制系統的運行參數,而線程調度程序并不能做出上述保證。
考慮以下情況:通過使線程B的優先級高于線程A或用戶接口中的任何其它線程,使其占用必需的全部運行時間。設計缺陷或不正確測試可能導致線程B實際的優先級降低(實際上所有的內核均有這樣的性能),從而使得用戶接口的線程控制了處理器。類似地,線程A的優先級提升超過線程B也將產生相同的效果。
為了確保處理器中不同關鍵程度的線程不互相影響,一種方法是提供進程級的調度程序,這種要求已受到高安全性軟件的設計工程師的關注。進程或分區、調度概念是ARINC 653規范的主要部分(ARINC 653 是一個航天應用軟件標準接口)。
ARINC 653分區調度程序根據系統設計工程師建立的時序流程運行分區或進程,每個進程在重復的時序流程中提供一個或多個運行窗口。在每個窗口期間,其它進程中的所有線程均不能運行,而只有當前活動的進程中的線程才能運行(通常根據標準線程調度準則進行調度)。當飛行控制應用程序的窗口活動時,可以確保其進程資源,此時用戶接口應用程序不能運行,因而無法在該窗口中占用關鍵應用程序的處理時間。
盡管ARINC 653沒有嚴格規定,但顯然更為謹慎的實現方法是采用后臺分區。當活動分區中不再有可運行線程時,分區調度程序應能運行后臺分區中仍然活動的后臺線程,而不是處于空閑狀態。低優先級的診斷代理程序就是后臺線程的一個實例,該程序間斷執行,但沒有嚴格的實時期限。
通過有選擇地停止活動區中的所有線程并運行下一分區中的所有線程,即可嘗試在現有商用操作系統上添加分區調度處理。這樣,分區交換時間是分區中線程數目的線性函數,這顯然是令人難以接受的實現方法。RTOS必須在內核中運行分區調度程序,以保證分區切換具有恒定的時間并盡可能快捷。
可調度性
滿足嚴格的時限是實時操作系統的基本要求之一,對于高安全性系統尤為重要。根據系統和線程要求,錯過時限將是非常嚴重的問題。
系統設計工程師經常利用速率單調分析(RMA)來分析和預測系統的時序行為。在這個過程中,系統設計工程師依靠基本的操作系統提供臨時而且快速的確定性系統業務。設計工程師不僅需要了解線程代碼執行的時間,還必須確定與線程相關的任何系統開銷。系統開銷通常包括關聯切換時間(運行系統調用所需的時間)以及中斷、中斷處理程序使能和運行系統開銷。
所有的實時操作系統都將承擔關聯轉換引發的系統開銷。較短的關聯轉換時間意味著較小的系統開銷、更為有效的進程資源利用,并能更好地滿足時限要求。實時操作系統的關聯轉換代碼通常需要經過優化以達到的運行速率。
中斷等待時間
典型的嵌入式系統通常需要處理幾類來自不同設備的中斷。某些中斷的優先級較高,需要盡快加以處理。例如,通知內核讀取傳感器的中斷對于航天器飛行控制而言至關重要,因此需要短的處理等待時間。另一方面,典型的定時器中斷頻率可為60Hz或100Hz,在硬件中總是采用10毫秒等待時間,因此定時器的中斷等待時間一般比其它中斷的等待時間要求更為寬松。
在系統調用期間,當內核對內部數據結構進行操作時,大多數內核將使所有的中斷失效。中斷失效的結果是當內核數據結構發生變化時,定時器中斷不會觸發(定時器中斷可能導致關聯轉換)。系統的中斷等待時間直接與內核中長臨界區的長度相關。
實際上,為了避免低優先級的定時器中斷,大多數內核增加了所有中斷的等待時間。更好的解決方案是在內核系統調用時不禁止中斷,而是將定時器中斷的處理推遲至系統調用完成之后。這種策略適用于所有內核系統調用過程中時間較短的情況(或者至少較長時間的調用可以重啟),這樣調度事件可以先于系統調用完成。因此,重新回到調度程序的時間可通過一些指令加以改變,但改變后的調度時間仍然要比較短并在一定的限制范圍之內。以這種方式設計帶有可搶先系統調用的內核則要復雜得多,這也正是大多數內核不采用這種方式的原因。
有界執行時間
為了對系統調用中線程占用的系統開銷進行計算,RTOS應為這些調用提供有界的執行時間。消息傳輸時序和互斥量(mutex)時序是涉及的兩大難題。
線程需要占用一定的時間完成各項任務,其中主要的任務是代碼執行,其它還包括發送和接收消息。消息傳送的時間取決于數據的大小,設計工程師如何計算傳送時間呢?RTOS具備這樣的功能,即控制傳送時間是否歸屬于發送線程或接收線程,或者兩者之間共享。實際上,內核的調度程序應將所有的任務(而不單單是主要的任務)視為具有優先級順序的執行單元,這樣系統設計工程師就能適當地控制和處理這些任務。
優先級倒置
優先級倒置一直是系統設計工程師嘗試速率單調分析(RMA)的絆腳石,因為RMA要求較高優先級的線程在較低優先級線程之前運行。當較高優先級的線程由于獲取的互斥量(或二元信號燈)被較低優先級的線程占用,而且較低優先級的線程因為中等優先級的線程也在運行而無法執行或釋放該互斥量時,將出現優先級倒置(圖4)。常見的RTOS優先級倒置解決方案是支持優先級繼承協議。
支持優先級繼承的互斥量工作原理如下:如果高優先級的線程試圖占用已被低優先級線程占有的互斥量,內核自動提升低優先級線程為高優先級線程。一旦低優先級線程釋放了互斥量,其優先級將恢復正常,然后接著運行高優先級線程。動態優先級提升可防止當高優先級線程仍在等待時運行中等優先級線程,從而避免了優先級倒置(見圖5)。在本例中,臨界區的執行時間(低優先級保持互斥量的時間)將添加至高優先級線程的系統開銷中。
優先級繼承協議不足以防止連鎖阻塞。假定中等優先級的線程試圖獲得低優先級占用的互斥量,而根據優先級繼承協議,隨著低優先級線程的優先級提升至中等,高優先級的線程將開始運行并試圖獲取另一個已被中等優先級線程占用的互斥量。中等優先級線程的優先級將被提升為高優先級,但高優先級線程現在必須等待低優先級線程和中等優先級線程完成后才能重新運行。
連鎖阻塞的臨界區可延伸至包含可能訪問相同互斥量的任何線程的臨界區,這不僅極大地增大了系統設計工程師計算系統開銷的難度,而且由于系統設計工程師必須計算壞情形下的系統開銷,連鎖阻塞現象可能導致系統效率極低(見圖6)。在RMA分析任務中,這些阻塞因素將增加計算時間,并有可能導致系統無法調度。由于連鎖阻塞的原因,設計工程師可能需要尋求更快的CPU或者去掉系統的部分功能。
優先級限額協議不僅能解決優先級倒置問題,還能防止連鎖阻塞(見圖7)。在一個實現方案(稱為“鎖定者”)中,每個信號燈均有關聯優先級,該優先級由系統設計工程師指定為優先級線程的優先級。當一個線程獲得該信號燈后,將立即提升至該信號燈的優先級。隨著信號燈的釋放,該線程也將恢復原來的優先級。由于優先級的提升,在信號燈釋放之前,其它可能爭奪信號燈的線程將不能運行。顯然這有效地抑制了連鎖阻塞。
多種RTOS既能支持優先級繼承,又能支持優先級限額,這完全取決于系統設計工程師的選擇。
系統要求的改變
當前使用的許多實時操作系統初專為那些簡單小型、運行于不帶存儲器保護硬件的處理器上的軟件系統而設計。隨著嵌入式系統中應用程序復雜度的不斷增加,容錯和高可用性特性正越來越重要,尤其是高安全性系統中必不可少。
容錯初是從進程和存儲器保護開始發展,但已經擴展至更多的領域,尤其是需要在時域和空間域保證資源可用性的那些領域。像優先級限額協議這樣的內核支持特性使得高安全性系統的設計工程師能在系統設計中極大地提高效率,并保障系統調度。
高安全性操作系統的設計
更新時間: 2007-02-02 14:10:36來源: 粵嵌教育瀏覽量:1138