Chinaunix首页 | 论坛 | 博客

OS

  • 博客访问: 2280396
  • 博文数量: 691
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2660
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-05 12:49
个人简介

不浮躁

文章分类

全部博文(691)

文章存档

2019年(1)

2017年(12)

2016年(99)

2015年(207)

2014年(372)

分类: 嵌入式

2015-12-11 21:48:51

现在介绍一下u-boot 的编译过程,这里用的uboot 版本是U-Boot 2010.10,硬
件用4412,这个板子用得比较普遍,uboot 已经有对其的支持。通过我们
对编译过程和代码的了解,我们也容易用uboot 支持我们自己需要的硬件。
编译命令非常简单:
make smdk2410_config (生成配置)
make all (生成最终文件)
当然,更好的做法是把编译出的文件生成到另外一个目录,并make clean 如:
export BUILD_DIR=../tmp
make distclean
make smdk2410_config
make all
现在,我们可以来看看Makefile,u-boot 的Makefile 文件非常大。但是,其结
构却并不复杂。
u-boot 已经支持了很多硬件,前半部分是共用部分,编译出最终的uboot 可执行
文件。
而后半部分,是为各种不同的硬件进行配置,每种硬件有一个目标,每个的做法
都非常类似,我们用到的是:
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
这里的 MKCONFIG := $(SRCTREE)/mkconfig
实际上是调用脚本mkconfig,而这个脚本做的工作简单如下:
建立include/config.mk 文件
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
echo "VENDOR = $5" >> config.mk
echo "SOC = $6" >> config.mk
建立include/config.h
echo "#include " >>config.h
在这里$1-$6 的值分别是:smdk2410 arm arm920t smdk2410 NULL s3c24x
0
而执行了 make smdk2410_config 之后,就生成了相应的config.mk,config.
h 两个文件。
在config.mk 文件中,定义了相应硬件信息 : ARCH CPU BOARD VENDO
R SOC
在config.h 文件中,包含了相应硬件的头文件smdk2410.h ,位于include\conf
igs 目录下。
如果新建自己的硬件项目,那么也需要建立相应的头文件在这个地方。
这样,uboot 的配置已经生成,下一次介绍make all 的过程。
接着上次,这次介绍make all 的过程。
首先,介绍一下生成的config.mk 和 config.h 如何使用,得到正确配置的。
config.mk 直接被include 到Makefile 来,并使用其定义如下:
include $(obj)include/config.mk
export ARCH CPU BOARD VENDOR SOC
这样可以直接选择需要编译的模块,例如:
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a
LIBS += lib_$(ARCH)/lib$(ARCH).a
LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a
config.h 被include/common.h 所包含,而它有包含了相应硬件的头文件。
common.h <--- config.h <--- smdk2410.h
除了在源程序中,使用这些头文件的定义之外,uboot 还有一个脚本通过解析c
ommon.h 以及其包含的所有头文件信息,来生成配置信息如下形式:
CONFIG_BAUDRATE=115200
CONFIG_NETMASK="255.255.255.0"
CONFIG_DRIVER_CS8900=y
CONFIG_ARM920T=y
CONFIG_RTC_S3C24X0=y
CONFIG_CMD_ELF=y
而头文件的定义的形式如下,对比可以看出脚本的工作原理。
#define CONFIG_BAUDRATE 115200
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_DRIVER_CS8900 1 /* we have a CS8900 on-bo
ard */
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_RTC_S3C24X0 1
#define CONFIG_CMD_ELF
通过这样,uboot 可以自动得到一个模块选择的配置功能。如果我们需要添加什
么定义或者功能,也可以在相应的头文件中加入定义实现。
现在,配置已经得到,就看最后的编译流程。
编译分为五大部分,分别如下:
1. $(SUBDIRS) 工具,例子等,包括目录:tools examples api_examples
2. $(OBJS) 启动模块 cpu/arm920t/start.o
3. $(LIBBOARD) 板子支持模块 board/smdk2410/libsmdk2410.a
4. $(LIBS) 其他模块,有诸如以下模块:
cpu/arm920t/libarm920t.a
cpu/arm920t/s3c24x0/libs3c24x0.a
lib_arm/libarm.a
fs/jffs2/libjffs2.a
fs/yaffs2/libyaffs2.a
net/libnet.a
disk/libdisk.a
drivers/bios_emulator/libatibiosemu.a
drivers/mtd/libmtd.a
drivers/net/libnet.a
drivers/net/phy/libphy.a
drivers/net/sk98lin/libsk98lin.a
drivers/pci/libpci.a
common/libcommon.a /
5. $(LDSCRIPT) 链接脚本
编译完成这五部分,链接成elf 格式的u-boot 文件,最后通过objcopy -O bina
ry 命令将elf 格式转换成为raw binary 格式的文件u-boot.bin 就可以烧到板子上
使用了。
mkconfig 文件的分析
http://niutao.org/blog/?p=50
在编译u-boot 之前都要执行”make XXX_config”命令,笼统的说是配置u-boot,使其编译出
适合目标板的bootloader。那么该命令都做了那些工作,具体的执行过程是怎样的?
我们首先从u-boot 的Makefile 文件看起,例如我们首先执行”make smd2410_config”
命令,则在Makefile 中会执行:
MKCONFIG := $(SRCTREE)/mkconfig
export MKCONFIG
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
也就是:
./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24×0
也就是说执行”make XXX_config”之后,实际上执行的是mkconfig 脚本,下面是对
mkconfig 文件的分析:
#!/bin/sh -e
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
#如果命令行参数中有--,-a,-n 等参数,则执行以下循环。
#如果有-n XXX_config 或者-n XXX,则取出XXX 作为目标板的名字
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
#如果传递给该脚本的参数小于4 个或者大于6 个,则退出
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
#如果BOARD_NAME 为空,则BOARD_NAME 等于传递给该脚本的第一个参数
[ $# -lt 4 ] && exit 1
[ $# -gt 6 ] && exit 1
echo "Configuring for ${BOARD_NAME} board..."
#OBJTREE 和SRCTREE 都是在Makefile 中导出的变量,分别为编译目录和源码目录
#如果编译目录和源码目录不为同一目录,则执行一下命令,创建$(OBJTREE)/include 等目录
if [ "$SRCTREE" != "$OBJTREE" ] ; then
mkdir -p ${OBJTREE}/include
mkdir -p ${OBJTREE}/include2
cd ${OBJTREE}/include2
rm -f asm
ln -s ${SRCTREE}/include/asm-$2 asm
LNPREFIX="../../include2/asm/"
cd ../include
rm -rf asm-$2
rm -f asm
mkdir asm-$2
ln -s asm-$2 asm
else
#如果编译目录和源码目录为同一个目录,则进入include 目录,删除旧的asm 链接,创建目
#标板到asm 的链接,例如如果目标体系结构为arm,则创建asm 软链接指向asm-arm。
cd ./include
rm -f asm
ln -s asm-$2 asm
fi
#删除目标平台下的旧的arch 链接
rm -f asm-$2/arch
#如果第6 个参数长度为0 或者其等于NULL,则创建arch-$3 到asm-$2 的链接,对于命令
#"./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0"
# $6=s3c24x0 不为空
# $3=arm920t $2=arm
#则最终执行的命令为"ln -s arch-s3c24x0 asm-arm/arch"
if [ -z "$6" -o "$6" = "NULL" ] ; then
ln -s ${LNPREFIX}arch-$3 asm-$2/arch
else
ln -s ${LNPREFIX}arch-$6 asm-$2/arch
fi
#如果目标平台为ARM,则删除建立的asm-arm 链接,重新建立从proc-armv 到asm-arm 的链接
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
#
# Create include file for Make
#
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
#如果参数5 存在并且不为NULL,则将VENDOR = $5 追加在config.mk 文件中
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
#如果参数6 存在并且不为NULL,则将SOC = $6 追加在config.mk 文件中
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
#创建config.h 文件
if [ "$APPEND" = "yes" ] # Append to existing config file
then
echo >> config.h
else
> config.h # Create new config file
fi
echo "/* Automatically generated - do not edit */" >>config.h
echo "#include " >>config.h
exit 0
总结一下,”make XXX_config”总共做了一下工作:
(1)确定开发板名称为BOARD_NAME = $1。
(2)创建一些链接文件,为编译u-boot 做准备:
ln -s asm-$2 asm
ln -s arch-$6 asm-$2/arch
ln -s proc-armv asm-$2/proc #仅在目标平台为arm 的时候才执行。
(3)创建顶层Makefile 包含的文件include/config.mk。
ARCH = $2
CPU = $3
BOARD = $4
VENDOR = $5
SOC = $6
(4)创建开发板相关的头文件include/config.h。
/* Automatically generated - do not edit */
#include
阅读(1675) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~