文章目录
U-Boot初体验
U-Boot-1.1.6中有几千个文件,要想了解对于某一款开发板,使用那些文件、那些文件首先执行、可执行文件占用内存情况,最好的办法就是阅读它的makefile
内容很长,大家可以自己下载下来读,但是可以先把博客阅读完,找对方法阅读,效果更好。
根据顶层Readme文件的说明,可以直到如果要使用开发板board/< board_name >,就先执行"make < board_name>_config"命令进行配置,然后执行"make all",就可以生成如下三个文件:(内容太长了,抱歉我没找到在源文件那些说明的,后面找到了会回来补上)
- U-Boot.bin:二进制可执行文件,它就是可以直接烧入ROM,NOR Flash的文件
- U-Boot:ELF格式的可执行文件。
- U-Boot.srec:Motorola S-Record格式的可执行文件。
对于S3C2410的开发板,执行"make smdk2410_config"、"make all"后生成的U-Boot.bin可以烧入NOR Flash中运行。启动后可以看到串口输出一些信息后进入控制界面。等待用户的输入。
对于S3C2440的开发板,烧入上面生成的U-Boot.bin,串口无输出,需要修改代码。在修改代码之前,先看看上面两个命令、“make smd2410_config” 、"make all"做了什么事情,以了解程序的流程,知道需要修改那些文件。
另外,编译U-Boot成功后,还会在它的tools子目录下生成一些工具,比如mkimage等。将他们复制到/usr/local/bin目录下。以后就可以直接使用他们了。比如编译内核时,会使用mkimage来生成U-Boot格式的内核映象文件uIimage。
(大家先理解,后面实操一定发一篇详细的博客)
U-Boot的配置过程
在顶层Makefile中可以看到如下代码:
SRCTREE := $(CURDIR)
......
MKCONFIG := $(SRCTREE)/mkconfig
......
smdk2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
都是可以找到的。
假定在U-Boot-1.1.6的根目录下编译,则其中的MKCONFIG就是根目录下的mkconfig文件
$(@:_config=)的结果就是将“smdk2410_config”中的“_confug”给去掉,结果为“smdk2410”。所以“make smdk2410_config”实际上就是执行如下命令:
./mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0
再来看看mkconfig的作用,再mkconfig文件开头第六行给出了它的作用
对于S3C2410,S3C2440,它们被称为SoC(System on Chip,片上系统)。上面除了CPU外,还集成了包括UART,USB控制器、NAND Flash控制器等设备(称为片内外设)。S3C2410中的CPU为ARM920T。
下面分步分析mkconfig的作用
确定开发板名称BOARD_NAME,代码如下
APPEND=no # Default: Create new config file
BOARD_NAME="" # Name to print in make output
while [ $# -gt 0 ] ; do
case "$1" in
--) shift ; break ;;
-a) shift ; APPEND=yes ;;
-n) shift ; BOARD_NAME="${1%%_config}" ; shift ;;
*) break ;;
esac
done
[ "${BOARD_NAME}" ] || BOARD_NAME="$1"
分析:
创建到平台/开发板相关的头文件的链接
略过mkconfig文件中的一些没有起作用的行,如下所示
#
# Create link to architecture specific headers
#
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
cd ./include
rm -f asm
ln -s asm-$2 asm
fi
分析:
继续往下看代码
rm -f asm-$2/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
if [ "$2" = "arm" ] ; then
rm -f asm-$2/proc
ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi
创建顶层Makefile包含文件include/config.mk,如下
#
# Create include file for Make
#
echo "ARCH = $2" > config.mk
echo "CPU = $3" >> config.mk
echo "BOARD = $4" >> config.mk
[ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk
[ "$6" ] && [ "$6" != "NULL" ] && echo "SOC = $6" >> config.mk
创建开发板相关头文件include/config.h,如下
#
# Create board specific header file
#
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 <configs/$1.h>" >>config.h
exit 0
现在总结以下,配置指令“make smdk2410_config”,实际作用就是执行"./mkconfig smdk2410 arm arm920t NULL s3c24x0"命令,.假设执行“/mkconfig $1 $2 $3 $4 $5 $6”命令,则产生如下结果。
- 开发板名称BOARD_NAME等于$1.
- 创建到平台/开发板相关头文件链接,如下所示:
ln -s asm_$2 asm
ln -s arch-$6 asm-$2/arch
ln -s proc-armv asm-$2/proc #如果$2不是arm的话,此行没有
- 创建顶层Makefile包含文件include/config.mk,如下所示
ARCH =$2
CPU=$3
BOARD=$4
VENDOR=$5 #$5为空,或者是NULL的话,此行没有
SOC=$6 #$6为空,或者是NULL的话,此行没有
- 创建开发板相关的头文件include/config.h,如下所示
/* Automatically generated - do not edit*/
#include <configs/$1.h>
从这4个结果可以知道,如果要在board目录下新建一个开发板< board_name >的目录,则在include/configs 目录下也建立一个文件< board_name>.h,里面存放地就是开发板< board_name>的配置信息。
实际操做展示
打开这个目录,查看文件如下
查看smdk2410的配置信息,include/configs下的smdk2410.h
(大家别慌,下面就来分析这个文件。)
开发板配置信息文件分析
U-Boot还没有类似Linux一样的可视化配置界面(比如使用 make menuconfig来配置),要手动修饰配置文件include/configs/< board_name>.h来裁减、设置U-Boot。
配置文件中有以下两类宏。
第一项OPTIONS
第一类是选项(Options),前缀为“CONFIG_”,它们用于选择CPU、SOC、开发板类型,设置系统时钟、选择驱动设备等。比如:
第二项:Setting
参数(Setting),前缀为"GFG_",它们用于设置malloc缓冲池的大小、U-Boot的提示符、U-Boot下载文件时的默认加载地址、Flash的起始地址等。如下
(我这里好像和书籍上略微不一样,在U-Boot的提示符这,书籍与100ASK(韦东山老师的个人平台)有关。)
从下一篇博客会分析的U-Boot的编译和链接过程可知,U-Boot中几乎每个文件都被编译和链接,但是这些文件是否包含有效的代码,则由宏开关来设置,比如网卡驱动drivers/cs8900.c,它的格式为:
意思就是如果定义了宏CONFIG_DRIVER_CS8900,则文件中包含有效代码;否则,文件被注释为空。
可以这样认为,“CONFIG_”除了设置一些参数外,主要用来设置U-Boot的功能,选择使用文件中的那一部分;而"CFG_"用来设置更细节的参数。
总结
U-Boot,Linux内核都是很庞然大物的工程,所以分析进度很慢,我也是已经分析好几天了,距离完成还有不少的距离。所以难得东西要慢慢得啃,相信这个过程完了以后,对计算机以及操做系统,Bootloader的理解会有本质的变化
贵在坚持!