3. 理論與實作背景
3.3. eCos
3.3.4. HAL
HAL 將處理器架構的底層硬體和平台的底層硬體抽象化可以有效率地移植 eCos kernel 到別的平台。為了移植 eCos 到新的平台,主要的工作是修改 HAL 以適應支援新的硬體平台,因此了解 HAL 這個軟體元件的架構相當重要。HAL 有一般化的 API,把特殊的硬體行為封裝起來,由硬體來完成設計的功能,並且
允許應用層直接存取硬體和任何架構特徵。例如有同樣意義的 interrupt,實際執 行插斷的程序依不同架構而相異。為了使 HAL 的可用性達到最廣的範圍,HAL 是用 C 語言和組合語言實作。另外為了 HAL 介面實作上的效率,HAL 是用 C/ CPP 巨集實作,可以使用 inline C 語言,inline 組合語言,或外部呼叫 C 語言和外部 呼叫組合語言。
HAL 含概三個不同的模組:
z Architecture z Variant z Platform
第一個 HAL 模組定義 architecture。每個被 eCos 支援的處理器家族都被認定 為不同的 architecture。每個 architecture 模組會包含所需的 CPU 啟動程式碼,
interrupt delivery 程式碼,context switching 程式碼和其他指令集架構特殊功能的 程式碼。第二個 HAL 模組定義了 variant。一個 variant 是一個處理器家族當中的 一個特定處理器。例如定義不同的 on-chip MMU 或是快取,也處理任何晶片上 的週邊,如記 memory controller 和 interrupt controller。第三個 HAL 副模組是定 義 platform。一個 platform 是一塊特別的硬體平台,它包括選擇處理器的 architecture 和 variant。傳統上這個模組包括平台啟動,晶片選擇設定,interrupt controller 和計時裝置。這三層的介定不必很清楚,因為各模組的功能性在不同 硬體平台有不同的設定。例如快取和 MMU 可以在 architecture HAL 或 variant HAL。
圖 4 是 HAL 啟動期間副程式被引用的流程圖[18]。啟動程序可能會依不同 架構和平台的使用有些微的不同。此外,啟動程序可能也因為 HAL 的一些設定 選項的不同而與此流程圖有所差異。
Figure 4. HAL 啟動流程圖
1. 系統在電力週期啟動之後開始運作。此啟動程序也是 soft reset 的啟動 方式。
2. 在 hard reset 或 soft reset 發生後,處理器會跳到 reset vector。Reset vector 對處理器會用到的最少數量暫存器做設定,使得系統可以繼續初始化程 序。
3. 接著 reset vector 會跳到 _start,是 HAL 初始化的主要開啟點。
4. 呼叫 hal_cpu_init,這個程式設定處理器的暫存器,如關閉指令和資料 快取。確保對於剩下的初使化程序而言,處理器在一個正常的狀態。
5. 下一個被呼叫的副程式叫 hal_hardware_init,硬體設定包含快取設定,
設定插斷暫存器為預設狀態,關閉處理器的 watchdog,設定即時時鐘 暫存器,和設定晶片選擇暫存器,這些都是基於平台特有的硬體而不同。
6. 接著是設定 interrupt stack 的區域,在 interrupt 發生時可以儲存處理器 狀態。在整個初始化程序中,都是利用這一段 stack 做為呼叫 C 副程式 會用到的 stack。因為此時 interrupt 是關閉的,不會有衝突發生。
7. 下一步執行 hal_mon_init 程式,確保預設的 exception 處理器安裝給每 一個處理器支援的例外情況。
8. 接著清理 BSS 部份,它包含所有未初始化的區域和全域變數。
9. 然後設定 stack,以致於 C 程式呼叫可以被實行,不再使用 interrupt stack。
10. 呼叫 hal_platform_init 或呼叫 hal_if_init,初始 virtual vector table。
11. 初始化 MMU,處理 logical addresses 和 physical addresses 的轉換,同時 提供保護和快取機制。
12. 接著啟動指令快取和資料快取。
13. 執行 hal_IRQ_Init,設定 Communications Processor Module (CPM),它 接受和按優先順序處理內外部 interrupt。
14. 下一步,cyg_hal_invoke_constructors 呼叫所有 global C++ constructors。
Linker 會提供 global constructor 的名單,cyg_type.h 則用巨集定義這份 名單上 constructor 被呼叫的順序。
15. 如果設定當中有除錯環境而且 ROM monitor 沒有提供除錯支援,下一 個要呼叫的是 initialize_stub。initialize_stub 安裝 standard trap handler 並 把硬體設定在適合除錯的狀態。
16. 最後一個步驟是把控制權轉給 kernel。cyg_start 就是控制權由 HAL 轉 入 kernel 的點。