Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1907333
  • 博文数量: 496
  • 博客积分: 12043
  • 博客等级: 上将
  • 技术积分: 4778
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-27 14:26
文章分类

全部博文(496)

文章存档

2014年(8)

2013年(4)

2012年(181)

2011年(303)

2010年(3)

分类: 嵌入式

2012-06-16 16:04:52

在这篇文字里,我就要分析一下在第一篇文字里被忽略的部分了。这部分是在$(OBJTREE)/include/config.mk文件已经存在的 情况下才执行的。
__________________________________________________

# load ARCH, BOARD, and CPU configuration
include $(OBJTREE)/include/config.mk
export ARCH CPU BOARD VENDOR SOC

ifndef CROSS_COMPILE
ifeq ($(HOSTARCH),ppc)
CROSS_COMPILE =
else
ifeq ($(ARCH),ppc)
CROSS_COMPILE = powerpc-linux-
endif
ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-
endif
ifeq ($(ARCH),i386)
ifeq ($(HOSTARCH),i386)
CROSS_COMPILE =
else
CROSS_COMPILE = i386-linux-
endif
endif
ifeq ($(ARCH),mips)
CROSS_COMPILE = mips_4KC-
endif
ifeq ($(ARCH),nios)
CROSS_COMPILE = nios-elf-
endif
ifeq ($(ARCH),nios2)
CROSS_COMPILE = nios2-elf-
endif
ifeq ($(ARCH),m68k)
CROSS_COMPILE = m68k-elf-
endif
ifeq ($(ARCH),microblaze)
CROSS_COMPILE = mb-
endif
ifeq ($(ARCH),blackfin)
CROSS_COMPILE = bfin-elf-
endif
ifeq ($(ARCH),avr32)
CROSS_COMPILE = avr32-
endif
endif
endif

export CROSS_COMPILE
____________________________________________________

注意开头一句中的include,它是把后面跟的文件内容给加到它出现的地方,这里就是把$(OBJTREE)/include /config.mk文件的内容加入到了这里,所以就得到了ARCH,BOARD与CPU的值,如果VENDOR与SOC也定义了,也会得到它们的值。

后面接着的一大段,就是在判断没有定义CROSS_COMPILE变量的情况下,根据各种情况对这个变量的值进行判断。这个值就是交叉编译工具的开 头部分的名称。如果不清楚什么是交叉编译工具,就需要查查相关的资料了。
在这里,我建议在编译的时候,还是把这个变量的值给置上,置上当前系统里 交叉编译工具相应的值,因为很难指望这些个判断就能把你现在系统里的值给判断对了。置变量的方法有-很多,其中一个,就是在make命令后跟上变量的赋 值,例如:make CROSS_COMPILE=arm-linux-gnueabi-,或是把CROSS_COMPILE设成一个系统变量,然后直接make CROSS_COMPILE=${CROSS_COMPILE}-这样来设置。
____________________________________________________

# load other configuration
include $(TOPDIR)/config.mk
____________________________________________________

这里把$(TOPDIR)/config.mk这个文件的内容包含进来了。
还有个语句需要提前说明一下,就是sinclude,它也是把后 面所跟的文件给包含进来。它与include的区别就是,include后面跟的文件,一定是存在的,如果不存在,执行就会出错误;那么sinclude 后面所跟的文件,可以不存在,如果文件存在则包含进来,如果不存在,则什么也不做。
在这里提这一句,是因为 在$(TOPDIR)/config.mk这个文件里,用到了这个命令,在这里提一下,是可以做个比较,这样便于记忆。

 

按理说,下面应该分析$(TOPDIR)/config.mk这个文件了,不过这个文件对移植的影响,源码的影响也不是特别大,所以就不做特别细致 的分析了,大概介绍一下这个文件的功能。

这个文件的功能就是给各个在编译过程中的变量赋值,包括编译执行的函数与编译的时候所带的参数等等。还会根据是否定义了 ARCH,CPU,SOC,VENDOR,BOARD来决定是否包含相应位置的config.mk文件,这些个文件里,也是定义了相应的平台在编译的时候 应该加的参数。所以如果你为你自己的开发板取了别的名字了,那么就要检查一下这个文件,看一下相应的位置上的config.mk文件有没有,内容是否为你 要想的。
____________________________________________________

OBJS  = cpu/$(CPU)/start.o
ifeq ($(CPU),i386)
OBJS += cpu/$(CPU)/start16.o
OBJS += cpu/$(CPU)/reset.o
endif
ifeq ($(CPU),ppc4xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc83xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc85xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),mpc86xx)
OBJS += cpu/$(CPU)/resetvec.o
endif
ifeq ($(CPU),bf533)
OBJS += cpu/$(CPU)/start1.o cpu/$(CPU)/interrupt.o cpu/$(CPU)/cache.o
OBJS += cpu/$(CPU)/cplbhdlr.o cpu/$(CPU)/cplbmgr.o cpu/$(CPU)/flush.o
endif

OBJS := $(addprefix $(obj),$(OBJS))

LIBS  = lib_generic/libgeneric.a
LIBS += board/$(BOARDDIR)/lib$(BOARD).a
LIBS += cpu/$(CPU)/lib$(CPU).a
ifdef SOC
LIBS += cpu/$(CPU)/$(SOC)/lib$(SOC).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 += rtc/librtc.a
LIBS += dtt/libdtt.a
LIBS += drivers/libdrivers.a
LIBS += drivers/nand/libnand.a
LIBS += drivers/nand_legacy/libnand_legacy.a
LIBS += drivers/sk98lin/libsk98lin.a
LIBS += post/libpost.a post/cpu/libcpu.a
LIBS += common/libcommon.a
LIBS += $(BOARDLIBS)

