02_开发环境搭建
1. 为什么要交叉编译?
因为不同的平台架构,指令集都不一样
所以不同平台的程序使用的编译器也不一样
在x86平台使用ARM的编译器去编译出ARM平台可以执行的程序就叫做 交叉编译
指令:file [可执行文件]
,在第三块可以看到该文件的架构
main: ELF 64-bit LSB executable, x86-64 version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld.so.1, for GNU/Linux 4.15.0, BuildID[sha1]=0f28ab2fd3c9976f56d063fa7a506c8d203725e7, with debug_info, not stripped
2. 安装交叉编译链
有两种方式
- 安装芯片厂商已经编译好的工具链
解压缩就可以
arm-linux- 缩写
arm-none-linux-gnueabi- linux
表示linux平台 gnu
开源组织eabi
嵌入式接口
arm-none-eabi-
arm-elf-
codesourcecy 提供交叉编译器工具的公司
- 自己动手编译交叉工具链
《The GNU Toolchain for ARM Target HOWTO》
自己编译工具链版本依赖比较麻烦!!!
安装已经编译好的工具链,解压缩之后将路径添加到环境变量中就行
工具链文件:arm-linux-gcc-4.5.1-v6-vfp-20120301.tgz
解压:sudo tar -zxvf [文件名]
进入到bin
路径下,这里存放着工具集
使用方法:
- 使用简单方法:
- 需要添加PATH环境变量
arm-linux-gcc -o build 1.c
- 使用绝对路径:写入makefile文件
环境配置
- 64位机缺少32位的库,需要安装
32bit os 制作 32bit lib
64bit os --> no 32 bit lib
update add
unbuntu18
sudo apt-get install libc6:i386
sudo apt-get install lib32ncurses5
sudo apt-get install lib32z1
3. 工具集介绍
3.1. readelf:读elf文件
可执行文件分两部分:一部分是执行的代码,另一部分是头信息(ELF头)给操作系统提供的
readelf -h abc
:查看elf头
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: DYN (Shared object file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x1120
Start of program headers: 64 (bytes into file)
Start of section headers: 14992 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 31
Section header string table index: 30
- Magic: 魔术数
- Class:类型 elf64类型
- Data:小端
- Version:版本1
- OS/ABI:unix内核
- Type
- Entry point address:入口地址
- 一般程序从这里开始进入,然后最终跳转到main
- 一般黑客会修改这里的值,跳转到病毒程序
3.2. size:显示可执行程序的内存分布
size [可执行程序]
text data bss dec hex filename
2614 648 16 3278 cce mycp
- text:代码段
- data:初始化变量
- bss:未初始化变量
3.3. nm:符号列表
可以查看可执行程序的符号列表
查看有哪些全局的标签
nm [可执行程序]
0000000000004010 B __bss_start
U close@@GLIBC_2.2.5
0000000000004028 b completed.8061
w __cxa_finalize@@GLIBC_2.2.5
0000000000004000 D __data_start
0000000000004000 W data_start
0000000000001150 t deregister_tm_clones
00000000000011c0 t __do_global_dtors_aux
0000000000003d90 d __do_global_dtors_aux_fini_array_entry
0000000000004008 D __dso_handle
0000000000003d98 d _DYNAMIC
0000000000004010 D _edata
0000000000004030 B _end
U exit@@GLIBC_2.2.5
0000000000001468 T _fini
0000000000001200 t frame_dummy
0000000000003d88 d __frame_dummy_init_array_entry
000000000000216c r __FRAME_END__
U fwrite@@GLIBC_2.2.5
0000000000003f88 d _GLOBAL_OFFSET_TABLE_
w __gmon_start__
0000000000002024 r __GNU_EH_FRAME_HDR
0000000000001000 t _init
0000000000003d90 d __init_array_end
0000000000003d88 d __init_array_start
0000000000002000 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000001460 T __libc_csu_fini
00000000000013f0 T __libc_csu_init
U __libc_start_main@@GLIBC_2.2.5
0000000000001209 T main
U open@@GLIBC_2.2.5
U perror@@GLIBC_2.2.5
U read@@GLIBC_2.2.5
0000000000001180 t register_tm_clones
0000000000001120 T _start
0000000000004020 B stderr@@GLIBC_2.2.5
0000000000004010 D __TMC_END__
U write@@GLIBC_2.2.5
- T 全局函数
- D 全局变量
- d 静态变量 本文件
- t 静态函数
- U
0000000000001120 T _start
就是程序入口
3.4. strip:去掉符号表
把符号表无用的信息去掉(节省空间,特别是嵌入式设备)
strip [可执行程序]
3.5. strings:查看常量字符串
strings [可执行程序]
3.6. objdump:反汇编
objdump --help
查看命令选项
objdump -d [可执行程序]
反汇编
3.7. objcopy:将段按相应的部分拷贝出来
3.8. addr2line:把代码的地址行标出
4. 开发环境搭建
4.1. 确定目标机 主机的连接方式
- UART异步串行通信接口(串口)
- 速率低 实用性强
- USB串行通信接口
- 速度快 驱动要移植修改
- TCP/IP网络通信接口
- 速度快(10/100Mbps) 驱动要移植
- Debug Jtag调试接口
- 方便快捷 价格极高
4.2. 开发PC和开发板连接需求分析
普通 uboot kernel 传递 (通常不用串口,速度太慢,通常使用网口 TFTP (UDP))
调试 挂载 NFS (网络文件系统)
- 网络搭建
虚拟机桥接
虚拟机双网卡(虚拟机添加网卡设备)
- 网络问题排查
TCP/IP
应用层
传输层 port端口不对/端口防火墙没开
网络层 ping
物理接口
4.3. 环境搭建
- 台式环境搭建
- 路由器环境
- 双网卡
- 笔记本环境搭建
- 虚拟机配置双网卡
- 串口配置
重点说一下台式机的环境搭建
台式机和开发板接到一个路由器的lan口上
台式机里的虚拟机网卡设置为桥接,连通到路由器