前言:
本帖是学习韦东山老师uboot教程,粗略总结的课堂笔记及自己感悟。如想深入了解uboot makefile,请绕路。
相关帖子:UBOOT初体验:编译、下载
uboot makefile主要包括两部分:配置编译参数;编译
1- make 100ask24x0_config 配置makefile编译环境
在makefile中搜索100ask24x0_config
SRCTREE := $(CURDIR)
MKCONFIG := $(SRCTREE)/mkconfig
100ask24x0_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
展开后为:
100ask24x0_config : unconfig
mkconfig 100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0
即执行当前路径下的脚本文件mkconfig,
入参为100ask24x0 arm arm920t 100ask24x0 NULL s3c24x0。
这个脚本文件是生成两个配置文件:./include/config.mk; ./include/config.h
#config.mk
ARCH = arm
CPU = arm920t
BOARD = 100ask24x0
SOC = s3c24x0
# config.h
/* Automatically generated - do not edit */
#include <configs/100ask24x0.h>
这两个文件指定了硬件架构为ARM,单板名字等
除了生成配置文件,mkconfig脚本还创建了一些软连接。
2- make 编译uboot
指定交叉编译工具链: 这里我们已经在./include/config.mk定义过了ARCH=arm
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
指定OBJ
OBJS = cpu/$(CPU)/start.o
OBJS := $(addprefix $(obj),$(OBJS))
指定LIB
LIBS = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
...
第一个目标 all:
ALL = $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
all: $(ALL)
$(obj)u-boot.hex: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@
$(obj)u-boot.srec: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
$(obj)u-boot.bin: $(obj)u-boot
$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
$(obj)u-boot.img: $(obj)u-boot.bin
./tools/mkimage -A $(ARCH) -T firmware -C none \
-a $(TEXT_BASE) -e 0 \
-n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
-d $< $@
$(obj)u-boot.dis: $(obj)u-boot
$(OBJDUMP) -d $< > $@
$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
这里我们关注下, 用于连接不同的目标文件生成uboot.bin
$(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
这里变量太多,我们直接看make的执行结果如下:
UNDEF_SYM=`arm-linux-objdump -x lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a |sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd /home/lhk/2440_learn/uboot/uboot_new/u-boot-1.1.6 && arm-linux-ld -Bstatic -T /home/lhk/2440_learn/uboot/uboot_new/u-boot-1.1.6/board/100ask24x0/u-boot.lds -Ttext 0x33F80000 $UNDEF_SYM cpu/arm920t/start.o \
--start-group lib_generic/libgeneric.a board/100ask24x0/lib100ask24x0.a cpu/arm920t/libarm920t.a cpu/arm920t/s3c24x0/libs3c24x0.a lib_arm/libarm.a fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a net/libnet.a disk/libdisk.a rtc/librtc.a dtt/libdtt.a drivers/libdrivers.a drivers/nand/libnand.a drivers/nand_legacy/libnand_legacy.a drivers/usb/libusb.a drivers/sk98lin/libsk98lin.a common/libcommon.a --end-group \
-Map u-boot.map -o u-boot
从打印可以获取到连接脚本为:
/home/lhk/2440_learn/uboot/uboot_new/u-boot-1.1.6/board/100ask24x0/u-boot.lds
链接地址为:
-Ttext 0x33F80000
第一个链接文件为:
cpu/arm920t/start.o #cpu/arm920t/start.S
3- 链接地址
3.1- uboot链接起始地址如何设置
韦东山的flash是64M的,flash起始地址为0x3000 0000, 结束地址为0x3FFF FFFF.
我们设置存放Uboot.bin的起始地址为0x33F8 0000. 结束地址为0x3FFF FFFF。即预留512KB大小。
参考:在flash上对地址寻址怎么看?_u010743406的博客-CSDN博客
如果我们的uboot小于512kb,可以将uboot的连接地址设置高于0x33F8 0000;反之可以设置低于0x33F8 0000地址。
这里我们编译出的uboot.bin只有194k,将uboot.bin连接起始地址设置在0x33F8 0000(预留512k给uboot使用)满足要求。
ls -lh u-boot.bin
-rwxr-xr-x 1 root root 194K 1月 21 22:50 u-boot.bin
3.2- uboot起始链接地址在哪里设置
在board/100ask24x0/config.mk中设置
#grep "0x33F80000" * -nR
board/100ask24x0/config.mk:25:TEXT_BASE = 0x33F80000
config.mk使用TEXT_BASE变量:
# grep "TEXT_BASE" * -nR
config.mk:189:LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
3.3- 连接脚本里有什么
我们通过上面可知uboot的连接脚本为:board/100ask24x0/u-boot.lds
连接脚本全文见后面。
指定起始地址
这里的0000 0000 对应链接地址0x33F8 0000
SECTIONS
{
. = 0x00000000;
}
指定代码段
代码段从0x33F8 0000开始放,第一个文件为cpu/arm920t/start.o(其源文件为cpu/arm920t/start.S),第二个文件为board/100ask24x0/boot_init.o(其源文件为board/100ask24x0/boot_init.c),之后存放其他所有的代码段
.text :
{
cpu/arm920t/start.o (.text)
board/100ask24x0/boot_init.o (.text)
*(.text)
}
存放只读数据
.rodata : { *(.rodata) }
存放data数据
.data : { *(.data) }
存放got?
.got : { *(.got) }
存放uboot调试命令
. = .;
__u_boot_cmd_start = .;
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
存放bss段
. = ALIGN(4);
__bss_start = .;
.bss : { *(.bss) }
_end = .;
连接脚本原文:
#board/100ask24x0/u-boot.lds
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
cpu/arm920t/start.o (.text)
board/100ask24x0/boot_init.o (.text)
*(.text)
}
. = ALIGN(4);
.rodata : { *(.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 : { *(.bss) }
_end = .;
}