歡迎您光臨本站 註冊首頁

嵌入式操作系統調試

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  調試是開發過程中必不可少的環節,通用的桌面操作系統與嵌入式操
作系統在調試環境上存在明顯的差別。前者,調試器與被調試的程序往
往是運行在同一台機器、相同的操作系統上的兩個進程,調試器進程
通過操作系統專門提供的調用介面(早期UNIX系統的ptrace調用、如
今的進程文件系統等)控制、訪問被調試進程。

後者(又稱為遠程調試),為了向系統開發人員提供靈活、方便的調
試界面,調試器還是運行於通用桌面操作系統的應用程
序,被調試的程序則運行於基於特定硬體平台的嵌入式操作系統
(目標操作系統)。

這就帶來以下 問 題:

調試器與被調試程序如何通信,被調試程序產生異常如何及
時通知調試器,調試器如何控制、訪問被調試程序,調試器
如何識別有關被調試程序的多任務信息並控制某一特定任務 ,
調試器如何處理某些與目標硬體平台相關的
信息(如目標平台的寄存器信息、機器代碼 的 反彙編等)。

我們介紹兩種遠程調試的方案,看它們怎樣解決這些問題。

調試方案 一 插樁(stub)
第一種方案是在目標操作系統和調試器內分別加入某些功能模塊,
二者互通信息來進行調試 。

上述問題可通過以下途徑解決:

調試器與被調試程序的通信

