程序加載的“調(diào)度員”:從存儲介質(zhì)到內(nèi)存的搬運工
完成硬件初始化后,
Bootloader的核心任務轉(zhuǎn)向“程序加載”——將存儲在非易失性介質(zhì)(如Flash、硬盤)中的操作系統(tǒng)內(nèi)核或應用程序,搬運到內(nèi)存(RAM)中并啟動。這一過程如同將演出道具從倉庫搬運到舞臺,需要精準的地址定位、數(shù)據(jù)校驗和跳轉(zhuǎn)執(zhí)行。
程序加載的第一步是“定位目標程序”。在嵌入式系統(tǒng)中,操作系統(tǒng)內(nèi)核通常存儲在特定的Flash分區(qū)中,例如在Linux系統(tǒng)中,內(nèi)核鏡像可能存放在“kernel”分區(qū)的0x08020000地址。Bootloader會通過解析分區(qū)表(如MBR、GPT或自定義分區(qū)表),找到目標程序的起始地址和大小,并檢查分區(qū)的完整性——若分區(qū)表損壞或程序大小超過分區(qū)容量,Bootloader會進入錯誤處理流程(如通過LED閃爍報警)。
數(shù)據(jù)搬運過程需要兼顧速度與可靠性。對于NOR Flash等支持隨機讀取的存儲介質(zhì),Bootloader可直接通過地址映射讀取數(shù)據(jù);而對于NAND Flash,由于其按頁讀取的特性,Bootloader需要先發(fā)送頁地址命令,再讀取整頁數(shù)據(jù)并搬運到內(nèi)存。為防止數(shù)據(jù)傳輸錯誤,Bootloader會對每塊搬運的數(shù)據(jù)進行校驗:簡單場景下使用校驗和(Checksum),復雜場景則采用CRC32算法,若校驗失敗則重新讀取,直至成功或達到重試上限。
程序加載的最后一步是“地址重定位”。許多程序在編譯時采用“位置無關代碼”(PIC),可在任意內(nèi)存地址運行,但部分內(nèi)核程序需要固定在特定地址執(zhí)行。
Bootloader會根據(jù)程序的鏈接腳本信息,將代碼段、數(shù)據(jù)段、BSS段搬運到內(nèi)存的指定位置:代碼段(Text)存放可執(zhí)行指令,通常加載到低地址區(qū)域;數(shù)據(jù)段(Data)存放初始化的全局變量,加載到讀寫區(qū)域;BSS段存放未初始化的全局變量,加載后會被清零。這一步確保了程序能按照編譯時的預期地址運行,避免因地址錯亂導致的崩潰。