首先参考 Ubuntu 16.04 (x64)树莓派B+ (Raspberry Pi B+)源代码编译 保证能够成功编译标准内核的源代码,然后切换到实时内核分支,并执行如下编译命令:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$ export PATH=$PATH:~/rpi/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin $ cd ~/rpi/rpi-linux/ $ git checkout rpi-4.14.y-rt $ git reset --hard $ KERNEL=kernel $ make clean $ make mrproper $ rm -rf .config #调整内核切换频率,增加实时性 $ sed -i '$a\CONFIG_HZ_1000=y' arch/arm/configs/bcmrpi_defconfig #Raspberry Pi Zero W的CPU是BCM2835 $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcmrpi_defconfig $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j8 $ mkdir rt_kernel $ make modules_install ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=./rt_kernel -j8 $ make dtbs_install ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_DTBS_PATH=./rt_kernel -j8 $ ./scripts/mkknlimg ./arch/arm/boot/zImage ./rt_kernel/kernel.img |
安装编译好的内核
Ubuntu
下面,SD
卡会自动挂载,默认挂载到了/media/
目录下面,如果是使用NOOBS
安装的话,系统目录是固定的,执行如下命令拷贝到目标SD
卡上面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ cd ~/rpi/rpi-linux #备份需要修改的文件 $ mv /media/`whoami`/boot/kernel.img /media/`whoami`/boot/kernel_old.img $ mv /media/`whoami`/boot/overlays /media/`whoami`/boot/overlays.old #拷贝内核 $ cp rt_kernel/kernel.img /media/`whoami`/boot/kernel.img #拷贝硬件配置 $ cp rt_kernel/bcm2835*.dtb /media/`whoami`/boot/ #拷贝overlays $ cp -r rt_kernel/overlays /media/`whoami`/boot/ #拷贝内核模块 $ sudo cp -r rt_kernel/lib/modules/* /media/`whoami`/rootfs/lib/modules/ #卸载设备 $ sudo umount -A -R -a /media/`whoami`/boot |
借助编译环境,单独编译内核模块
有时,我们需要单独编译新下载的内核驱动,这个时候,就可以使用如下的方式进行单独内核模块的编译。
下面,我们以ASIX AX88772
系列的USB
有线网卡驱动的编译为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$ export PATH=$PATH:~/rpi/rpi-tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin $ cd ~/rpi/rpi-linux # wget https://www.mobibrw.com/wp-content/uploads/2018/09/AX88772C_772B_772A_760_772_178_LINUX_DRIVER_v4.22.0_Source.tar.bz2 $ wget http://www.asix.com.tw/FrootAttach/driver/AX88772C_772B_772A_760_772_178_LINUX_DRIVER_v4.22.0_Source.tar.bz2 $ tar xvf AX88772C_772B_772A_760_772_178_LINUX_DRIVER_v4.22.0_Source.tar.bz2 $ cd AX88772C_772B_772A_760_772_178_LINUX_DRIVER_v4.22.0_Source $ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -C ../ M=`pwd` #当前目录下就会生成 asix.ko 这个内核模块,生成的内核模块拷贝到指定的目录即可正常工作 |
解决已知问题
使用上面的命令安装完成内核后,目前(2018.09.26
)遇到的问题为,当插入ASIX AX88772
系列的USB
有线网卡之后,会导致内核崩溃,启动失败。
设备信息如下:
1 |
Bus 001 Device 034: ID 0b95:7720 ASIX Electronics Corp. AX88772 |
初步怀疑是USB
设备的驱动依赖关系不正确导致内核崩溃。
目前的临时解决方法为要求设备启动时候优先加载USB
设备相关的驱动,而不是等到网卡插入的时候再去加载。
也就是在/boot/config.txt
文件尾部新增加一行dtoverlay=dwc2
。这段代码本来是为树莓派通过USB
访问网络的虚拟网卡准备的(是的,你没看错,树莓派本身可以不借助网卡直接通过USB
接口跟电脑共享方式上网,不过需要设置一堆东西,最简单的还是外接真正的USB
网卡)。我们加载这个模块,但是并不使用这个功能,造成的结果就是重新调整了模块加载顺序,规避了后续的问题。
1 |
$ sed -i '$a\\ndtoverlay=dwc2' /media/`whoami`/boot/config.txt |
上述修改后,依旧存在动态插拔网卡,设备会重启的问题,不过已经不影响正常使用。