0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

詳談嵌入式之Bootloader

Q4MP_gh_c472c21 ? 來源:lq ? 2019-02-04 15:27 ? 次閱讀

一、Bootloader 的引入

1.1 Bootloader 的引入

Linux 內核的啟動是需要一定的必要條件的,但在 CPU 剛上電啟動時,一般連內存控制 器都沒有配置過,根本無法在內存中運行程序,更不可能處在 Linux 內核的啟動環(huán)境中。為 了初始化 CPU 及其他外設,使得 Linux 內核可以在系統(tǒng)主存中跑起來,并讓系統(tǒng)符合 Linux 內核啟動的必備條件,必須要有一個先于內核運行的程序,他就是所謂的引導加載程序: Bootloader。

Bootloader并不是只有Linux才需要,是幾乎所有的運行操作系統(tǒng)的設備都必須具備的。 PC電腦的BIOS就是bootloader的一部分,對于Linux PC來說:Bootloader = BIOS + GRUB/LILO。

1.2 嵌入式 Linux 系統(tǒng)軟件結構與分布

一般情況下嵌入式 Linux 系統(tǒng)中軟件主要由以下幾個部分組成:

1.引導加載程序:其中包括內部ROM中的固化啟動代碼和bootloader兩部分。固化ROM 是廠家在芯片生產(chǎn)時固化,用于引導 bootloader。

2.Linux Kernel 和Drivers。

3.文件系統(tǒng):包括根文件系統(tǒng)和建立于Flash 內存設備之上的文件系統(tǒng)(ext4、UBI、 CRAMFS 等)。它是提供管理系統(tǒng)的各種配置文件以及系統(tǒng)執(zhí)行用于應用程序的良好運行環(huán) 境的載體。

4.應用程序:用于自定義的應用程序,存放于文件系統(tǒng)之中。 在Flash 存儲器中,上面四個部分的分布如圖 1 所示:

圖1:嵌入式Linux的軟件分布

但是以上只是大部分情況下的分布,也有一些根文件系統(tǒng)可能是 initramfs,被一起壓縮到了內核映像里,或者沒有 bootloader 參數(shù)區(qū)等。

二、Bootloader 介紹

2.1 Bootloader 的功能

Bootloader是在操作系統(tǒng)內核運行之前運行的一段小程序,通過它我們可以初始化硬件設備,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的狀態(tài),以便為最終調用操作系統(tǒng)內核準備好 正確的環(huán)境,最后從別處(Flash、以太網(wǎng)UART 等)載入內核映像并跳到入口地址運行。

簡單的說,Bootloader 就是這么一小段程序,它在系統(tǒng)上電時開始執(zhí)行,初始化硬件設備、準備好軟件環(huán)境,最后調用操作系統(tǒng)內核。

可以增強 Bootloader 的功能,比如增加網(wǎng)絡功能、從 PC 上通過串口或網(wǎng)絡下載文件、 燒寫文件、將 Flash 上壓縮的文件解壓后再運行等,這就是一個功能更為強大的 Bootloader, 也稱為 Monitor。實際上,在最終產(chǎn)品中用戶并不需要這些功能,他們只是為了方便開發(fā)。

2.2 Bootloader 的特點

由于 Bootloader 直接操作硬件,因此它嚴重依賴于硬件,且依據(jù)所引導的操作系統(tǒng)的不同而不同。在嵌入式世界中建立一個通用的 Bootloader 幾乎是不可能的,而有可能的是 讓一個 Bootloader 代碼支持多種不同的架構和操作系統(tǒng),并讓他方便移植。Bootloader的啟動過程通常是多階段的,這樣既能夠提供復雜的功能,又具有更好的可移植性。

大多數(shù) Bootloader 都包含兩種不同的操作模式:本地加載模式和遠程下載模式。遠程下載模式只對開發(fā)人員才有意義。

Bootloader 都映射在 CPU復位后運行的第一條指令的地址處,以保證系統(tǒng)上電或復位 后首先執(zhí)行 Bootloader。

2.3 Bootloader 的分類

首先區(qū)分一下“Bootloader”和“Monitor”的概念:嚴格的講,“Bootloader”只是引 導設備并執(zhí)行主程序的固件;而“Monitor”還提供更多的命令行接口,可進行調試、讀寫內存、燒寫 Flash、配置環(huán)境變量等?!癕onitor”在嵌入式系統(tǒng)開發(fā)過程中可以提供更好的調試功能,開發(fā)完成后,就完全設置成一個“Bootloader”了。所以習慣上將他們統(tǒng)稱為 Bootloader。表 2.1 為常見的開放源碼的 Linux 引導程序。

