mini2440系統(tǒng)移植篇之u-boot分析
1.Bootloader概念
系統(tǒng)上電后,需要一段程序來初始化重要的硬件,有些程序是固化在固件firmwware上的,如PC的BIOS。然后是Bootloader,如PC上的GRUB。對于嵌入式系統(tǒng)來說,一般只有Bootloader,它負責初始化內(nèi)核運行的硬件環(huán)境,如內(nèi)存,然后調(diào)用操作系統(tǒng)內(nèi)核。一般最終產(chǎn)品它只需要啟動內(nèi)核就足夠了,為了方便開發(fā),還可以增強Bootloader功能,比如網(wǎng)絡(luò)功能,通過網(wǎng)絡(luò)下載文件,燒寫文件到Flash中。
2.嵌入式系統(tǒng)結(jié)構(gòu)
嵌入式系統(tǒng)一般包含4部分。
1、引導(dǎo)加載程序,包括固化在固件的boot代碼(可選)和Bootloader。
2、Linux內(nèi)核
3、文件系統(tǒng),包括根文件系統(tǒng)和其他掛載的文件系統(tǒng)。從某方面說,Android也屬于嵌入式,只是它的文件系統(tǒng)比較龐大,比QT漂亮而已。
4、用戶應(yīng)用程序,就是如計數(shù)器之類的應(yīng)用。
3.U-Boot
U-Boot全稱UniversalBootLoader,即通用Bootloader。確實,現(xiàn)在很多公司的bootloader都采用u-boot,基本上成為標準。u-boot可以看成是一個大型的裸機程序,它的優(yōu)點是集成了很多好用的工具,命令,支持很多平臺。
4.U-Boot配置
4.1.Makefile
u-boot要經(jīng)過配置、編譯、連接過程。先說配置,從readme文件可以知道,要使用開發(fā)板board/
hyq2440_config:unconfig
@$(MKCONFIG)$(@:_config=)armarm920thyq2440samsungs3c24x0
unconfig是一些清理事情,不重要,根據(jù)makefile目標依賴命令的原理,分析一下@$(MKCONFIG)$(@:_config=)armarm920thyq2440samsungs3c24x0
做了什么事情。makefile的前面定義了MKCONFIG:=$(SRCTREE)/mkconfig,STRTREE就是當前目錄,所以MKCONFIG就是源碼根目錄下的mkconfig。$(@:_config=)展開就是hyq2440_config。所以就變成
mkconfighyq2440armarm920thyq2440samsungs3c24x0
$0$1$2$3$4$5$6
4.2.mkconfig
進入mkconfig看看干了什么事情。
4.2.1.確定開發(fā)板名稱BOARD_NAME
["${BOARD_NAME}"]||BOARD_NAME="$1"。定義了BOARD_NAME=hyq2440。
4.2.2.創(chuàng)建平臺相關(guān)的頭文件鏈接
ln-s${SRCTREE}/include/asm-$2asm。創(chuàng)建鏈接ln-sasm-armasm。
ln-s${LNPREFIX}arch-$6asm-$2/arch。創(chuàng)建鏈接ln-sarch-s3c24x0asm-arm/arch
4.2.3.創(chuàng)建頂層makefile包含的文件include/config.mk
echo"ARCH=$2">config.mk
echo"CPU=$3">>config.mk
echo"BOARD=$4">>config.mk
則config.mk配置文件內(nèi)容為:
ARCH=arm
CPU=arm920t
BOARD=hyq2440
VENDOR=samsung
SOC=s3c24x0
4.2.4.創(chuàng)建開發(fā)板相關(guān)頭文件config.h
echo"#include
echo"#include">>config.h
>config.h表示新建文件
/*Automaticallygenerated-donotedit*/
#include
#include
從配置中可以知道,如果在board新建一個開發(fā)板
4.3.配置文件
1、這個文件主要用來定制u-boot的功能,比如:
/*----------------------------------體系配置----------------------------------*/
#defineCONFIG_ARM920T 1 /*ThisisanARM920TCore */
#define CONFIG_S3C2440 1 /*inaSAMSUNGS3C2440SoC*/
#define CONFIG_HYQ2440 1 /*inaHYQ2440Board*/
/*---------------------------------內(nèi)存配置--------------------------------------*/
#defineCONFIG_NR_DRAM_BANKS 1 /*wehave1bankofDRAM*/
#definePHYS_SDRAM_1 0x30000000/*SDRAMBank#1*/
#definePHYS_SDRAM_1_SIZE 0x04000000/*64MB*/
/*--------------------------------NorFlash驅(qū)動配置-----------------------------*/
#definePHYS_FLASH_1 0x00000000/*FlashBank#1*/
#defineCONFIG_SYS_FLASH_BASE PHYS_FLASH_1
#defineCONFIG_SYS_MAX_FLASH_BANKS 1 /*maxnumberofmemorybanks*/
#defineCONFIG_AMD_LV160B 1
#definePHYS_FLASH_SIZE 0x00200000/*2MB*/
#defineCONFIG_SYS_MAX_FLASH_SECT (35) /*maxnumberofsectorsononechip*/
#defineCONFIG_SYS_FLASH_ERASE_TOUT (5*CONFIG_SYS_HZ)/*TimeoutforFlashErase*/
#defineCONFIG_SYS_FLASH_WRITE_TOUT (5*CONFIG_SYS_HZ)/*TimeoutforFlashWrite*/
需要哪些代碼有效,就開啟響應(yīng)的宏。
5.U-Boot編譯鏈接
先編譯u-boot,從編譯的log反過來看u-boot編譯鏈接過程。
cd/home/share/hyq-u-boot-2009.11/trunk/hyq-u-boot
&&
arm-linux-ld-Bstatic-Tu-boot.lds-Ttext0x33f80000
$UNDEF_SYMcpu/arm920t/start.o
--start-group
lib_generic/libgeneric.a
lib_generic/lzma/liblzma.a
lib_generic/lzo/liblzo.a
cpu/arm920t/libarm920t.a
cpu/arm920t/s3c24x0/libs3c24x0.a
lib_arm/libarm.afs/cramfs/libcramfs.a
fs/fat/libfat.afs/fdos/libfdos.a
fs/jffs2/libjffs2.a
fs/reiserfs/libreiserfs.a
fs/ext2/libext2fs.a
fs/yaffs2/libyaffs2.a
fs/ubifs/libubifs.a
net/libnet.a
disk/libdisk.a
drivers/bios_emulator/libatibiosemu.a
drivers/block/libblock.a
drivers/dma/libdma.a
drivers/fpga/libfpga.a
drivers/gpio/libgpio.a
drivers/hwmon/libhwmon.a
drivers/i2c/libi2c.a
drivers/input/libinput.a
drivers/misc/libmisc.a
drivers/mmc/libmmc.adrivers/mtd/libmtd.a
drivers/mtd/nand/libnand.a
drivers/mtd/onenand/libonenand.a
drivers/mtd/ubi/libubi.a
drivers/mtd/spi/libspi_flash.a
drivers/net/libnet.a
drivers/net/phy/libphy.a
drivers/net/sk98lin/libsk98lin.a
drivers/pci/libpci.a
drivers/pcmcia/libpcmcia.a
drivers/power/libpower.a
drivers/spi/libspi.a
drivers/rtc/librtc.a
drivers/serial/libserial.a
drivers/twserial/libtws.a
drivers/usb/gadget/libusb_gadget.a
drivers/usb/host/libusb_host.a
drivers/usb/musb/libusb_musb.a
drivers/usb/slave/libusb_slave.a
drivers/video/libvideo.a
drivers/watchdog/libwatchdog.a
common/libcommon.a
libfdt/libfdt.a
api/libapi.a
post/libpost.a
board/samsung/hyq2440/libhyq2440.a
--end-group/home/share/hyq-u-boot-2009.11/trunk/hyq-u-boot/lib_arm/eabi_compat.o
-L/usr/local/arm/4.3.2/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.2/armv4t
-lgcc-Mapu-boot.map-ou-boot
arm-linux-objcopy-Osrecu-bootu-boot.srec
arm-linux-objcopy--gap-fill=0xff-Obinaryu-bootu-boot.bin
從編譯log看出,使用鏈接腳本u-boot.lds來編譯,最后生成的起始地址是0x33f80000,把各個平臺和驅(qū)動下面的libxxx.a鏈接進來,最后生成u-boot.bin二進制文件。鏈接腳本對應(yīng)的是cpu體系下各自的u-boot.lds,
5.1.鏈接腳本
SECTIONS
{
.=0x00000000;
.=ALIGN(4);
.text:
{
cpu/arm920t/start.o (.text)
board/samsung/hyq2440/lowlevel_init.o (.text)
board/samsung/hyq2440/nand_read.o (.text)
*(.text)
}
.=ALIGN(4);
.rodata:{*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))}
.=ALIGN(4);
.data:{*(.data)}
.=ALIGN(4);
.got:{*(.got)}
.=.;
__u_boot_cmd_start=.;
.u_boot_cmd:{*(.u_boot_cmd)}
__u_boot_cmd_end=.;
.=ALIGN(4);
__bss_start=.;
.bss(NOLOAD):{*(.bss).=ALIGN(4);}
_end=.;
}
鏈接腳本指定鏡像中代碼段text,只讀數(shù)據(jù)段rodata,全局初始化數(shù)據(jù)區(qū)data,u-boot命令和全局未初始化數(shù)據(jù)區(qū)bss的排列位置。并且知道,第一段代碼是cpu/arm920t/start.o,對應(yīng)目錄下的匯編文件start.S。