國嵌Linux視頻Uboot


1.1 BootLoader介紹

什麼是BootLoader?

軟件層次

一個嵌入式系統從軟件角度來看分爲三個層次:

1. 引導加載程序

包括固化在固件(firmware)中的 boot 程序(可選),和 BootLoader 兩大部分。

2. Linux 內核

特定於嵌入式平臺的定製內核。

3. 文件系統

包括了系統命令和應用程序。

一個同時裝有 BootLoader、內核的啓動參數、內核映像和根文件系統映像的固態存儲設備的典型空間分配結構圖:

PC機中的引導加載程序由BIOS(其本質是一段固件程序)和

GRUB或LILO一起組成。BIOS在完成硬件檢測和資源分配後,將硬盤中的引導程序讀到系統內存中然後將控制權交給引導程序。引導程序的主要任務是將內核從硬盤上讀到內存中,然後跳轉到內核的入口點去運行,即啓動操作系統。

定義

在嵌入式系統中,通常沒有像BIOS那樣的固件程序,因此整個系統的加載啓動任務就完全由BootLoader來完成。比如在一個基

於 ARM7TDMI core的嵌入式系統中,系統在上電或復位時都從地址 0x00000000開始執行。而在這個地址處安排的通常就是系統的BootLoader程序。

簡單地說,BootLoader就是在操作系統運行之前運行的一段小程序。通過這段小程序,可以初始化硬件設備,從而將系統的軟硬件環境帶到一個合適的狀態,以便爲最終調用操作系統做好準備。

安裝

系統加電或復位後,所有的CPU通常都從CPU製造商預先安排地址開始執行。比如,S3C2410在復位後從地址0x00000000起開始執行。而嵌入式系統則將固態存儲設備(比如:FLASH)安排在這個地址上,而bootloader程序又安排在固態存儲器的最前端,這樣就能保證在系統加電後,CPU首先執行BootLoader程序。

爲什麼需要進行bootloader移植?

每種不同的CPU體系結構都有不同的BootLoader。除了依賴於CPU的體系結構外,BootLoader 還依賴於具體的嵌入式板級設備的配置,比如板卡的硬件地址分配,外設芯片的類型等。這也就是說,對於兩塊不同的開發板而言,即使它們是基於同一種CPU而構建的,但如果他們的硬件資源或配置不一致的話,要想在一塊開發板上運行的BootLoader程序也能在另一塊板子上運行,還是需要作修改。

流程

BootLoader 的啓動過程可分爲單階段(Single-Stage)和多階段(Multi-Stage)兩種,通常多階段的 BootLoader 具有更復雜的功能,更好的可移植性。從固態存儲設備上啓動的BootLoader 大多采用兩階段,即啓動過程可以分爲 stage 1和 stage2;stage1完成初始化硬件,爲stage2準備內存空間,並將stage2複製到內存中,設置堆棧,然後跳轉到stage2。

BootLoader 的 stage1 通常包括以下步驟:

·硬件設備初始化

·爲加載 BootLoader 的 stage2 準備 RAM 空間

·拷貝 BootLoader 的 stage2 到 RAM 空間中

·設置好堆棧(why??)

·跳轉到 stage2 的 C 入口點

BootLoader 的 stage2 通常包括以下步驟:

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

·將內核映像和根文件系統映像從 flash 上讀到RAM 中

·調用內核

內存分佈

1.2 Uboot介紹

作用

Uboot是德國DENX小組開發的用於多種嵌入式CPU( MIPS、x86、ARM、XScale等)的bootloader程序,UBoot不僅支持嵌入式Linux系統的引導,還支持VxWorks, QNX等多種嵌入式操作系統。

下載

從下面地址可以下載到uboot的源代碼:

ftp://ftp.denx.de/pub/u-boot/

目錄結構

進入到UBOOT目錄,可以得到如下的目錄結構:

|­­ board

|­­ common

|­­ cpu

|­­ disk

|­­ doc

|­­ drivers

|­­ dtt

|­­ examples

|­­ fs

|­­ include

|­­ lib_arm

|­­ lib_generic

|­­ lib_i386

