1、配置lepus时候我们输入:
make lepus_nand_config
从Makefile文件2146行可以找到
这个命令等于 ./mkconfig-a lepus mips mips lepus
$1 $2 $3 $4
这个在mkconfig文件6行给出了用法:Parameters: Target Architecture CPU Board [VENDOR] [SOC]
另外还向include/config.h、board/lepus/config.tmp、include/config.mk写入信息
2、在mkconfig文件33行中判断源代码目录和目标文件目录是否一样,由于我们直接在源代码目录编译,所以删除asm文件,再创建asm文件并链接到asm-$2,即asm-mips
3、第51行删除asm-$2/arch,即asm-arm/arch
4、第53行判断$6为空,ln -s arch-mips asm-mips/arch
5、第67-69创建并向/include/config.mk写入信息,加上Makefile文件写入的,内容如下:
ARCH = mips
CPU = mips
BOARD = lepus
CONFIG_NAND_U_BOOT = y
CONFIG_CPU_TYPE = 4760
CONFIG_USE_MDDR = n
CONFIG_USE_DDR1 = n
CONFIG_USE_DDR2 = y
CONFIG_USE_SDRAM = n
6、第78-85行创建开发板相关include/config.h,如下
/* Automatically generated - do not edit */
#include <configs/lepus.h>
总结:我们输入:make lepus_nand_config实际上就是执行./mkconfig-a lepus mips mipslepus
将产生如下结果:
(1) 开发板名称BOARD_NAME等于$1,即lepus
(2) 创建开发板相关的头文件链接:
ln -s asm-mips asm
ln -s arch-mips asm-mips/arch
(3) 创建顶层Makefile包含的文件include/config.mk
ARCH = mips
CPU = mips
BOARD = lepus
CONFIG_NAND_U_BOOT = y
CONFIG_CPU_TYPE = 4760
CONFIG_USE_MDDR = n
CONFIG_USE_DDR1 = n
CONFIG_USE_DDR2 = y
CONFIG_USE_SDRAM = n
(4) 创建开发板相关的头文件include/config.h
/* Automatically generated - do not edit */
#include <configs/lepus.h>
7、Makefile第138-140行,根据ARCH CPU BOARD VENDOR SOC四个变量确定编译器为mipsel-linux-
8、Makefile第170行知道OBJS的第一个值为"cpu/$(CPU)/start.o"即cpu/lepus/start.o
9、Makefile第194-213指定了LIBS变量就是开发板相关的各个目录、通用目录下的库
OBJS、LIBS所代表的.o、.a文件就是U-Boot的构成,通过如下命令由相应的源文件编译得到:
283 $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
284
285 $(LIBS):
286 $(MAKE) -C $(dir $(subst $(obj),,$@))
287
288 $(SUBDIRS):
289 $(MAKE) -C $@ all
10、当所有OBJS、LIBS所代表的.o和.a文件生成后,再进行连接,对应Makefile文件
260 $(obj)u-boot.srec: $(obj)u-boot
261 $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
262
263 $(obj)u-boot.bin: $(obj)u-boot
264 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
265
......
276 $(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIP T)
277 UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boo t_cmd_.*\)/-u\1/p'|sort|uniq`;\
278 cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
279 --start-group $(__LIBS) --end-group $(PLATFORM_LIBS ) \
280 -Map u-boot.map -o u-boot
281
先用276-280行连接得到ELF格式的U-Boot,最后转换成二进制格式的U-Boot.bin、S-Record格式U-Boot.serc。LDFLAGS确定连接方式。board/lepus/u-boot.lds文件如下:
/* 这里是生成格式为elf。大端,mips */
21 OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlit tlemips")
22
23 OUTPUT_ARCH(mips)/* 平台为mips */
24 ENTRY(_start)/* 入口点为_start */
25 SECTIONS
26 {
27 . = 0x00000000;
28
29 . = ALIGN(4);
30 .text :
31 {
32 *(.text)/* 这个是程序存放的地方 */
33 }
34
35 . = ALIGN(4);/* 表示以4字节对齐 */
36 .rodata : { *(.rodata) }
37
38 . = ALIGN(4);
39 .data : { *(.data) }
40
41 . = ALIGN(4);
42 .sdata : { *(.sdata) }
43
44 . = ALIGN(16);
45 _gp = .;
46 __got_start = .;/* 表示该处地址的值给__got_start */
47 .got : { *(.got) }
48 __got_end = .;
49
50 .sdata : { *(.sdata) }
51
52 . = ALIGN(16);
53 __u_boot_cmd_start = .;
54 .u_boot_cmd : { *(.u_boot_cmd) }
55 __u_boot_cmd_end = .;
56
57 uboot_end_data = .;
58 num_got_entries = (__got_end - __got_start) >> 2;
59
60 . = ALIGN(4);
61 .sbss : { *(.sbss) }
62 .bss : { *(.bss) }
63 uboot_end = .;
64 }
从24行我们知道U-Boot的入口点在/cpu/mips/start.S
总结一下编译流程:
(1) 首先编译cpu/mips/start.S
(2) 开发板每个目录,每个通用目录都使用各自Makefile生成相应的库
(3) 将1、2步骤生成的.o、.a文件按照board/lepus/comfig.mk文件指定的代码段起始地址、board/lepus/u-boot.lds连接脚本进行连接
make lepus_nand_config
从Makefile文件2146行可以找到
这个命令等于 ./mkconfig-a lepus mips mips lepus
$1 $2 $3 $4
这个在mkconfig文件6行给出了用法:Parameters: Target Architecture CPU Board [VENDOR] [SOC]
另外还向include/config.h、board/lepus/config.tmp、include/config.mk写入信息
2、在mkconfig文件33行中判断源代码目录和目标文件目录是否一样,由于我们直接在源代码目录编译,所以删除asm文件,再创建asm文件并链接到asm-$2,即asm-mips
3、第51行删除asm-$2/arch,即asm-arm/arch
4、第53行判断$6为空,ln -s arch-mips asm-mips/arch
5、第67-69创建并向/include/config.mk写入信息,加上Makefile文件写入的,内容如下:
ARCH = mips
CPU = mips
BOARD = lepus
CONFIG_NAND_U_BOOT = y
CONFIG_CPU_TYPE = 4760
CONFIG_USE_MDDR = n
CONFIG_USE_DDR1 = n
CONFIG_USE_DDR2 = y
CONFIG_USE_SDRAM = n
6、第78-85行创建开发板相关include/config.h,如下
/* Automatically generated - do not edit */
#include <configs/lepus.h>
总结:我们输入:make lepus_nand_config实际上就是执行./mkconfig-a lepus mips mipslepus
将产生如下结果:
(1) 开发板名称BOARD_NAME等于$1,即lepus
(2) 创建开发板相关的头文件链接:
ln -s asm-mips asm
ln -s arch-mips asm-mips/arch
(3) 创建顶层Makefile包含的文件include/config.mk
ARCH = mips
CPU = mips
BOARD = lepus
CONFIG_NAND_U_BOOT = y
CONFIG_CPU_TYPE = 4760
CONFIG_USE_MDDR = n
CONFIG_USE_DDR1 = n
CONFIG_USE_DDR2 = y
CONFIG_USE_SDRAM = n
(4) 创建开发板相关的头文件include/config.h
/* Automatically generated - do not edit */
#include <configs/lepus.h>
7、Makefile第138-140行,根据ARCH CPU BOARD VENDOR SOC四个变量确定编译器为mipsel-linux-
8、Makefile第170行知道OBJS的第一个值为"cpu/$(CPU)/start.o"即cpu/lepus/start.o
9、Makefile第194-213指定了LIBS变量就是开发板相关的各个目录、通用目录下的库
OBJS、LIBS所代表的.o、.a文件就是U-Boot的构成,通过如下命令由相应的源文件编译得到:
283 $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@))
284
285 $(LIBS):
286 $(MAKE) -C $(dir $(subst $(obj),,$@))
287
288 $(SUBDIRS):
289 $(MAKE) -C $@ all
10、当所有OBJS、LIBS所代表的.o和.a文件生成后,再进行连接,对应Makefile文件
260 $(obj)u-boot.srec: $(obj)u-boot
261 $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@
262
263 $(obj)u-boot.bin: $(obj)u-boot
264 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
265
......
276 $(obj)u-boot: depend version $(SUBDIRS) $(OBJS) $(LIBS) $(LDSCRIP T)
277 UNDEF_SYM=`$(OBJDUMP) -x $(LIBS) |sed -n -e 's/.*\(__u_boo t_cmd_.*\)/-u\1/p'|sort|uniq`;\
278 cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
279 --start-group $(__LIBS) --end-group $(PLATFORM_LIBS ) \
280 -Map u-boot.map -o u-boot
281
先用276-280行连接得到ELF格式的U-Boot,最后转换成二进制格式的U-Boot.bin、S-Record格式U-Boot.serc。LDFLAGS确定连接方式。board/lepus/u-boot.lds文件如下:
/* 这里是生成格式为elf。大端,mips */
21 OUTPUT_FORMAT("elf32-tradlittlemips", "elf32-tradlittlemips", "elf32-tradlit tlemips")
22
23 OUTPUT_ARCH(mips)/* 平台为mips */
24 ENTRY(_start)/* 入口点为_start */
25 SECTIONS
26 {
27 . = 0x00000000;
28
29 . = ALIGN(4);
30 .text :
31 {
32 *(.text)/* 这个是程序存放的地方 */
33 }
34
35 . = ALIGN(4);/* 表示以4字节对齐 */
36 .rodata : { *(.rodata) }
37
38 . = ALIGN(4);
39 .data : { *(.data) }
40
41 . = ALIGN(4);
42 .sdata : { *(.sdata) }
43
44 . = ALIGN(16);
45 _gp = .;
46 __got_start = .;/* 表示该处地址的值给__got_start */
47 .got : { *(.got) }
48 __got_end = .;
49
50 .sdata : { *(.sdata) }
51
52 . = ALIGN(16);
53 __u_boot_cmd_start = .;
54 .u_boot_cmd : { *(.u_boot_cmd) }
55 __u_boot_cmd_end = .;
56
57 uboot_end_data = .;
58 num_got_entries = (__got_end - __got_start) >> 2;
59
60 . = ALIGN(4);
61 .sbss : { *(.sbss) }
62 .bss : { *(.bss) }
63 uboot_end = .;
64 }
从24行我们知道U-Boot的入口点在/cpu/mips/start.S
总结一下编译流程:
(1) 首先编译cpu/mips/start.S
(2) 开发板每个目录,每个通用目录都使用各自Makefile生成相应的库
(3) 将1、2步骤生成的.o、.a文件按照board/lepus/comfig.mk文件指定的代码段起始地址、board/lepus/u-boot.lds连接脚本进行连接
(4) 第3步得到的是ELF格式的U-Boot,后面Makefile还会将它转换成二进制格式\S-Record格式
good job!
参考《嵌入式linux应用开发完全手册》
《see mips run》