表2.1 常見的開放源碼 Linux 引導程序

其中 U-Boot 支持大多 CPU,可以燒寫 EXT2、JFFS2 文件系統(tǒng)映像,支持串口下載、網(wǎng)絡 下載,并提供了大量的命令。

2.4 Bootloader 的啟動模式

Bootloader 的主要功能是引導操作系統(tǒng),但在開發(fā)時,通常需要使用各種命令操作 Bootloader,一般通過串口來連接 PC 和開發(fā)板,可以在串口上輸入各種命令、觀察運行結果等。這也只是對開發(fā)人員才有意義,用戶使用產(chǎn)品時是不用接串口來控制 Bootloader 的。 從這個角度可以將 Bootloader 分為啟動加載(Boot loading)模式和下載(Down loading)模 式。

2.4.1 啟動加載(Bootloading)模式

這種模式也稱為"自主"(Autonomous)模式。也即 Boot Loader 從目標機上的某個固態(tài)存儲設備上將操作系統(tǒng)加載到 RAM 中運行,整個過程并沒有用戶的介入。這種模式是 Boot Loader 的正常工作模式,因此在嵌入式產(chǎn)品發(fā)布的時侯,Bootloader顯然必須工作在這種模 式下。

2.4.2 下載(Downloading)模式

在這種模式下,目標機上的 Boot Loader 將通過串口連接或網(wǎng)絡連接等通信手段從主機(Host)下載文件,比如:下載內核映像和根文件系統(tǒng)映像等。從主機下載的文件通常首先 被 Boot Loader 保存到目標機的 RAM 中,然后再被 Boot Loader 寫到目標機上的 FLASH 類固 態(tài)存儲設備中。Boot Loader 的這種模式通常在第一次安裝內核與根文件系統(tǒng)時被使用;此 外,以后的系統(tǒng)更新也會使用Boot Loader的這種工作模式。工作于這種模式下的Boot Loader 通常都會向它的終端用戶提供一個簡單的命令行接口。

像 Blob 或 U-Boot 等這樣功能強大的 Boot Loader 通常同時支持這兩種工作模式,而且 允許用戶在這兩種工作模式之間進行切換。比如,Blob 在啟動時處于正常的啟動加載模式, 但是它會延時 10 秒等待終端用戶按下任意鍵而將 blob 切換到下載模式。如果在 10 秒內沒 有用戶按鍵,則 blob 繼續(xù)啟動 Linux 內核。

2.4.3 下載模式之網(wǎng)絡啟動方式

這種方式開發(fā)板不需要配置較大的存儲介質(跟無盤工作站有點類似),但是使用這種 啟動方式之前,需要把 Bootloader 安裝到板上的 EPPROM 或者 Flash 中。Bootloader 通過以 太網(wǎng)接口遠程下載 Linux 內核映像或者文件系統(tǒng)到 RAM 中運行。這種方式對于嵌入式系統(tǒng)開發(fā)來說非常重要。

使用這種方式的前提條件,就是目標板有串口、以太網(wǎng)接口、USB 接口或者其他鏈接方式:串口一般作為控制臺,同時可以用來下載內核映像和 RAMDISK 文件系統(tǒng);用網(wǎng)絡接口 來掛載 NFS 文件系統(tǒng);也可以使用 USB 接口虛擬成以太網(wǎng)口來通訊。

使用網(wǎng)絡啟動方式,還需要在服務器上配置啟動相關網(wǎng)絡服務:使用 TFTP 服務為 Bootloader 客戶端提供文件下載功能;DHCP 服務動態(tài)為 Bootloader 設置 IP 地址,配置網(wǎng)絡 參數(shù)。網(wǎng)絡啟動方式如圖 2.1 所示。

圖2.1 網(wǎng)絡方式啟動系統(tǒng)

2.5 Bootloader 的啟動流程

Bootloader 的啟動過程可以分為單階段(Single Stage)、多階段(Multi-Stage)兩種。通 常多階段的 Bootloader 能提供更為復雜的功能以及更好的可移植性。從固態(tài)存儲設備上啟動 的Bootloader 大多都是兩個階段的啟動過程。第一階段使用匯編來實現(xiàn),它完成一些依賴于 CPU 體系結構的初始化,并調用第二階段的代碼;第二階段則通常使用 C 語言來實現(xiàn),這樣 可以實現(xiàn)更復雜的功能,而且代碼會有更好的可讀性和可移植性。

