目录:
驱动代码的编写需要一个提前编译好的内核,编译内核就必须配置内核,配置的最终目标是生成 .config 文件,该文件指导 Makefile 去把有用东西组织成内核
1.获取编译所需源码:
点击进入官方网址.
所需文件:
linux:内核源码,可以在branches下进行版本的选择。
tools:编译内核和其他源码所需的工具——交叉编译器等。
linux:
tools:
2.配置环境变量:
(1)手动配置环境变量:
①获取当前环境变量的值:echo $PATH
②获取交叉编译工具链所在路径:pwd
③手动配置环境变量:export PATH=
echo $PATH+pwd
tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin // 将该文件配置入环境变量
arm-linux-gnueabihf-gcc -> arm-linux-gnueabihf-gcc-4.8.3 // 使用该交叉编译工具
(2)自动配置环境变量:
①进入工作目录:cd
②进入工作目录下的 .bashrc 隐藏文件:vi .bashrc
③修改 .bashrc 隐藏文件内容,文件最后一行添加对应内容:export PATH=
echo $PATH+pwd
④保存文件
3.配置config:
linux 源码中有很多工程:
- 树莓派1的工程是
bcmrpi_defconfig
- 树莓派2、3的工程是
bcm2709_defconfig
(1)使用源码自带的 config:
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
// 获取 bcm2709_defconfig 的配置到 .config 里,此命令在 linux-rpi-4.14.y 目录下执行
解释:
ARCH=arm
:指定 ARM 架构CROSS_COMPILE=arm-linux-gnueabihf-
:指定编译器KERNEL=kernel7
:树莓派make bcm2709_defconfig
:主要核心指令
我们可以直接用工程里的配置,但这样的话可能会丢失原来使用的树莓派的配置,这里提供一个方法可以获取当前正在使用的树莓派的 config
(2)获取当前树莓派的 config:
①已经开机的树莓派上会有这个节点:/proc/config.gz
,从这个节点可以获取本树莓派的 config
如果没有这个节点的话则需要先加载模块:sudo modprobe configs
②把config.gz
内容复制到要编译的电脑上
③解压并保存为 .config 文件:zcat config.gz > .config
!!注意:必须在 linux 环境下解压,否则会乱码
④把此 config 文件复制到 linux 源码的根目录
4.编译:
(1)安装必要的库:
!!安装必要的库:
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
(2)执行 menuconfig:
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make menuconfig
(3)编译:
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage modules dtbs
// 此过程持续时间较长
解释:
-j4
:指定调用多少电脑资源进行编译zImage
:生成内核镜像modules
:生成驱动模块dtbs
:生成配置文件
!!内核源码树目录中多出vmlinux
文件,说明编译成功,目标zImage
镜像在arch/arm/boot
路径中
(4)打包 zImage 文件:
直接用 linux 源码包里的工具:
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
在本目录生成一个kernel_new.img
文件,这个文件就是要放到 SD 卡中的文件
5.挂载树莓派 sd卡,并安装编译出的 DIRECTLY 到 sd卡:
把树莓派的 sd 卡插入 ubuntu 系统的虚拟机,树莓派的sd卡有两个分区:
一个是 fat 分区,是 boot 相关的内容,kernel 的 img 文件就放在这个分区里;
另一个是 ext4 分区,也就是系统的根目录分区。
(1)创建两个文件夹:
mkdir data1
mkdir data2
(2)挂载:
sudo mount /dev/sdb1 data1
sudo mount /dev/sdb2 data2
/dev/sdb1
(fat 分区)挂载到 data1
/dev/sdb2
(ext4分区)挂载到 data2
(3)向 data2(ext4分区)安装modules
(设备驱动文件):
此操作须在内核源码linux-rpi-4.14.y
路径中完成
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=/home/xxx/data2 modules_install
!!注意 data2(ext4分区)路径
(4)更新 kernel.img 文件:
!!注意:镜像名字是kernel7.img
,建议先备份再更新
①备份kernel7.img
(在原目录备份即可,令起名字)(此文件在 fat 分区)
②再把刚刚编译新生成的镜像kernel_new.img
拷贝cp
到 data1(fat分区) 中的kernel7.img
文件
③查看文件编码检查拷贝是否完整:
md5sum kernel_new.img // 查看 kernel_new.img 文件编码
md5sum kernel7.img // 查看 kernel7.img 文件编码
④拷贝配置文件(arch
文件在内核源码linux-rpi-4.14.y
路径中):
cp arch/arm/boot/dts/.*dtb* /home/xxx/data1
cp arch/arm/boot/dts/overlays/.*dtb* /home/xxx/data1/overlays
cp arch/arm/boot/dts/overlays/README /home/xxx/data1/overlays
!!注意路径
更新完成后将 SD卡插回树莓派即可开机,开机后可以用uname -a
命令查看 kernel 信息已经改变