一、驱动编写
驱动代码编译需要一个提前编译好的内核,编译内核就必须配置,配置的最终目标会生成 .config文件,该文件就是去指导Makefile把有用的东西组织生成内核
第一种方式:
cp厂家 .config .config
芯片厂家会提供Linux内核源码,比如树莓派
第二种:
通过make memuconfig一项一项配置,一般是根据厂家提供的config配置
第三种:
完全自己编写
二、交叉编译Linux内核:
2.1安装所需和依赖的交叉编译工具:
(查看内核:通过在Pi里运行“file /sbin/busybox” 或其他可执行程序可查看当前内核是32位还是64位的。如果是32位的,会显示如下32-bit 字段,否则为64位的)
32位:
$ sudo apt install crossbuild-essential-armhf
64位主机:
$ sudo apt install crossbuild-essential-arm64
2.2获取源码:
利用git获取当前git仓库默认Pi的内核源码,如下所示:
$ git clone --depth=1 https://github.com/raspberrypi/linux
你也可以选择下载自己所需的内核源码版本,如需要下载4.14.y,可利用branch参数下载,如下:
$ git clone --depth=1 https://github.com/raspberrypi/linux --branch rpi-4.14.y
2.3配置内核:
32位主机
树莓派2, Pi 3, Pi 3+
在内核源码路径下运行(find 、-name *_defconfig搜索内核文件)
KERNEL=kernel7
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2709_defconfig
树莓派4b
在内核源码路径下运行
KERNEL=kernel7l
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make bcm2711_defconfig
树莓派1, Pi Zero, Pi Zero W
在内核源码路径下运行
KERNEL=kernel
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig
64位主机:
Pi 2, Pi 3, Pi 3+, 和3系列
KERNEL=kernel8
ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make bcmrpi3_defconfig
Raspberry Pi 4
KERNEL=kernel8
ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make bcm2711_defconfig
2.4安装ncurses库:
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
驱动两种加载方式:
* 编译进内核 zImage包含了驱动
M 模块方式生成驱动文件xxx.ko ,系统启动后通过命令inmosd xxx.ko加载
2.5编译:
32位内核
ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make -j4 zImage
//指定ARM架构 指定编译器 树莓派
modules dtbs
//j4占用多少内核资源
//zImage生成内核镜像
//modules 生成驱动模块
//dtbs生成配置文件
64位内核
ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- make -j4 zImage modules dtbs
编译成功,源码目录会产生vmlinux文件,失败则不产生
成功后,目标zImage镜像再arch/arm/boot文件夹下
打包(可跳过):
用linux源码包里的工具打包zImage成树莓派可用的xxx.img:
./scripts/mkknlimg arch/arm/boot/zImage ./kernel_new.img
2.6数据拷贝
创建文件夹 data1,data2
挂载U盘
lsblk 查看设备节点
sudo mount /dev/sdb1 data1 //fat分区,是boot相关内容
sudo mount /dev/sdb2 data2 //ext4分区,系统根目录
2.7安装modules(设备驱动文件,例如hdmi,无线网,io,usb等等)
sudo ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- KERNEL=kernel7 make INSTALL_MOD_PATH=[ext4] modules_install
2.8安装更新kernel.img
如果是32位内核,运行如下命令
sudo env PATH=$PATH make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=/media/linux/rootfs modules_install
如果是64位内核,运行如下命令:
sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INST
2.9备份
cp kernel7.img kernel7old.img
备份原理SD卡中的旧内核, 并将新内核和设备树配置文件到SD卡中:
如果是32位内核,运行如下命令:
sudo cp /home/tianchong/data1/$KERNEL.img /home/tianchong/boot/$KERNEL-backup.imgsudo cp arch/arm/boot/zImage /home/tianchong/data1/$KERNEL.imgsudo cp arch/arm/boot/dtshome/tianchong/data1sudo cp arch/arm/boot/dts/overlays/*.dtb* /home/tianchong/data1/overlays/sudo cp arch/arm/boot/dts/overlays/README /home/tianchong/data1/overlays/sudo umount /home/tianchong/data1sudo umount /home/tianchong/data2
64位内核,运行如下命令:
sudo cp /home/tianchong/data1/$KERNEL.img /home/tianchong/data1/$KERNEL-backup.imgsudo cp arch/arm64/boot/Image /home/tianchong/data1/$KERNEL.imgsudo cp arch/arm64/boot/dts/broadcom/*.dtb /tianchong/home/data1/sudo cp arch/arm64/boot/dts/overlays/*.dtb* /home/tianchong/data1/overlays/sudo cp arch/arm64/boot/dts/overlays/README /home/tianchong/data1/overlays/sudo umount /home/tianchong/data1/sudo umount /home/tianchong/data2
也可以不备份旧的内核,而是通过重命令编译出来的内核名称,如将编译出来的img改为kernel-new.img,然后修改config.txt的配置文件种的kernel字段,如下:
kernel=kernel-new.img
这么做的好处是保证原有的内核不被破坏,如果新的内核无法启动,只需要将config.txt的kernel字段改回来即可。
最后,将TF卡插回Pi上,然后启动Pi即可.