2. 链接器脚本
gboot.lds 链接器脚本 代码解析 :
1.指明输出格式 ( 处理器架构 ) : 使用 OUTPUT_ARCH(架构名称) 指明输出格式, 即处理器的架构, 这里是 arm 架构的, OUTPUT_ARCH(arm) ;
2.指明输出程序的入口 : 设置编译输出的程序入口位置, 语法为 ENTRY(入口位置), 在上面的 Start.S 中设置的程序入口是 _start, 代码为 ENTRY(_start) ;
3.设置代码段 : 使用 .text : 设置代码段;
4.设置数据段 : 使用 .data : 设置数据段;
5.设置 BSS 段 : 使用 .bss : 设置 BSS 段;
( 1 ) 记录 BSS 段的起始地址 : bss_start = .; ;
( 2 ) 记录 BSS 段的结束地址 : bss_end = .; ;
6.对齐 : 每个段都需要设置内存的对齐格式, 使用 . = ALIGN(4); 设置四字节对齐即可;
7.代码示例 :
OUTPUT_ARCH(arm) /*指明处理器结构*/ ENTRY(_start) /*指明程序入口 在 _start 标号处*/ SECTIONS { . = 0x50008000; /*整个程序链接的起始位置, 根据开发板确定, 不同开发板地址不一致*/ . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ .text : /*代码段*/ { start.o (.text) /*start.S 转化来的代码段*/ *(.text) /*其它代码段*/ } . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ .data : /*数据段*/ { *(.data) } . = ALIGN(4); /*对齐处理, 每段开始之前进行 4 字节对齐*/ bss_start = .; /*记录 bss 段起始位置*/ .bss : /*bss 段*/ { *(.bss) } bss_end = .; /*记录 bss 段结束位置*/
3. Makefile 编译脚本
makefile 文件编写 :
1.通用规则 ( 汇编文件编译规则 ) : 汇编文件 编译 成同名的 .o 文件, 文件名称相同, 后缀不同, %.o : %.S, 产生过程是 arm-linux-gcc -g -c $^ , 其中 ^ 标识是所有的依赖文件, 在该规则下 start.S 会被变异成 start.o ;
2.通用规则 ( C 文件编译规则 ) : C 代码编译成同名的 .o 文件, %.o : %.c , 产生过程是 arm-linux-gcc -g -c $^ ;
3.设置最终目标 : 使用 all: 设置最终编译目标;
( 1 ) 依赖文件 : 产生最终目标需要依赖 start.o 文件, 使用 all: start.o 表示最终目标需要依赖该文件;
( 2 ) 链接过程 : arm-linux-ld -Tgboot.lds -o gboot.elf $^, 需要使用链接器脚本进行连接, ①链接工具是 arm-linux-ld 工具, ②使用 -Tgboot.lds 设置链接器脚本 是刚写的 gboot.lds 链接器脚本, ③输出文件是 gboot.elf 这是个中间文件, ④ 依赖文件是 $^ 代表所有的依赖;
( 3 ) 转换成可执行二进制文件 : arm-linux-objcopy -O binary gboot.elf gboot.bin, 使用 -O binary 设置输出二进制文件, 依赖文件是 gboot.elf, 输出的可执行二进制文件 即 结果是 gboot.bin ;
4.makefile 文件内容 :
all: start.o #依赖于 start.o arm-linux-ld -Tgboot.lds -o gboot.elf $^ #使用链接器脚本, 将 start.o 转为 gboot.elf arm-linux-objcopy -O binary gboot.elf gboot.bin #将 gboot.elf 转化为可以直接在板子上执行的 gboot.bin 文件 %.o : %.S #通用规则, 如 start.o 是由 start.S 编译来的, -c 是只编译不链接 arm-linux-gcc -g -c $^ %.o : %.c #通用规则, 如 start.o 是由 start.c 编译来的, -c 是只编译不链接 arm-linux-gcc -g -c $^ .PHONY: clean clean: #清除编译信息 rm *.o *.elf *.bin
4. 编译输出可执行文件
编译过程 :
1.文件准备 : 将 汇编代码 ( start.S ) 链接器脚本 ( gboot.lds ) makefile 文件 拷贝到编译目录 ;
2.执行编译命令 : make ;
3.编译结果 : 可以看到 生成了 编译目标文件 start.o, 链接文件 gboot.elf, 可执行的二进制文件 gboot.bin ;