一般而言,這兩個階段完成的功能可以如下分類:

2.5.1 Bootloader 第一階段的功能

Bootloader 在第一階段主要完成以下功能:

硬件設備初始化;

為加載 Bootloader 的第二階段代碼準備 RAM 空間;

復制 Bootloader 的第二階段代碼到 RAM 空間中;

設置好棧;

跳轉到第二階段代碼的 C 入口點;

在第一階段進行的硬件初始化一般包括:關閉 WATCHDOG、關中斷、設置 CPU 的速度 和時鐘頻率、RAM 初始化等。這些并不都是必須的,比如 S3C2410/S3C2440 的開發(fā)板所使 用的 U-Boot 中,就將 CPU 的速度和時鐘頻率放在第二階段進行設置。

甚至,將第二階段的代碼復制到 RAM 空間也不是必須的,對于 Nor Flash 等支持 XIP 的 存儲設備,完全可以在上面直接執(zhí)行代碼,只不過相比在 RAM 中執(zhí)行效率大為降低。

2.5.2 Bootloader 第二階段的功能

Bootloader 在第二階段主要完成以下功能:

初始化本階段要使用到的硬件設備;

檢測系統(tǒng)內存映射(Memory map);

將內核映像和根文件系統(tǒng)映像從 Flash 上讀到 RAM 空間中;

為內核設置啟動參數(shù);

調用內核;

為了方便開發(fā),只要要初始化一個串口以便程序員與 Bootloader 進行交互。

所謂檢測內存映射,就是確定板上使用了多少內存、他們的地址空間是什么。由于嵌入 式開發(fā)中的 Bootloader 多是針對某類板子進行編寫,所以可以根據(jù)板子的情況直接設置,不 需要考慮可以適用于各類情況的復雜算法。

Flash 上的內核映像有可能是經(jīng)過壓縮的,在讀到 RAM 之后,還需要進行解壓。當然, 對于有自解壓功能的內核,不需要Bootloader 來解壓。

將根文件系統(tǒng)映像復制到 RAM 中并不是必須的,這取決于是什么類型的根文件系統(tǒng),以及內核訪問它的方法。

將內核放在適當?shù)奈恢煤?,在跳入?zhí)行內核之前,需要根據(jù)內核啟動的需求,配置相應 的啟動參數(shù)。如 Linux 內核的啟動要求如表 2.2 所示。

表2.2 Linux 內核啟動條件

在 C 語言中,可以像下列示例代碼一樣來調用內核:

void (*theKernel)(int zero, int arch, u32params_addr) = (void (*)(int, int, u32))KERNEL_RAM_BASE;

theKernel(0,ARCH_NUMBER, (u32)kernel_params_start);

2.6 Bootloader 與內核的交互

U-Boot 與內核之間的交互是單向的,U-Boot 將各類參數(shù)傳遞給內核。由于他們(U-Boot 與內核)不能同時運行,傳遞的辦法只有一個:U-Boot 將參數(shù)放在放在某個約定的地方之 后,再啟動內核,內核啟動后從這個地方獲得參數(shù)。

除了約定好參數(shù)存放的地址外,還要規(guī)定參數(shù)的結構。Linux 2.4.x 以后的內核都期望以標記列表(tagged list)的形式來傳遞啟動參數(shù)。標記,就是一種數(shù)據(jù)結構;標記列表,就 是挨著存放的多個標記。標記列表以標記 ATAG_CORE 開始,以標記 ATAG_NONE 結束。

標記的數(shù)據(jù)結構為tag,它由一個tag_header結構和一個聯(lián)合體(union)組成。tag_header 結構標示標記的類型及長度,比如是表示內存還是表示命令行參數(shù)等。對于不同類型的標記使用不同的聯(lián)合體(union),比如表示內存時使用tag_mem32,表示命令時使用tag_cmdline。

數(shù)據(jù)結構 tag 和tag_header 定義在 Linux 內核源碼的include/asm/setup.h 頭文件中(在 U-Boot 的 include/asm-arm/目錄下的 setup.h 中也有定義),如下所示:

struct tag_header {

u32 size;

u32 tag;

};

struct tag {

struct tag_header hdr;

union {

struct tag_core core;

struct tag_mem32 mem;

struct tag_videotext videotext;

struct tag_ramdisk ramdisk;

struct tag_initrd initrd;

struct tag_serialnr serialnr;

struct tag_revision revision;

struct tag_videolfb videolfb;

struct tag_cmdline cmdline;

/*

* Acorn specific

*/

struct tag_acorn acorn;

/*

* DC21285 specific

*/

struct tag_memclk memclk;

} u;

};

