先给出一个靠谱的参考链接,我整个内核编译的步骤基本都是按照这个来的。
结合个人情况看每一步采用哪种方法。
我的目标:基于Xavier 35.1.0内核版本使能pps驱动。
准备:Xavier开发套件(这个谁都有,不然你也不可能做这个事),一台linux系统的电脑(专业一点叫做Host)用来给Xavier刷系统,以及各种连接线不多说。
开发环境准备:
系统源码,交叉编译工具链(cross compile toolchain)
接下来详细说这几个东西的获取。
系统源码和工具链都是在官网下载的。
我这里因为内核版本是35.1.0,所以我源码和工具都是35.1.0 release note中的,地址:
Jetson Linux 35.1 | NVIDIA Developer
如果你的版本和我不一致,你可以在这里找到你版本:
Jetson Linux Archive | NVIDIA Developer
到这你应该可以看到如下的页面内容了:
将红框中的四个文件下载下来,下载完应该是这四个:
三个源码包。一个编译工具链。
这里要说明的是工具链问题:下载的工具链一定要和源码版本对应,也就是说是同一页面下的,网上有很多说用什么glic-7.3版本的,这种说法不正确,亲测刷出来后无法进入桌面,会报一个infuse之类的错误。
OK,到这里一切已经准备就绪,可以操作了!
1. 解压工具链
找到工具链压缩包所在的位置,执行:
sudo tar -xzf aarch64--glibc--stable-final.tar.gz
2. 解压源码
将三份源码放到同一目录下,依次执行:
sudo tar xpf Jetson_Linux_R35.1.0_aarch64.tbz2
cd Linux_for_Tegra/rootfs/
sudo tar xpf ../../Tegra_Linux_Sample-Root-Filesystem_R35.1.0_aarch64.tbz2
cd ..
sudo ./apply_binaries.sh
在这里可能会让你安装static menu什么的,直接apt install 安装就好,如果报错,就apt update一下就ok。
然后在cd到public_sources.tbz2所在的目录,执行
tar -xjf public_sources.tbz2
第一层解压之后会出现一个public_sources的文件夹,继续解压第二层文件
tar -xjf public_sources/kernel_src.tbz2
解压完这层以后,目录下会出现kernel的文件夹,这个就是源码了。打开kernel会看到kernel-5.10 这就是Linux5.10的源码。 源码目录层级如下:
作为参考。
3. 配置环境变量
TOOLCHAIN_PREFIX=/opt/linaro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-JETSON_XAVIER_NX_KERNEL_SOURCES=$HOME/xavierNX_l4t325/Linux_for_Tegra/sourcesTEGRA_KERNEL_OUT=$JETSON_XAVIER_NX_KERNEL_SOURCES/build KERNEL_MODULES_OUT=$JETSON_XAVIER_NX_KERNEL_SOURCES/modulesexport JETPACK_4_5_L4T=$HOME/xavierNX_l4t325/Linux_for_Tegra/
上面是参考链接里面的,然后给出我自己的作为参考,我是写在.bashrc里的:
这里不多说,只是找到几个目录所在的位置而已。
4. cd到kernel目录
mkdir build
mkdir modules
sudo make -C kernel-5.10/ ARCH=arm64 O=$TEGRA_KERNEL_OUT LOCALVERSION=-tegra CROSS_COMPILE=${TOOLCHAIN_PREFIX} tegra_defconfig
如果成功可以看到xxx has been written.config
sudo make -C kernel-5.10/ ARCH=arm64 O=$TEGRA_KERNEL_OUT LOCALVERSION=-tegra CROSS_COMPILE=${TOOLCHAIN_PREFIX} -j8 Image
sudo make -C kernel-5.10/ ARCH=arm64 O=$TEGRA_KERNEL_OUT LOCALVERSION=-tegra CROSS_COMPILE=${TOOLCHAIN_PREFIX} -j8 dtbs
sudo make -C kernel-5.10/ ARCH=arm64 O=$TEGRA_KERNEL_OUT LOCALVERSION=-tegra CROSS_COMPILE=${TOOLCHAIN_PREFIX} -j8 modules
make -C kernel/kernel-5.10/ ARCH=arm64 O=$TEGRA_KERNEL_OUT LOCALVERSION=-tegra INSTALL_MOD_PATH=$KERNEL_MODULES_OUT modules_install
如果你很幸运,到这编译都没报错,那你就可以直接将编译生成的Image和dtb文件复制到系统中,就完成了一次内核打补丁(这块后面细讲)。
5. 然后开始刷机:
刷机流程官网有标准文档,按照操作执行即可。文档链接如下:
Quick Start — Jetson Linux<br/>Developer Guide 34.1 documentation
基本流程就是同步下环境后进入recovery模式,然后刷入镜像。有一个点要说就是如何进入recovery模式:
- 载板关机,用tyte-c转USB将 载板与IPC连接,Type-C一端接载板,同时按下载板上的recovery和reset按键,位置在载板中间,两个白色小按钮。然后载板开机,能看到三个灯亮起说明开机完毕,等待三秒后先松开reset,再松开recovery。这时应该能在IPC端用lsusb命令查看到Nvidia Corp这一项,说明载板已经进入recovery模式,可以开始刷机了。
- IPC端进入到xavier-32.6.1,进入linux_for_tegra文件夹,执行命令:sudo ./flash.sh jetson-agx-xavier-devkit mmcblk0p1
以上是标准Xavier内核编译和刷机流程,下面是使能pps模块的部分:
PPS模块在内核中有驱动源码并且编译选项默认打开,如要检查自己的编译选项是否打开,可以在kernel-5.10/arch/arm64/configs/defconfig这个文件中查看CONFIG_PPS_DEBUG CONFIG_PPS_CLIENT_GPIO选项是否置为true,若没有,需要手动修改为true。
我的情况是,刚刷完系统后dmesg -w |grep pps去查看pps驱动情况会报错:
failed to register IRQ xxx as PPS source
failed to acquire IRQ
解决办法是:
修改pps-gpio.c代码,代码在kernel-5.10/drivers/pps/clients目录下:
在这里将 return -EINVAL改为 return ret
另外需要在dtsi中定义pps-gpio的设备,目录是Linux_for_Tegra/source/public/hardware/nvidia/soc/t19x/kernel-dts/tegra194-soc,修改
tegra194-soc-base.dtsi,加入如下内容:
pps_gpio {
compatible = "pps-gpio";
gpios = <&tegra_aon_gpio TEGRA194_AON_GPIO(BB, 0) GPIO_ACTIVE_HIGH>;
};
然后编译dtb,与上面的Image一起复制到Xavier系统中。
sudo cp Image /boot/
sudo cp tegra194-p2888-0001-p2822-0000.dtb /boot/dtb/kernel_tegra194-p2888-0001-p2822-0000.dtb
然后reboot即可。