驱动代码的编写需要一个提前编译好的内核,编译内核就必须配置内核,配置的最终目标是生成 .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
使用源码自带的 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
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
通过dmesg
查看
/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 信息已经改变