調試器與目標操作系統通過指定通信埠(串口、網卡、並口)
遵循遠程調試協議進行通信
(遠程調試協議詳見http://rtos.ict.ac.cn/rtos/debugger/)。

被調試程序產生異常及時通知調試器
目標操作系統的所有異常處理最終都要轉向通信模塊,告知調
試器當前的異常號;調試器據 此向用戶顯示被調試程序產生了
哪一類異常。 調試器控制、訪問被調試程序 調試器的這類請
求實際上都將轉換成對被調試程序的地址空間或目標平台的某些寄存器
的 訪問,目標操作系統接收到這樣的請求可以直接處理。對於
沒有虛擬存儲概念的簡單的嵌入式 操作系統而言,完成這些
任務十分容易。調試器識別有關被調試程序的多任務信息並
控制某一特定任務 由目標操作系統提供相關介面。目標系統根
據調試器發送的關於多任務的請求,調用該介面 提供相應信息
或針對某一特定任務進行控制,並返回信息給調試器。

調試器處理與目標硬體平台相關的信息

第2條所述調試器應能根據異常號識別目標平台產生異常的類型
也屬於這一範疇,這類工作完全可以由調試器獨立完成。支持多
種目標平台正是GNU GDB的一大特色。

綜上所述,這一方案需要目標操作系統提供支持遠程調試協議的
通信模塊(包括簡單的設備驅動)和多任務調試介面,並改寫異
常處理的有關部分。另外目標操作系統還需要定義一個設置斷點的
函數;因為有的硬體平台提供能產生特定調試陷阱異常(debug trap)
的斷點指令以支持調試(如X86的INT 3),而另一些機器沒有類似的
指令,就用任意一條不能被解釋執行的非法(保留)指令代替。

目標操作系統添加的這些模塊統稱為"插樁"(見下圖),駐留於ROM
中則稱為ROM monitor。通用操作系統也有具備這類模塊的:

編譯運行於Alpha、Sparc或PowerPC平台的LINUX內核時若將kgdb開
關打開,就相當於加入了插樁。

http://www.cn.ibm.com/developerWorks/linux/embed/debug/fig1.gif
圖1

運行於目標操作系統的被調試的應用程序要在入口處調用這個設置
斷點的函數以產生異常,異常處理程序調用調試埠通信模塊,
等待主機(host)上的調試器發送信息。雙方建立連接后調試器便
等待用戶發出調試命令,目標系統等待調試器根據用戶命令生成的指令。

這一 過程如下圖所示。

http://www.cn.ibm.com/developerWorks/linux/embed/debug/fig2.gif
圖2

這一方案的實質是用軟體接管目標系統的全部異常處理(exception
handler)及部分中斷處理,在其中插入調試埠通信模塊,與主機的調試器
交互。它只能在目標操作系統初始化,特別是調試通信埠初始化完成
后才起作用,所以一般只用於調試運行於目標操作系統之上的應用程序,
而不宜用來調試目標操作系統,特別是無法調試目標

操作系統的啟動過程。而且由於它必然要佔用目標平台的某個通信埠,
該埠的通信程序就無法調試了。最關鍵的是它必須改動目標操作系統,
這一改動即使沒有對操作系統在調試過程中的表現造成不利影響,至少
也會導致目標系統多了一個不用於正式發布的調試版。



二 片上調試(On Chip Debugging)及
Embedded PowerPC Background Debug Mode

片上調試是在處理器內部嵌入額外的控制模塊,當滿足了一定的觸發條件
時進入某種特殊狀態。在該狀態下,被調試程序停止運行,主機的調試器
可以通過處理器外部特設的通信介面
訪問各種資源(寄存器、存儲器等)並執行指令。為了實現主機通信端
口與目標板調試通信介面各引腳信號的匹配,二者往往通過一塊簡單的
信號轉換電路板連接(如下圖所示)。

內 嵌的控制模塊以基於微碼的監控器(microcode monitor)或純硬體
資源的形式存在,包括一些提供給用戶的介面(如斷點寄存器等)。具體
產品有Motorola CPU16、CPU32、Coldfire系列的BDM(Background Debug
Mode),Motorola PowerPC 5xx、8xx系列的
EPBDM(Embedded PowerPC Background Debug Mode),IBM、TI的
JTAG(Joint Test Action Debug,IEEE標準),還有OnCE、MPSD等等。

下面以MPC860的EPBDM為例介紹片上調試方式。



http://www.cn.ibm.com/developerWorks/linux/embed/debug/fig3.gif
圖3



EPBDM的運作相當於用處理器內嵌的調試模塊接管中斷及異常處理。用戶
通過設置調試許可寄存器(debug enable register)來指定哪些中斷或
異常發生后處理器直接進入調試狀態,而不是操作系統的處理程序。進入
調試狀態后,內嵌調試模塊向外部調試通信介面發出信號,通知一直在通信介面
監聽的主機調試器,然後調試器便可通過調試模塊使處理器執行任意系統
指令(相當於特權 態)。所有指令均通過調試模塊獲取,所有load/store
均直接訪問內存,緩存(cache)及存儲管理單元(MMU)均不可用;數據寄
存器被映射為一個特殊寄存器DPDR,通過mtspr和mfspr指令訪問。調試器
向處理器送rfi(return from interrupt)指令便結束調試狀態,被調試程序
繼續運行。


與插樁方式的缺點相對應,OCD不佔用目標平台的通信埠,無需修改目
標操作系統,能調試目標操作系統的啟動過程,大大方便了系統開發人
員。

隨之而來的缺點是軟體工作量的增加:調試器端除了需補充對目標操作
系統多任務的識別、控制等模塊,還要針對使用同一芯 片的不同開發板
編寫各類ROM、RAM的初始化程序。

下面就以調試運行於MPC860的LINUX為例,說明用OCD方式調試OS 啟動的
某些關鍵細節。



首先,LINUX內核模塊以壓縮后的zImage形式駐留於目標板的ROM,目標
板上電后先運行RO M 中指定位置的程序將內核移至RAM並解壓縮,然後
再跳轉至內核入口處運行。要調試內核,
必須在上電后ROM中的指令執行之前獲得系統的控制權,即進入調試
狀態、設斷點,這樣才能開展調試過程。MPC860的EPBDM提供了這一手段。

MPC860沒有類似X86的INT
3那樣能產生特定調試陷阱異常的指令,而操作系統內核往往具有針對
非法指令的異常處理

;為了使對內核正常運行的干擾降至最小,調試時應盡量設置硬體
斷點,而不是利用非法
指 令產生異常的"軟"斷點。

LINUX實現了虛存管理,嵌入式LINUX往往也有這一功能。地址空間從實
到虛的轉換在內核啟動過程中便完成了,不論調試內核還是應用程序,調
試器都無法迴避對目標系統虛地址空間的訪問,否則斷點命中時根本無法
根據程序計數器的虛地址顯示當前指令,更不用說訪問變數了。由於調試
狀態下轉換旁視緩衝器(Translation Lookaside Buffer)無法利用,
只能仿照LINUX內核TLB失效時的異常處理程序,根據虛地址中的頁表索
引位訪問特定寄存器查兩級頁表得出物理頁面號,從而完成虛實地址的
轉換。MPC860採用哈佛結構(Harvard architecture),指令和數據緩
存分離設置(因為程序的指令段和數據段是分離的,這種結構可以消除取
指令和訪問數據之間的衝突),二者的TLB也分離設置;然而TLB失效時查找頁
表計算物理地址的過程是相同的,因為頁表只有一個,不存在指令、數據
分離的問題。虛實地址轉換這一任務雖然完全落在了調試器一方,

由於上述原因,再加上調試對象是嵌入式系統,一般不會有外存設備,
不必考慮內存訪問缺頁的情況,所以增加的工作量並不大。



深入話題
傳統的調試方法可概括為如下過程:設斷點--程序暫停--觀察程序狀態
--繼續運行。被調試的如果是實時系統,即使調試器支持批處理命令避免了
用戶輸入命令、觀察結果帶來的延遲,它與目標系統之間的通信也完全可
能錯過對目標平台外設信號的響應。於是,針對某些調 試器(如GDB)
提供的監視點(trace point)這一特殊調試手段,目標方的插樁在原有
的基礎上被改進,稱為代理(agent)。調試時用戶首先在調試器設置監
視點,以源代碼表達式的形式指定感興趣的對象名。為了減少
代理解析表達式的工作,調試器將表達式轉換為簡單的位元組碼,傳送至
代理。程序運行后命中監視點、喚醒代理,代理根據位元組碼記錄用戶所
需數據存入特定緩衝區(不僅僅是表達式的最終結果,還有中間結果),
令程序繼續運行;這一步驟無需與調試器通信。當調試器再度得到控制
時,就可以發出命令,向代理查詢歷次監視記錄。較之於插樁,代理
增加了對接受到的位元組碼的分析模塊,相應的目標代碼體積只有大
約3K位元組;當然,監視記錄緩衝區也要佔用目標平台的存儲空間,不過
緩衝區的大小可在代理生成時由用戶決定。總之,這一改進以有限的目
標系統資源為代價,為實時監視提供了一個低成本的可行方案。


調試並不僅僅意味著設斷點--程序暫停--觀察--繼續這一過程,往往還
需要profiling、跟蹤(trace)等多種手段,而現代微處理器的技術進
步卻為這些調試手段的實行帶來了困難。

以跟蹤為例,其目的無非是記錄真實的程序運行流;可現代處理器指令
緩存都集成於晶元內(RISC處理器尤為如此),運行指令時"取指"這一
操作大多在晶元內部針對指令緩存進行,晶元外部匯流排上只能觀察到多
條指令的預取(prefetch),預取的指令並不一定執行(由於跳轉等原因);
另外,指令往往經過動態調度后在流水線中亂序執行,如何再現其原始
順序也是個問題。解決方案大致有以下三種:

有的處理器除了正常運行外,還能以串列方式運行,所有的取指周期都
可呈現於片外匯流排 (相當于禁用緩存與流水線)。
這樣一來,跟蹤容易多了,處理器性能也大大降低了,根本不適用於
實時要求嚴格的系統。編譯器自動在指定的分支及函數出入口插入對特
定內存區域的寫指令(與gprof等profiling 工具採用的手段類似),它
們都是不通過緩存而直接向內存寫的,這就能反映於晶元外匯流排

從而被外接的邏輯分析儀記錄,最終由主機端的調試工具分析並結合符號
表重構程序流。這種方法雖被廣泛使用,但畢竟是干擾式的(intrusive),
對系統性能也有影響。像上文所述的片上調試那樣,也有處理器在片
內附加了跟蹤電路,收集程序流運行時的"不連貫"(discontinuities)
信息(分支和異常處理的跳轉目的及源地址等),壓縮後送至特定端
口,再由邏輯分析儀捕獲送至主機端調試工具重構程序流。該方案對
系統性能影響最小。


總之,處理器廠家提供集成於片內的調試電路為高檔嵌入式系統開發提
供各種非干擾式的調試手段早已是大勢所趨。為了解決該領域標準化的
需要,一些處理器廠家、工具開發公司和 儀器製造商於1998年組成了
Nexus 5001 Forum,這是一個旨在為嵌入式控制應用產生和定義嵌入式
處理器調試介面標準的聯合組織,以前的名稱是
Global Embedded Processor Debug Interface Standard Consortium
(全球嵌入式處理器調試介面標準協會)。

Nexus現在有24個成員單位,包括創始成員Motorola、Infineon
Technologies、日立、ETAS和HP等公司。該組織首先處理的是汽車
動力應用所需要的調試,現在已發展成為調試數據通信、無線系統和其
他實時嵌入式應用的通用介面。


參考文獻



MPC860 PowerQUICC Users Manual MOTOROLA http://www.vas-gmbh.de/software/mpcbdm/
http://www.metrowerks.com/tools/documentation/embedded/zenofbdm
http://www.redhat.com/support/wpapers/cygnus_heinsenberg/trace.html
http://www.ednmag.com/reg/2000/05112000/10tt.htm


[火星人 ] 嵌入式操作系統調試已經有204次圍觀

http://coctec.com/docs/program/show-post-72176.html