|­­ lib_m68k

|­­ lib_microblaze

|­­ lib_mips

|­­ lib_nios

|­­ lib_nios2

|­­ lib_ppc

|­­ net

|­­ post

|­­ rtc

|­­ tools

Board

和開發板有關的文件。每一個開發板都以一個子目錄出現在當

前目錄中,比如:SMDK2410,子目錄中存放與開發板相關的文

件。

Common

實現Uboot支持的命令。

Cpu

與特定CPU架構相關的代碼,每一款Uboot下支持的CPU在該

目錄下對應一個子目錄,比如有子目錄arm920t等。

Disk

對磁盤的支持。

Doc

文檔目錄。Uboot有非常完善的文檔,推薦大家參考閱讀。

Drivers

Uboot支持的設備驅動程序都放在該目錄,比如各種網卡、

支持CFI的Flash、串口和USB等。

Fs

文件系統的支持。

Include

Uboot使用的頭文件。該目錄下configs目錄有與開發板相關的配置頭文件,如smdk2410.h。該目錄下的asm目錄有與CPU體系結構相關的頭文件。

Net

與網絡協議棧相關的代碼,例如:TFTP協議、RARP協議的實現。

Tools

生成Uboot的工具,如:mkimage, crc等等。

編譯

Uboot的Makefile從功能上可以分成兩個

部分:

1、執行每種board相關的配置

2、編譯生成uboot.bin文件

Uboot.bin的生成也分爲兩步,以smdk2410爲例來說明,如下:

1. 選擇要使用的board:

$makesmdk2410_config

2. 編譯生成u-boot.bin:

$makeCROSS_COMPILE=arm-linux-

1.3 Uboot命令

常用命令

儘管UBOOT提供了豐富的命令集,但不同的單板所支持的命令並不一定一樣(可配置,How?後面章節),help 命令可用於察看當前單板所支持的命令。

【2410】 # help

autoscr -run scriptfrom memory

base -print or setaddress offset

bdinfo -print BoardInfo structure

bootm -bootapplication image from memory

環境變量相關

printenv 查看環境變量

usage:

printenv

- print values ofall environment variables

printenv name ...

- print value ofenvironment variable 'name'

Uboot> printenv

ipaddr=192.168.1.1

ethaddr=12:34:56:78:9A:BC

serverip=192.168.1.5

setenv 添加、修改、刪除環境變量

setenv name value...

- set environmentvariable 'name' to 'value ...‘

setenv name

- delete environmentvariable 'name'

Uboot> setenvmyboard AT91RM9200DK

Uboot> printenv

serverip=192.168.1.5

myboard=AT91RM9200DK

saveenv 保存環境變量

將當前定義的所有變量及其值存入flash中。

文件下載

tftp 通過網絡下載文件

注意:使用tftp,需要先配置好網絡

Uboot> setenv ethaddr12:34:56:78:9A:BC

Uboot> setenvipaddr 192.168.1.1

Uboot> setenvserverip 192.168.1.254 (tftp服務器的地址)

例:

Uboot> tftp32000000 uImage

把server(IP=環境變量中設置的serverip)中服務目錄 下的

uImage通過TFTP讀入到0x32000000處。

內存操作

md(memory display) 顯示內存區的內容。

md採用十六進制和ASCII碼兩種形式來顯示存儲單元的內容。

這條命令還可以採用長度標識符 .l, .w和.b :

md [.b, .w, .l]address

md.w 100000

00100000: 2705 19565050 4342 6f6f 7420 312e 312e

00100010: 3520 284d6172 2032 3120 3230 3032 202d

mm(memory modify) 修改內存,地址自動遞增。

mm [.b, .w, .l]address

mm 提供了一種互動修改存儲器內容的方法。它會顯示地址和當前值,然後提示用戶輸入。如果你輸入了一個合法的十六進制數,

這個新的值將會被寫入該地址。然後提示下一個地址。如果你沒

有輸入任何值,只是按了一下回車,那麼該地址的內容保持不

變。如果想結束輸入,則輸入空格,然後回車。

=> mm 100000

00100000: 27051956 ?0

