交叉编译 内核编译
一·交叉编译
编译在一个平台上生成该平台的代码
交叉编译是一个平台生成另一个平台的可执行文件
例如在keli里面生成的xxx.hex文件在C51里面运行
我们在Ubuntu Linux生成的可执行文件a.out 在树莓派里面运行,而不是在Ubuntu Linux下面运行
二·为什么要交叉编译
平台不能够安装编译器,或者没有办法安装编译器 例如C51
平台资源匮乏,不能安装编译器
树莓派是不是可以不使用交叉编译
树莓派有时候因为目的平台还没有建立,连操作系统都没有,更别说编译器
操作系统也是代码,也要编译!
平台运行需要两样至少东西:bootloader(启动引导代码)以及操作系统核心
宿主机(host) :编辑和编译程序的平台,一般是基于X86的PC机,通常也被称为主机。
目标机(target):用户开发的系统,通常都是非X86平台。host编译得到的可执行代码在target上运行。
交叉编译的工具:
交叉编译器
交叉编译数据链
1.交叉编译的环境配置
(1)安装网站
https://github.com/raspberrypi/
(2)配置环境
Ubuntu配置环境变量
通过把tools-master放入linux里面
进行文件的解压
unzip
打开文件的cd tools-master
打开cd arm-bcm2708
打开cd gcc-linaro-arm-linux-gnueabihf-raspbian-x64/
打开 cd bin
环境变量 PATH
通过echo $PATH 显示当前的环境变量 进行使用
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games: 剪贴到games:这里
使用pwd 显示当前路径
/home/CLC/Pi/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
配置环境变量 临时的环境变量
export PATH=
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/CLC/Pi/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
在 games:后面添加当前路径
arm-linux-gnueabihf-gcc -v
通过该指令进行查看
查看是不是4.8.6版本的
配置永久环境变量
vi /home/CLC/.bashrc
在最后一行加入
配置临时环境变量那段话 进行使用
使用source /home/CLC/.bashrc
该指令是快速保存配置指令 马上生效文件
2.使用交叉编译
交叉编译使用
通过指令file 可以查看文件的属性
使用 arm-linux-gnueabihf-gcc dema1.c -o test_1
使用交叉编译进行编译
发送到树莓派里面
scp test_1 pi@192.168.43.58:/home/pi
输入密码后传输给树莓派 表示的是传输到树莓派的文件地址
3.带wiringPi的交叉编译的实现
首先加载一个wiringPi的文件夹
进入到文件夹中 把文件夹加载进来
使用./build
进行加载
- 正常我们先交叉编译wiringPi的库 让他变成树莓派可以使用的库,这时候交叉编译之后,链接库的格式也是正确的
- 通过 -I -L指定库的位置
- 进行编译文件的时候
arm-linux-gnueabihf-gcc dema1.c -I /home/sp/WiringPi/WiringPi/wiringPi -L./ -lwiringPi
使用 -I(大写的 i 表示当前头文件所在的目录) 使用 -L表示当前使用的库文件在当前目录下面
使用树莓派上面的库进行使用
在树莓派上进入到 /usr/lib 里面
使用 ls -l |grep wiringPi 寻找和wiringPi有关的库文件
将 树莓派库的软连接指向的文件都发送给 ubuntu
软链接概念
1.软链接有点类似于windows的快捷方式
2.在符号连接中,文件实际上是一个文本文件,其中包含了另一个文件的文件地址
3.如果你选定的位置生成文件的镜像不会占用磁盘空间
生成方法 :
ln -s libwiringPi.so.2.50 libwiringPi.so 指令是 L的小写l
指令 参数 要被链接的文件 软连接文件的名字
创建生成了libwiringPi.so 的软链接文件(相当于libwiringPi.so.2.50的快捷方式)
硬链接:ln libwiringPi.so.2.50 libwiringPi.so
它会在你选定的位置上生成一个和源文件大小相同的文件
无论是软连接还是硬链接 文件都保持同步变换
源码树
安装源码树
sudo apt-get install tree
内核的文件相当多 支持多平台多架构
编译前进行配置 进行该特定平台的支持
可能一个系统的内核编译完成后就几M的内存空间
内核编译
内核编译的目的就是为了底层代码的编写 比如使用驱动代码的编写
驱动代码的编写 驱动代码的编译的前提是需要使用一个提前编译好的内核
内核编译就必须进行配置
配置最终会生成 .config文件 .config 文件指导Makefile文件把有用的东西组装成内核
配置
解压内核文件
进入到文件夹里面
配置config
linux源码中有很多工程:
树莓派1的工程是bcmrpi_defconfig;
树莓派2、3的工程是bcm2709_defconfig。
使用源码自带的config
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
此命令功能是获取bcm2709_defconfig的配置到 .config里。
我们可以直接用工程里的配置,但这样的话可能会丢失原来使用的树莓派的配置,这里提供一个方法可以获取当前正在使用的树莓派的config。
树莓派本地的config
编译
安装必要的库:
sudo apt-get install bc
sudo apt-get install libncurses5-dev libncursesw5-dev
sudo apt-get install zlib1g:i386
sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5
1、执行menuconfig
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
指定ARM架构 指定编译器 树莓派 主要核心指令
如果没什么改的就不用执行这一步。可以直接执行编译
2、编译
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs 2>&1 | tee build.log
j4 指定多少电脑资源进行编译
zImage 指定生成的内核镜像
modules 指定驱动模块
dtbs 指定生成的配置文件
2>&1 | tee build.log 错误调试
以n进程编译。不指明几进程的话则默认以单进程编译。
编译成功后会生成 vmliunx文件
3、打包zImage文件
直接用linux源码包里的工具:
使用该代码进行打包
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
在本目录生成一个kernel_new.img文件,这个文件就是要放到sd卡中的文件。
注:网上很多地方说的用 tools/mkimage/imagetool-uncompressd.py 的方法不行!!
树莓派本地编译
安装必要的库:
sudo apt-get install bc
sudo apt-get install libncurses5-dev libncursesw5-dev
sudo apt-get install zlib1g
sudo apt-get install libc6
挂载到SD卡
将SD卡挂载到ubuntu里面
在/home/sp下面新建两个文件夹
mkdir data1
mkdir data2
放在分区下
sudo mount /dev/sdb1 data1 一个fat分区,是boot相关的内容,kernel的img
sudo mount /dev/sdb2 data2 一个是ext4分区,也就是系统的根目录分区。
安装modules, 设备驱动文件: hdmi usb wifi io …
安装modules
以下用[fat]表示boot挂载的路径,[ext4]表示ext4挂载的路径。
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=/home/sp/data2 modules_install
里面的/home/sp/data2 表示的是ext4的挂载路径
安装更新 kernel.img 文件,注意镜像名字是kernel7.img
先备份kernel7.img,防止错误删除,或者覆盖
cd /home/sp/data1
cp kernel7.img kernel7cp.img
再把编译新生成的拷贝到data1,起名kernel7.img
cp kernel_new.img /home/sp/data1/kernel7.img
检测两者的唯一序列号是否相同
md5sum kernel_new.img
md5sum /home/sp/data1/kernel7.img
复制其他相关文件
这里的/home/sp/data1 表示的是boot的挂载路径
sp@sp-virtual-machine:~/linux-rpi-4.14.y$ cp arch/arm/boot/dts/.*dtb* /home/sp/data1
sp@sp-virtual-machine:~/linux-rpi-4.14.y$ cp arch/arm/boot/dts/overlays/.*dtb* /home/sp/data1/overlays/
sp@sp-virtual-machine:~/linux-rpi-4.14.y$ cp arch/arm/boot/dts/overlays/README /home/sp/data1/overlays/
修改串口
然后再修改根目录的"cmdline.txt",将里面的内容全部替换成以下内容,以防万一,请先备份好这个文件的原内容
复制完成后打开修改串口
添加console=serial0,115200
dwc_otg.lpm_enable=0 console=tty1
添加【console=serial0,115200】root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
添加【】里面的信息进行使用串口进行登录
串口里面的数据删除 就是使用该串口进行使用