下面以設置內存標記、命令標記為例說明參數(shù)的傳遞。

2.6.1 設置標記ATAG_CORE

標記列表以標記 ATAG_CORE 開始,其結構體定義如下:

/* The list must start with an ATAG_COREnode */

#define ATAG_CORE 0x54410001

struct tag_core {

u32 flags; /* bit 0 =read-only */

u32 pagesize;

u32 rootdev;

};

假設 Bootloader與內核約定的參數(shù)存放地址為 0x30000100,則可以以如下代碼設置標 記 ATAG_CORE:

#define tag_next(t) ((struct tag *)((u32*)(t) + (t)->hdr.size))

static struct tag *params; //定義全局變量 params,為 struct tag 結構

static void setup_start_tag (bd_t *bd)

{

params = (struct tag *) bd->bi_boot_params; //bi_boot_params =0x30000100

params->hdr.tag = ATAG_CORE;// ATAG_CORE 在前面定義,指定標記類型

params->hdr.size = tag_size (tag_core); //計算標記大小

// 設置 ATAG_CORE 標記的內容

params->u.core.flags = 0;

params->u.core.pagesize = 0;

params->u.core.rootdev = 0;

params = tag_next (params);

}

其中,tag_next定義為指向當前標記的末尾。

2.6.2 設置內存標記

內存標記 tag_mem32 的定義如下:

struct tag_mem32 {

u32 size; // 內存的大小

u32 start; /* physical start address */

};

假設開發(fā)板使用的內存起始地址為 0x30000000,大小為 0x4000000,則內存標記可以如 下設置:

static void setup_memory_tags (bd_t *bd)

{

params->hdr.tag = ATAG_MEM;

params->hdr.size = tag_size (tag_mem32);

params->u.mem.start = 0x30000000;

params->u.mem.size = 0x4000000;

params = tag_next (params);

}

2.6.3 設置命令行標記

命令行就是一個字符串,它被用來控制內核的一些行為。比如“root=/dev/mtdlock2 init=/linuxrc console=ttySAC0”表示根文件系統(tǒng)在 MTD2 分區(qū)上,系統(tǒng)啟動后執(zhí)行的第一個程序為/linuxrc,控制臺為 ttySAC0。

命令行可以在 Bootloader 中通過命令設置好,然后按如下構造標記傳給內核。

char *p = ”root=/dev/mtdlock 2init=/linuxrc console=ttySAC0”;

params->hdr.tag = ATAG_CMDLINE;

params->hdr.size = (sizeof (structtag_header) + strlen (p) + 1 + 4) >> 2;

strcpy (params->u.cmdline.cmdline,p);

params = tag_next (params);

2.6.4 設置標記ATAG_NONE

標記列表以標記 ATAG_NONE 結束,如下設置:

static void setup_end_tag (bd_t *bd)

{

params->hdr.tag = ATAG_NONE;

params->hdr.size = 0;

}

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5052

    文章

    18909

    瀏覽量

    300732
  • Linux
    +關注

    關注

    87

    文章

    11161

    瀏覽量

    208462
  • bootloader
    +關注

    關注

    2

    文章

    233

    瀏覽量

    45460

