uboot分析 uboot啟動核心

2021-10-02 06:18:12 字數 3308 閱讀 2186

u-boot啟動核心概述

u-boot啟動完成後,最終進入到main_loop()迴圈中。若在bootdelay倒計時為0之前,u-boot控制台有輸入,則進入命令解析-執行的迴圈;若控制台無輸入,u-boot將啟動核心。

u-boot啟動核心可歸結為以下四個步驟:

1)將核心搬移至ddr中;

2)校驗核心格式、crc;

3)準備傳參;

4)跳轉執行核心。

u-boot啟動核心過程分析

2.1 將核心搬移至ddr中

在/uboot/lib_arm/board.c->start_armboot()函式呼叫/uboot/common/main.c->main_loop()函式,main_loop()函式中包含了核心的啟動**。

複製**

s = getenv (「bootcmd」); //獲取bootcmd環境變數的值

debug ("### main_loop: bootcmd="%s"\n", s ? s : 「」);

if (bootdelay >= 0 && s && !abortboot (bootdelay))

複製**

環境變數bootcmd的值在開發板配置檔案(/uboot/include/configs/x210_sd.h)中定義。

複製**

#if defined(cfg_fastboot_nandbsp)

#define config_bootcommand 「nand read c0008000 600000 400000; nand read 30a00000 b00000 180000;

bootm c0008000 30a00000」

#elif defined(cfg_fastboot_sdmmcbsp)

#define config_bootcommand 「movi read kernel c0008000; movi read rootfs 30a00000 180000;

bootm c0008000 30a00000」

#endif

複製**

環境變數bootcmd包含如下命令:

bootcmd=nand read c0008000 600000 400000; /將kernel(大小0x00400000位元組)從nand中的0x00600000位址處拷貝到ddr中的 0xc0008000位址處/

nand read 30a00000 b00000 180000; /將rootfs(大小0x00180000位元組)從nand中的0x00b00000位址處拷貝到ddr中的 0x30a08000位址處/

bootm c0008000 30a00000 //啟動kernel、rootfs

u-boot能準確識別kernel、rootfs在nandflash中的位置,是因為u-boot中已對nandflash進行分割槽。燒錄時,嚴格按照分割槽要求將uboot、kernel、rootfs燒錄進nandflash中即可。

在u-boot下執行mtd命令,即可檢視各個分割槽的情況。

2.2 校驗核心格式、crc

核心格式有兩類:zimage和uimage。

並不是所有u-boot都支援zimage,是否支援就看其配置檔案(x210_sd.h)中是否定義config_zimage_boot這個巨集。所以有些uboot是支援zimage啟動的,有些則不支援。但是所有的uboot肯定都支援uimage啟動。

zimage

linux核心經過編譯後生成乙個elf格式的可執行檔案,vmlinux。再通過arm-linux-objcopy工具進行加工,最後進行壓縮,得到zimage格式的核心映象,可以燒錄進啟動介質中。

uimage

uimage是由zimage加工得到的。uboot中的mkimage工具將zimage加工生成uimage來給uboot啟動。這個加工過程其實就是在zimage前面加上64位元組的uimage的頭資訊即可。

ulmage格式的核心頭部資訊在/uboot/include/image.h中定義。

ih_load是載入位址,即核心在ddr中的位址(執行位址);ih_ep是核心入口位址。

複製**

typedef struct image_header image_header_t;

複製**

執行環境變數bootcmd中的命令"bootm c0008000 30a00000",實質是執行do_bootm()函式(/uboot/common/cmd_bootm.c->do_bootm())。

do_bootm()函式在標號after_header_check之前,都是在校驗核心的頭部資訊。根據頭部資訊,判斷核心格式和進行crc校驗。

實際上,從nandflash中讀取的uimage可以放置在ddr中的任意位置,只要不破壞u-boot占有的記憶體空間即可。因為do_bootm()函式內部從頭部獲取核心的載入位址,當發現該uimage當前所處的位址與載入位址不同時,會將核心搬移至載入位址中。一般情況下,都會將核心搬移至載入位址中,便不用使用do_bootm()函式來搬移核心,提高效率。

do_bootm()函式將根據系統型別,啟動核心。此處將呼叫/uboot/lib_arm/bootm.c/->do_bootm_linux ()函式啟動核心。

複製**

after_header_check:

os = hdr->ih_os;

#endif

switch (os) ;

struct tag u;};

複製**

標記列表舉例:

複製**

static void setup_start_tag (bd_t *bd)

#ifdef config_setup_memory_tags

static void setup_memory_tags (bd_t *bd)

}#endif

…//中間還有多個標記

static void setup_end_tag (bd_t *bd)

複製**

do_bootm_linux ()函式啟動核心前,先將u-boot中的啟動引數傳給核心。

引數分析:

1)0 : 相當於mov r0 #0。

2)machid : u-boot中的機器碼,從全域性變數bd中獲取。核心機器碼和u-boot機器碼必須一致才能啟動核心。

複製**

void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *ar**, bootm_headers_t *images)

複製**

2.4 跳轉執行核心

thekernel()函式執行成功後,核心將讀取啟動引數,並開始啟動。

Uboot啟動流程分析

uboot是嵌入式系統中最常用的bootloader,這裡我們以s3c2410為例分析一下uboot的啟動流程。首先通過uboot的鏈結檔案,我們可以看到uboot執行是執行的第一段 在start.s中。entry start sections align 4 rodata align 4 data...

uboot移植 uboot啟動回顧

一 uboot啟動的第一階段start.s 路徑uboot cpu s5pc11x start.s 1 include 標頭檔案包含,config.件原始碼中不存 在,配置後自動生成 路徑 include linux config.h 2 include 標頭檔案包含,version.件原始碼中不存...

uboot啟動流程概述 uboot啟動流程

u boot系統啟動流程 大多數bootloader都分為stage1和stage2兩大部分,u boot也不例外。依賴於cpu體系結構的 如裝置初始化 等 通常都放在stage1,且可以用組合語言來實現,而stage2則通常用c語言來實現,這樣可以實現複雜的功能,而且有更好的可讀性和移植性。2.1...