00100004: 50504342 ?AABBCCDD

Flash操作

flinfo 查看Flash扇區信息

Usage:Uboot>flinfo

protect Flash寫保護

打開或關閉扇區寫保護

用法:

protect off all

關閉所有扇區的寫保護

protect on all

打開所有扇區的寫保護

protect off startend

關閉從start 到 end 扇區的寫保護(start爲要關閉的第1個扇區的起始

地址,end爲要關閉的最後一個扇區的結束地址)

protect on start end

打開從start 到 end 扇區的寫保護

erase 擦除flash扇區

用法: erase start end

擦除從start 到 end 的扇區,start 爲要擦除的第1個扇區的起始地址,end 爲要擦除的最後一個扇區的結束地址(在使用cp命令向Nor型Flash寫入數據之前必須先使用erase 命令擦除flash,因爲

nor flash 按字節寫入時,無法寫入1,所以必須通過擦除來寫入1)。

例:erase 30000 1effff

cp 數據拷貝。

cp [.b, .w, .l]saddress daddress len

cp 提供了一種內存與內存,內存與Flash之間數據拷貝的方法。

例:

cp.b 31000000 50000d0000

將內存地址0x31000000處的數據(長度爲0xd0000)拷貝到

地址0x50000處(Flash中)

cp.b 32000000 120000c0000

將內存地址0x32000000處的數據(長度爲0xc0000)拷貝到

地址0x120000處(Flash中)

執行程序

go 執行內存中的二進制代碼,一個簡單的跳轉到指定地址

go addr [arg ...]

- start applicationat address 'addr‘,

passing 'arg' asarguments

bootm 執行內存中的二進制代碼

bootm [addr [arg...]]

- boot applicationimage stored in memory

passing arguments'arg ...'; when booting a Linux kernel, 'arg' can be the address of an initrdimage

要求二進制代碼有固定格式的文件頭。

開發板信息

bdinfo – 顯示開發板信息

bdinfo命令(簡寫爲bdi)將在終端顯示諸如內存地址和大小、時鐘頻率、MAC地址等信息。這些信息在傳遞給Linux內核一些

參數時可能會用到。

自動啓動

1. 設置自動啓動

bootdelay時間內未打斷自啓動則開始執行bootcmd裏的命令

mini2440=>setenvbootcmd tftp

31000000 uImage \;bootm 31000000

mini2440=>saveenv

1.4 Uboot工作流程

工作模式

大多數BootLoader都包含兩種不同的操作模式:“啓動模式” 和“下載模式”,這種區別僅對於開發人員纔有意義,但從最終用戶

的角度看,BootLoader的作用就是用來加載操作系統,而不存在所謂的啓動模式與下載模式。

啓動模式

這種模式也稱爲“自主” 模式,是指BootLoader 從目標機上的某個固態存儲設備上將操作系統自動加載到 RAM 中運行,整個過程並沒有用戶的介入。這種模式是BootLoader 的正常工作模式,因此在嵌入式產品發佈的時侯,BootLoader 顯然必須工作在這種模式下。

下載模式

在這種模式下,目標機上的BootLoader 將通過串口或網絡等通

信手段從主機(Host)下載文件 ,然後控制啓動流程。

代碼導讀

參考文檔《uboot啓動流程》

1.5 Uboot移植

爲什麼需要對Uboot進行移植?

BootLoader 依賴於:

具體的CPU體系、具體的板級設備配置

(芯片級移植、板級移植)

具體的板級設備的配置在哪裏?

板級設備的配置文件位於

include/configs/<board_name>.h

<board_name>用相應的BOARD定義代替(例:smdk2410.h)

Smdk2410.h

#defineCONFIG_ARM920T 1

/* CPU 類型 */

#define CONFIG_S3C24101

/* MCU類型 */

#defineCONFIG_SMDK2410 1

/* 開發板型號 */

#define USE_920T_MMU1

/* 使用MMU */

#undefCONFIG_USE_IRQ

/* 不使用 IRQ/FIQ */

/* malloc 池大小*/

#defineCFG_MALLOC_LEN (CFG_ENV_SIZE +

128*1024)

