上篇文章地址:http://www.jyguagua.com/?p=1042
1:继续上次的分析,编译uboot需要执行如下两条命令:
make smdkv210single_config make
make smdkv210single_config在上文已经具体分析过了,这里不再分析,本篇重点分析make命令执行之后的结构
2:打开Makefile,我们逐行向下分析,我只贴出重要部分的内容,讲解也在其中注释中:
#查看include目录下是否有config.mk,上一篇博文我们讲了,这个include目录下是生成了config.mk文件的 #内容如下: #ARCH = arm #CPU = s5pc11x #BOARD = smdkc110 #VENDOR = samsung #SOC = s5pc110 ifeq ($(obj)include/config.mk,$(wildcard $(obj)include/config.mk)) # load ARCH, BOARD, and CPU configuration # 加载include/config.mk文件 include $(obj)include/config.mk #将各个变量添加到环境变量里 export ARCH CPU BOARD VENDOR SOC ... #这里定义了我们的arm平台的交叉编译链 ifeq ($(ARCH),arm) CROSS_COMPILE = arm-linux- ... #第一个目标文件 OBJS = cpu/$(CPU)/start.o ... #加载编译所需要的一些库文件 LIBS = lib_generic/libgeneric.a LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \ "board/$(VENDOR)/common/lib$(VENDOR).a"; fi) LIBS += cpu/$(CPU)/lib$(CPU).a ifdef SOC LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).a endif ifeq ($(CPU),ixp) LIBS += cpu/ixp/npe/libnpe.a endif LIBS += lib_$(ARCH)/lib$(ARCH).a LIBS += fs/cramfs/libcramfs.a fs/fat/libfat.a fs/fdos/libfdos.a fs/jffs2/libjffs2.a \ fs/reiserfs/libreiserfs.a fs/ext2/libext2fs.a LIBS += net/libnet.a LIBS += disk/libdisk.a LIBS += drivers/bios_emulator/libatibiosemu.a LIBS += drivers/block/libblock.a LIBS += drivers/dma/libdma.a LIBS += drivers/hwmon/libhwmon.a LIBS += drivers/i2c/libi2c.a .... #我们编译默认从这里开始,我们需要生成u-boot.bin,所以我们看下面u-boot.bin的依赖 ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND) $(obj)u-boot.dis ... ... #默认make命令从这里开始执行 all: $(ALL) ... $(obj)u-boot.hex: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ $(obj)u-boot.srec: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ #u-boot.bin依赖u-boot,我们再看u-boot依赖哪里,接着向下分析 $(obj)u-boot.bin: $(obj)u-boot $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ $(obj)u-boot.ldr: $(obj)u-boot $(LDR) -T $(CONFIG_BFIN_CPU) -f -c $@ $< $(LDR_FLAGS) $(obj)u-boot.ldr.hex: $(obj)u-boot.ldr $(OBJCOPY) ${OBJCFLAGS} -O ihex $< $@ -I binary $(obj)u-boot.ldr.srec: $(obj)u-boot.ldr $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ -I 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.sha1: $(obj)u-boot.bin $(obj)tools/ubsha1 $(obj)u-boot.bin $(obj)u-boot.dis: $(obj)u-boot $(OBJDUMP) -d $< > $@ #我们发现u-boot依赖后面这些内容 $(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT) UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \ sed -n -e 's/.*\($(SYM_PREFIX)__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 ... #对各个子目录下的obj,lib文件进行编译 $(OBJS): depend $(obj)include/autoconf.mk $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@)) $(LIBS): depend $(obj)include/autoconf.mk $(MAKE) -C $(dir $(subst $(obj),,$@)) ...
3:上述过程我们分析到了uboot编译的命令如下:
$(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT)
UNDEF_SYM=`$(OBJDUMP) -x $(LIBBOARD) $(LIBS) | \
sed -n -e 's/.*\($(SYM_PREFIX)__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,在最后,我们发现如下:
make[1]: Leaving directory `/root/uboot_smdkv210-8-18/board/samsung/smdkc110'
make -C /root/uboot_smdkv210-8-18/board/samsung/smdkc110/ u-boot.lds
make[1]: Entering directory `/root/uboot_smdkv210-8-18/board/samsung/smdkc110'
make[1]: Nothing to be done for `u-boot.lds'.
make[1]: Leaving directory `/root/uboot_smdkv210-8-18/board/samsung/smdkc110'
UNDEF_SYM=`arm-linux-objdump -x board/samsung/smdkc110/libsmdkc110.a lib_generic/libgeneric.a cpu/s5pc11x/libs5pc11x.a cpu/s5pc11x/s5pc110/libs5pc110.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 drivers/bios_emulator/libatibiosemu.a drivers/block/libblock.a drivers/dma/libdma.a drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a drivers/input/libinput.a drivers/misc/libmisc.a drivers/mmc/libmmc.a drivers/mtd/libmtd.a drivers/mtd/nand/libnand.a drivers/mtd/nand_legacy/libnand_legacy.a drivers/mtd/onenand/libonenand.a drivers/mtd/ubi/libubi.a drivers/mtd/spi/libspi_flash.a drivers/net/libnet.a drivers/net/sk98lin/libsk98lin.a drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a drivers/spi/libspi.a drivers/rtc/librtc.a drivers/serial/libserial.a drivers/usb/libusb.a drivers/video/libvideo.a common/libcommon.a libfdt/libfdt.a api/libapi.a post/libpost.a | \
sed -n -e 's/.*\(__u_boot_cmd_.*\)/-u\1/p'|sort|uniq`;\
cd /root/uboot_smdkv210-8-18 && arm-linux-ld -Bstatic -T /root/uboot_smdkv210-8-18/board/samsung/smdkc110/u-boot.lds -Ttext 0xc3e00000 $UNDEF_SYM cpu/s5pc11x/start.o \
--start-group lib_generic/libgeneric.a cpu/s5pc11x/libs5pc11x.a cpu/s5pc11x/s5pc110/libs5pc110.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 drivers/bios_emulator/libatibiosemu.a drivers/block/libblock.a drivers/dma/libdma.a drivers/hwmon/libhwmon.a drivers/i2c/libi2c.a drivers/input/libinput.a drivers/misc/libmisc.a drivers/mmc/libmmc.a drivers/mtd/libmtd.a drivers/mtd/nand/libnand.a drivers/mtd/nand_legacy/libnand_legacy.a drivers/mtd/onenand/libonenand.a drivers/mtd/ubi/libubi.a drivers/mtd/spi/libspi_flash.a drivers/net/libnet.a drivers/net/sk98lin/libsk98lin.a drivers/pci/libpci.a drivers/pcmcia/libpcmcia.a drivers/spi/libspi.a drivers/rtc/librtc.a drivers/serial/libserial.a drivers/usb/libusb.a drivers/video/libvideo.a common/libcommon.a libfdt/libfdt.a api/libapi.a post/libpost.a board/samsung/smdkc110/libsmdkc110.a --end-group -L /usr/src/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1 -lgcc \
-Map u-boot.map -o u-boot
arm-linux-objcopy --gap-fill=0xff -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
arm-linux-objdump -d u-boot > u-boot.dis
,根据上面的显示,我们发现最后一部分跟makefile是匹配的,我们可以看到编译的命令具体是什么,我们这个时候可以反推下编译中的命令意思,比如:
cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
--start-group $(__LIBS) --end-group $(PLATFORM_LIBS) \
-Map u-boot.map -o u-boot
中的红色部分,这些具体是什么,其实都可以在上面的那堆编译命令行里找到了,比如:
$(LNDIR) = /root/uboot_smdkv210-8-18
$(LD) = arm-linux-ld
$(LDFLAGS) = -Bstatic -T /root/uboot_smdkv210-8-18/board/samsung/smdkc110/u-boot.lds -Ttext 0xc3e00000
...具体这些在哪些文件里面呢?我们可以通过对uboot源码进行grep分析,可以清楚的看到这些定义在哪个地方,比如我们搜索$(LDFLAGS) 这个定义:
[root@localhost uboot_smdkv210-8-18]# grep "LDFLAGS" * nR
avr32_config.mk:PLATFORM_LDFLAGS += --relax
config.mk:PLATFORM_LDFLAGS =
config.mk:LDFLAGS += -Bstatic -T $(LDSCRIPT) $(PLATFORM_LDFLAGS)
config.mk:LDFLAGS += -Ttext $(TEXT_BASE)
m68k_config.mk:PLATFORM_LDFLAGS += -n
Makefile: cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
mips_config.mk:# LDFLAGS_vmlinux += -G 0 -static -n -nostdlib
mips_config.mk:PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib
ppc_config.mk:PLATFORM_LDFLAGS += -n
然后我们可以继续找LDSCRIPT,如下:
[root@localhost uboot_smdkv210-8-18]#grep "LDSCRIPT" * nR
CHANGELOG: Makefile: add target for $(LDSCRIPT)
CHANGELOG: If the $(LDSCRIPT) does not exist (normally it's board/$(BOARD)/u-boot.lds),
CHANGELOG-before-U-Boot-1.1.5: - allow LDSCRIPT override and OBJCFLAGS initialization: change to
CHANGELOG-before-U-Boot-1.1.5: linker script, selected via the LDSCRIPT, make variable, and to
config.mk:ifndef LDSCRIPT
config.mk:#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
config.mk:LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
config.mk:LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
config.mk:LDFLAGS += -Bstatic -T $(LDSCRIPT) $(PLATFORM_LDFLAGS)
Makefile:$(obj)u-boot: depend $(SUBDIRS) $(OBJS) $(LIBBOARD) $(LIBS) $(LDSCRIPT)
Makefile:$(LDSCRIPT): depend $(obj)include/autoconf.mk
然后我们接着找BOARDDIR:
[root@localhost uboot_smdkv210-8-18]# grep "BOARDDIR" * nR
CHANGELOG: $(TOPDIR)/board/$(BOARDDIR)/config.tmp
CHANGELOG: $(OBJTREE)/board/$(BOARDDIR)/config.tmp
config.mk:BOARDDIR = $(VENDOR)/$(BOARD)
config.mk:BOARDDIR = $(BOARD)
config.mk:sinclude $(TOPDIR)/board/$(BOARDDIR)/config.mk # include board specific rules
config.mk:#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
config.mk:LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
config.mk:LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
Makefile:LIBBOARD = board/$(BOARDDIR)/lib$(BOARD).a
Makefile: $(MAKE) -C nand_spl/board/$(BOARDDIR) all
Makefile:# $(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
Makefile:TAG_SUBDIRS += lib_generic board/$(BOARDDIR)
然后这个脚本的地址便是:uboot_smdkv210-8-18/board/samsung/smdkc110/u-boot.lds
然后就这样向下分析,我们便可以知道的更多了,通过这个编译之后链接,我们发现第一个是从cpu/s5pc11x/start.o开始链接的,那么第一个文件也就是cpu/s5pc11x/start.S这个文件了,具体uboot的详细引导启动过程,下次有时间再说.
文章的脚注信息由WordPress的wp-posturl插件自动生成