原文標題:詳談嵌入式之Bootloader

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    嵌入式Linux啟動時間優(yōu)化的秘密五-Bootloader

    本文主要講述嵌入式Linux啟動時間優(yōu)化的秘密,我們繼續(xù)上篇沒有講完的嵌入式Linux啟動時間優(yōu)化方法,本文主要會講Bootloader。想看上一篇的請查看本文結尾的鏈接。 Bootloade
    發(fā)表于 04-21 17:24 ?2793次閱讀
    <b class='flag-5'>嵌入式</b>Linux啟動時間優(yōu)化的秘密<b class='flag-5'>之</b>五-<b class='flag-5'>Bootloader</b>

    #嵌入式軟件設計 BootLoader

    嵌入式嵌入式軟件bootloaderBoot
    電子技術那些事兒
    發(fā)布于 :2022年09月03日 09:26:33

    基于網(wǎng)絡加載的嵌入式BootLoader的設計與實現(xiàn)

    1摘要:由于嵌入式系統(tǒng)引導裝載程序(BootLoader)的網(wǎng)絡加載方式在產(chǎn)品開發(fā)初期階段的廣泛應用,因此基于網(wǎng)絡的BootLoader設計與實現(xiàn)具有較強的實際意義。提出了基于網(wǎng)絡加載
    發(fā)表于 01-16 10:58

    基于網(wǎng)絡加載的嵌入式BootLoader有什么優(yōu)點?

    嵌入式系統(tǒng)從軟件結構層次的角度來看,一般由引導裝載程序(BootLoader,BSP)、操作系統(tǒng)和應用程序幾部分組成。然而在有的嵌入式系統(tǒng)中,操作系統(tǒng)和應用程序存放在系統(tǒng)以外的設備中,如網(wǎng)絡、硬盤等,整個系統(tǒng)只有引導裝載程序。因
    發(fā)表于 04-10 07:19

    嵌入式開發(fā)系列課程六:啟動程序BootLoader的分析

    嵌入式開發(fā)系列課程六:啟動程序BootLoader的分析
    發(fā)表于 03-25 08:59 ?27次下載

    嵌入式系統(tǒng)Bootloader開發(fā)移植

    嵌入式系統(tǒng)Bootloader開發(fā)移植
    發(fā)表于 02-11 10:42 ?53次下載
    <b class='flag-5'>嵌入式</b>系統(tǒng)<b class='flag-5'>Bootloader</b>開發(fā)移植

    嵌入式系統(tǒng)BootLoader 移植

    嵌入式系統(tǒng):BootLoader 移植 U-Boot,全稱Universal Boot Loader,是遵循GPL條款的開放源碼項目。從FADSROM、8xxROM、PPCBOOT逐步發(fā)展演化而來。其源碼目錄、編譯形式與Linux
    發(fā)表于 03-01 14:54 ?47次下載

    基于MIPS64的嵌入式Linux Bootloader的移

    結合OCTEON3010(MIPS64)的U-boot移植經(jīng)驗,介紹了嵌入式Linux Bootloader的工作原理及功能,設計一個基于MIPS體系的Bootloader模型。對OCTEON系列的MIPS處理器
    發(fā)表于 12-17 16:30 ?56次下載

    嵌入式考試筆記嵌入式系統(tǒng)基礎知識

    嵌入式考試筆記嵌入式系統(tǒng)基礎知識 一、引言 自《嵌入式系統(tǒng)設
    發(fā)表于 05-17 09:25 ?965次閱讀

    基于Xilinx FPGA特點的嵌入式Bootloader設計與實現(xiàn)

    Bootloader程序是指嵌入式系統(tǒng)在正常工作之前,配置系統(tǒng)運行環(huán)境,引導操作系統(tǒng)的一小段程序。通過這段程序,我們可以初始化硬件設備、建立內存空間映射等,從而將系統(tǒng)的軟硬件環(huán)境帶到一個合適的環(huán)境
    發(fā)表于 07-16 13:07 ?1516次閱讀
    基于Xilinx FPGA特點的<b class='flag-5'>嵌入式</b><b class='flag-5'>Bootloader</b>設計與實現(xiàn)

    基于嵌入式Linux系統(tǒng)的Bootloader模型在MIPS64上的移植設計淺析

    Linux具備良好的裁剪性和移植性,并且開源、資源豐富,已成為嵌入式系統(tǒng)的開發(fā)熱點。一個完整的嵌入式Linux系通通常包括Bootloader、內核、文件系統(tǒng)三部分,目標板上電后由
    發(fā)表于 09-12 16:13 ?888次閱讀

    嵌入式軟件c語言編碼規(guī)范

    嵌入式軟件c語言編碼規(guī)范
    發(fā)表于 10-28 18:13 ?28次下載

    VScode嵌入式開發(fā)入門教程

    VScode嵌入式開發(fā)入門教程1.VScode進行單片機嵌入式開發(fā)教程2.單片機開發(fā)環(huán)境的搭建3.相關技巧與設置 VScode
    發(fā)表于 11-03 09:51 ?44次下載
    VScode<b class='flag-5'>嵌入式</b>開發(fā)<b class='flag-5'>之</b>入門教程

    分享嵌入式軟件Bootloader設計與移植方法

      嵌入式電子產(chǎn)品由于其專用性的特性 ,使得與硬件相關的軟件需要經(jīng)過移植才能使用。如何設計與移植設備開機第一個運行的代碼引導程序 Bootloader尤為重要。不同內核開發(fā)平臺
    發(fā)表于 04-02 17:24 ?3次下載

    嵌入式系統(tǒng)中u-boot和bootloader詳解

    嵌入式軟件工程師聽說過 u-boot 和 bootloader,但很多工程師依然不知道他們到底是啥。
    發(fā)表于 10-20 13:12 ?1959次閱讀