LIBS := $(addprefix $(obj),$(LIBS))
.PHONY : $(LIBS)

# Add GCC lib
PLATFORM_LIBS += -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc

# The "tools" are needed early, so put this first
# Don't include stuff already done in $(LIBS)
SUBDIRS = tools /
   examples /
   post /
   post/cpu
.PHONY : $(SUBDIRS)

ifeq ($(CONFIG_NAND_U_BOOT),y)
NAND_SPL = nand_spl
U_BOOT_NAND = $(obj)u-boot-nand.bin
endif

__OBJS := $(subst $(obj),,$(OBJS))
__LIBS := $(subst $(obj),,$(LIBS))
____________________________________________________

这段代码,其实也是定义变量,根据不同的条件,给变量定义不同的值。这些变量都是在后面编译的时候,写到运行命令参数里面的,这些变量的意义,还有 各种参数的意义,可以查看相应的工具的参数手册来得到,由于跟移植没有什么太大的关系,就不做一一说明了。
这段代码不难理解,就是需要注意一下各 个变量值所添加的顺序,第一个添加的,编译的时候,变量进行替换,就会被放在前面,然后就会被首先编译,连接,以此类推。可以看到,最先执行的就是 start.o这个文件里的内容,这个文件是由start.S来生成的。
____________________________________________________

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

$(OBJS):
  $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))

$(LIBS):
  $(MAKE) -C $(dir $(subst $(obj),,$@))

$(SUBDIRS):
  $(MAKE) -C $@ all

$(NAND_SPL): version
  $(MAKE) -C nand_spl/board/$(BOARDDIR) all

$(U_BOOT_NAND): $(NAND_SPL) $(obj)u-boot.bin
  cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin

version:
  @echo -n "#define U_BOOT_VERSION /"U-Boot " > $(VERSION_FILE); /
  echo -n "$(U_BOOT_VERSION)" >> $(VERSION_FILE); /
  echo -n $(shell $(CONFIG_SHELL) $(TOPDIR)/tools/setlocalversion /
    $(TOPDIR)) >> $(VERSION_FILE); /
  echo "/"" >> $(VERSION_FILE)

gdbtools:
  $(MAKE) -C tools/gdb all || exit 1

updater:
  $(MAKE) -C tools/updater all || exit 1

env:
  $(MAKE) -C tools/env all || exit 1

depend dep:
  for dir in $(SUBDIRS) ; do $(MAKE) -C $$dir _depend ; done

tags ctags:
  ctags -w -o $(OBJTREE)/ctags `find $(SUBDIRS) include /
    lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) /
    fs/cramfs fs/fat fs/fdos fs/jffs2 /
    net disk rtc dtt drivers drivers/sk98lin common /
   /( -name CVS -prune /) -o /( -name '*.[ch]' -print /)`

etags:
  etags -a -o $(OBJTREE)/etags `find $(SUBDIRS) include /
    lib_generic board/$(BOARDDIR) cpu/$(CPU) lib_$(ARCH) /
    fs/cramfs fs/fat fs/fdos fs/jffs2 /
    net disk rtc dtt drivers drivers/sk98lin common /
   /( -name CVS -prune /) -o /( -name '*.[ch]' -print /)`

$(obj)System.map: $(obj)u-boot
  @$(NM) $< | /
  grep -v '/(compiled/)/|/(/.o$$/)/|/( [aUw] /)/|/(/./.ng$$/)/|/(LASH[RL]DI/)' | /
  sort > $(obj)System.map

______________________________________________________

这里就是定义了各种目标的target。我们最终想要的目标就是$(obj)u-boot,然后看后面的,它都信赖了好多其它的目标,然后这些个目 标,也是在此处定义的,然后有相应的$(MAKE)来执行相应的操作,所以这样就实现了一个Makefile文件,套很多个其它的Makefile文件来 编译整个工程的情况。


现在整个编译的过程就分析清楚了,那么开始移植就是对代码的整个熟悉的过程了。最先开始执行的就是start.S的内容,移值就需要先分析 它。
其实要想自己写这样的一个文件,难度还是比较大的,首先要熟悉这种比较特别的汇编语法,然后需要了解与处理器相关的各种状态寄存器的定义。但 是如果只是做修改,难度就小多了,拿着ARM处理器汇编语言的手册,再参考三星提供的S3C2440的板子的说明,一步步检查源码,修改相应的参数,以符 合自己的板子的需要就行了,如果有兴趣,也可以弄清楚各种参数的具体的意义,各种状态寄存器的格式定义,这也是比较有意思的。

我自己的移植也刚则开始,目前还没有遇到很棘手的问题,现在最担心的,就是我买的开发板上的各种重要的状态寄存器的地址与S3C2440这块板子上 的不一样,因为我的这块板子也没有相应的说明书,只给了三星的S3C2440的说明书,万一不一致,我就完蛋了,希望这种局面不要发生,阿门。

等我自己的u-boot移植成功后,我就要去给自己找个嵌入式相关的工作了,实在比较喜欢这个行当的这种比较富有挑战性的工作,哈哈哈哈:)

现在这系列的文章,暂时告一段落,已经写完的,算是一个上部吧,等我自己的移植工作做完了,我就开始接着写u-boot-1.1.6源码浅析 (五),从五开始,就要分析源码的具体的内容了,只要于移植相关的,都会做出说明,包括各种寄存器的状态的定义,至于会告诉你去哪里查这个东西,怎么查, 怎么看明白。
好了,这系列的说明上部,就到此为止,再见。

阅读(671) | 评论(0) | 转发(0) |
0

上一篇:s3c2440读/写NAND FALSH

下一篇:SDRAM原理初探

给主人留下些什么吧!~~