一、gnu二进制工具集
1.1 gcc命令
将.s文件生成.o文件 arm-linux-gnueabihf-gcc -c asm-led.S -o asm-led.o
1.2 ld链接器
ld:链接命令,将.o文件链接生成.elf文件,需要指定链接的入口地址
arm-linux-gnueabihf-ld -Ttext=0xc0008000 asm-led.o -o asm-led.elf
1.3 objdump生成反汇编
objdump:生成反汇编命令,将.elf文件生成反汇编文件
arm-linux-gnueabihf-objdump -D asm-led.elf > asm-led.dis
1.4 objcopy生成二进制文件
objcopy:生成二进制文件,将.elf文件生成纯粹二进制文件
.elf文件:包含符号表信息,调试信息
.bin文件:不包含符号表信息,调试信息
arm-linux-gnueabihf-objcopy -O binary asm-led.elf asm-led.bin
1.5 nm查看符号表信息
命令:arm-linux-gnueabihf-nm asm-led.elf
c00181e8 T __bss_end__
c00181e8 T _bss_end__
c00181e8 T __bss_start
c00181e8 T __bss_start__
c00081a8 t delay_1s
c00181e8 T _edata
c00181e8 T __end__
c00181e8 T _end
c0008000 t led1_init
c000816c t led1_off
c0008130 t led1_on
c0008054 t led2_init
c0008180 t led2_off
c0008144 t led2_on
c00080a8 t led3_init
c0008194 t led3_off
c0008158 t led3_on
c00080fc t loop
c00081ac t mm
c0008000 T _start
1.6 size查看各个段大小
arm-linux-gnueabihf-size asm-led.elf
1.7 readelf查看文件头部信息
arm-linux-gnueabihf-readelf -h asm-led.elf
1.8 strip压缩文件体积
strip压缩文件体积,不可以对中间文件进行压缩(.i,.s,.o文件)
arm-linux-gnueabihf-strip asm-led.elf
1.9 addr2line调试段错误信息
addr2line:用来调试内核中段错误信息
格式:arm-linux-gnueabihf-addr2line 地址 -e 指定elf文件 -f-e:指定elf可执行文件-f:回显函数名,行号linux@ubuntu:~/DC22081/01-asm-led$ arm-linux-gnueabihf-addr2line c000816c -e asm-led.elf -fled1_off/home/linux/DC22081/01-asm-led/asm-led.S:146以上学习的所有命令,支持X86架构和ARM架构,如果想生成X86架构,直接使用命令即可,不需要加交叉编译工具链前缀
如果想生成ARM架构,需要加交叉编译工具链前缀就可以
二、gcc编译流程
2.1 预处理
预处理作用:头文件展开,去掉注释,宏替换,不检查语法错误 gcc -E *.c -o *.i
2.2 编译
编译:生成汇编文件,检查语法错误 gcc -S *.i -o *.s
2.3 汇编
汇编:生成二进制文件,检查语法错误 gcc -c *.s -o *.o
2.4 链接
链接:链接对应的库,生成.elf可执行文件 gcc *.o -o 可执行文件
三、分析Makefile文件
makefile中四种赋值方式有什么区别?
?= :询问赋值
+=:追加赋值
:=:立即赋值
=:普通赋值# SHELL=C:/Windows/System32/cmd.exe
# 指定交叉编译工具链前缀
CROSS_COMPILE = arm-linux-gnueabihf-
#指定文件名字
NAME = interface
#=============================================================================#
#-g:gdb调试信息 -marm:编译生成arm架构 -Wall: 显示所有警告信息 -O0:优化等级信息
#-I:指定头文件路径
#-fno-builtin:不使用linux操作系统提供的库函数
#-nostdinc:不使用系统提供的头文件
CFLAGS += -g -marm -Wall -O0 -mabi=apcs-gnu -mfpu=neon -mfloat-abi=softfp -fno-builtin \-nostdinc -I./common/include -I./include
#ld:链接命令
LD = $(CROSS_COMPILE)ld
#gcc:编译命令
CC = $(CROSS_COMPILE)gcc
#nm:查看符号表信息
NM = $(CROSS_COMPILE)nm
#objcopy:生成二进制文件
OBJCOPY = $(CROSS_COMPILE)objcopy
#objdump:生成反汇编文件
OBJDUMP = $(CROSS_COMPILE)objdump
#============================================================================#
#wildcard是Makefile中内置函数
#函数功能:将某个文件夹下面的内容进行以字符串形式进行展开,并用空格隔开
#函数参数:需要展开目录文件
#函数返回值:以字符串展开后的结果
OBJSss := $(wildcard start/*.S) $(wildcard common/src/*.S) $(wildcard *.S)\$(wildcard start/*.c) $(wildcard common/src/*.c) \$(wildcard src/*.c) $(wildcard *.c)
#patsubst是Makefile中内置函数
#函数功能:将一个字符串内容替换成另外一个字符串
#函数参数:
#第一个参数:源字符串,也就是要替换的字符串
#第二个参数:目标字符串,也就是替换后的字符串
#第三个参数:要替换的字符串目录
#函数返回值:替换后的目标字符串
#将OBJSss目录下所有以.S结尾的字符串,替换成.o
OBJSs := $(patsubst %.S,%.o,$(OBJSss))
#将OBJS目录下所有以.c结尾的字符串,替换成.o
OBJS := $(patsubst %.c,%.o,$(OBJSs))%.o: %.S @echo " AS $@"@$(CC) $(CFLAGS) -c -o $@ $<#将所有以.S结尾的文件根据指定参数编译生成.o结尾的文件#$@:目标#$<:第一个依赖#$^:所有依赖%.o: %.c@echo " CC $@"@$(CC) $(CFLAGS) -c -o $@ $<#将所有以.c结尾的文件根据指定参数编译生成.o结尾的文件all:clean $(OBJS)@echo " LD Linking $(NAME).elf"#将OBJS目录下所有文件,根据链接脚本文件map.lds指定地址信息,生成elf文件@$(LD) $(OBJS) -T map.lds -o $(NAME).elf@echo " OBJCOPY Objcopying $(NAME).bin"#将elf文件生成.bin文件@$(OBJCOPY) -O binary $(NAME).elf $(NAME).bin @echo " MAP Generating $(NAME).map"#将elf文件符号表信息重定向到interface.map文件中@$(NM) $(NAME).elf > $(NAME).map @echo " OBJDUMP Objdumping $(NAME).dis"#将elf文件生成反汇编文件到.dis文件中 @$(OBJDUMP) -DS $(NAME).elf > $(NAME).dis distclean clean:@rm -rf $(OBJS) *.elf *.bin *.dis *.map @echo " CLEAN complete."install:sudo cp $(NAME).bin /mnt/hgfs/share/huyue:@echo $(OBJSss)@echo $(OBJSs)@echo $(OBJS)