由于受到眾多硬件廠商及軟件巨頭的支持,以及自身學術性和應用性的完美結合,Linux操作系統在各個方面尤其是嵌入式領域得到了廣泛應用。同時,作為開源軟件,市面上雖然已經有不少介紹Linux內核啟動流程的文章和書籍,但往往都過于簡陋,流于表面,或者過于分散,無法得到一個整體的印象。本文基于ARM FVP模擬器平臺ARMv7 Cortext-A9處理器,專注于Linux 4.10內核啟動流程中的內核初始化環節,對整個過程進行逐行解讀,分析每行關鍵代碼涉及到的ARM架構和Linux內核的基本知識,使得用戶可以對整個啟動流程有一個整體的概念,從而有助于解決啟動過程中遇到的各種問題。
注意*:本文草稿同步在本人GitHub倉庫更新,有興趣者可移步觀看。
關鍵詞:嵌入式系統,虛擬化,Linux內核,32位ARM架構,ARMv7,Cortext-A9;內核初始化
1. 介紹
1.1 基本環境
本文使用的調試環境如下:
- 調試器采用ARM公司的DS-5 V5.27.1;
- 模擬器采用DS-5繼承的ARM FVP(Fixed Virtual Platform,固定虛擬平臺);
- 模擬器目標板采用ARM vexpress,處理器為Cortext-A9 4核處理器;
- Linux內核版本為4.10;
- 配置文件采用vexpress_defconfig;
- 內核格式為非壓縮的Image;
- DTB文件采用DS-5自帶的rtsm_ve-cortex_a9x4.dtb。
注意:
- 本文讀者應具備基礎的ARM架構指令集知識(工作模式、寄存器組織、尋址模式等)和C語言常識;
- 本文關注的是32位ARMv7架構啟動流程,無關代碼以
...
表示從而方便閱讀; - DS-5和ARM FVP的使用方法可參見ARM FVP(固定虛擬平臺)Linux內核調試簡明手冊;
- Linux內核代碼可參考Linux源碼主線;
- ARM體系結構可參考官網ARMv7-AR Reference Manual;
- ARM指令可參考ARM官網ARM and Thumb-2 Instruction Set Quick Reference Card (Chinese)和ARMv7-AR Reference Manual附錄A4 - A8;
- ARM 32位架構ABI可參考ARM官網針對ARM體系結構的應用程序二進制接口(ABI);
- GNU鏈接器(ld)和匯編器(as)手冊可參考GNU二進制工具文檔。
1.2 初始化階段劃分
Linux內核初始化劃分為如下幾個階段:
- 入口階段,即內核入口到C語言入口start_kernel()之前的階段,基本上使用匯編語言實現;
- 早期初始化階段,即start_kernel()過程,用于為kernel_init線程(PID為1)和線程調度準備最基本的運行環境;
- 初始化階段,即kernel_init線程的執行過程,用于進行真正的內核初始化,包括驅動、文件系統、網絡協議棧等模塊的真正初始化,并最終執行跟文件系統中的初始化腳本;
- 用戶空間初始化,即初始化腳本定義的用戶程序執行和模塊加載等,不屬于本文討論范圍。