/* 數據段大小 128字節 */

#defineCFG_GBL_DATA_SIZE 128

/* 使用 CS8900 網卡 */

#defineCONFIG_DRIVER_CS8900 1

/* CS8900A 基地址 */

#define CS8900_BASE0x19000300

/* 使用串口1 */

#defineCONFIG_SERIAL1 1

/* 波特率 */

#defineCONFIG_BAUDRATE 115200

#defineCONFIG_COMMANDS \

(CONFIG_CMD_DFL |\

CFG_CMD_CACHE |\

/*CFG_CMD_NAND |*/ \

/*CFG_CMD_EEPROM |*/\

/*CFG_CMD_I2C |*/ \

/*CFG_CMD_USB |*/ \

CFG_CMD_REGINFO | \

CFG_CMD_DATE

|\

CFG_CMD_ELF)

/*定義使用的命令,可添加額外命令,如PING*/

/* 自動啓動等待時間 */

#defineCONFIG_BOOTDELAY 3

/* 內核啓動參數 */

#defineCONFIG_BOOTARGS

"root=ramfsdevfs=mount console=ttySA0,9600“

#defineCONFIG_ETHADDR 08:00:3e:26:0a:5b

#defineCONFIG_NETMASK 255.255.255.0

#defineCONFIG_IPADDR 10.0.0.110

#defineCONFIG_SERVERIP 10.0.0.1

#defineCONFIG_BOOTCOMMAND "tftp; bootm"

#define CFG_PROMPT"SMDK2410 # "

#define PHYS_SDRAM_10x30000000 /* SDRAM Bank #1 */

#definePHYS_SDRAM_1_SIZE 0x04000000 /* 64 MB */

#defineCFG_LOAD_ADDR 0x33000000

/* 默認的啓動地址 */

#defineCFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600,115200 } /*可用的波特率*/

/* 有一片SDRAM */

#defineCONFIG_NR_DRAM_BANKS 1

/* FLASH No1的基地址 */

#define PHYS_FLASH_10x00000000

/* FLASH 的基地址 */

#defineCFG_FLASH_BASE

PHYS_FLASH_1

移植

開始移植之前,首先要分析U-Boot已經支持的開發板,選擇出硬件配置最接近的開發板。選擇的原則是,首先選擇MCU相同的開發板,如果沒有,則選擇MPU相同的開發板。

以mini2440開發板爲例,該開發板採用s3c2440芯片。根據選擇原則,首先選擇MCU爲s3c2440的開發板,但 UBoot 各版本均不支持採用s3c2440芯片的開發板。因此根據第二原則,選擇MPU相同,即ARM核爲arm920T的開發板,Uboot支持SMDK2410開發板,並且SMDK2410採用s3c2410芯片,s3c2410採用的正好是arm920T,因此選取SMDK2410開發板作爲移植參考板。

移植U-Boot的基本步驟如下:

1.在頂層Makefile中爲開發板添加新的配置選項,使用已有的

配置項目爲例

smdk2410_config :

unconfig @./mkconfig$(@:_config=) arm arm920t smdk2410 NULL s3c24x0

參考上面2行,添加下面2行:

mini2440_config :

unconfig

@./mkconfig$(@:_config=) arm arm920t mini2440 NULL s3c24x0

arm: CPU 架構

arm920t: CPU 類型,對應cpu/arm920t目錄

mini2440: 開發板型號,對應board/mini2440目錄

NULL:開發者

s3c24x0: 片上系統(SOC)

2. 在board目錄中創建一個屬於新開發板的目錄,並添加文件:

mkdir –pboard/mini2440

cp –rfboard/smdk2410/* board/mini2440

3. 爲開發板添加新的配置文件

先複製參考開發板的配置文件,再修改。例如:

$cpinclude/configs/smdk2410.h include/configs/mini2440.h

4. 選擇板級配置

$ makemini2440_config

5. 編譯U-Boot

執行make CROSS_COMPILE=arm-linux- 命令,編譯成功可以得到U-Boot映像。

6.燒寫Uboot

 

 

發佈了21 篇原創文章 · 獲贊 2 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章