jetson-linux编译内核
本次博客记录基于x86_64平台交叉编译jetson nano的linux内核
顶层目录
首先进入到顶层目录
1 | cd /home/jym/code/linux/ec20_driver_pro |
顶层目录分布如下:
kernel_out为编译输出目标文件夹
gcc-linaro-x86_64_aarch64-linux-gnu为交叉编译器,下载地址Linaro Releases
其他为kernel_src.tar解压得到;内核相关文件在${PWD}/kernel/kernel-4.9
设置环境变量
1 | export CROSS_COMPILE_AARCH64=~/home/jym/code/linux/ec20_driver_pro/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- #尽量使用绝对路径或在内核顶层目录使用相对路径 |
设置好环境变量之后,下面有两种方法编译内核:一是英伟达官方的自动编译脚本nvbuild.sh
,在顶层目录执行以下命令即可:
1 | ./nvbuild.sh -o $PWD/kernel_out |
下面对另一种方法进行介绍
手动编译
编译的项目有:config
配置文件,Image
,dtbs
,modules
下面操作均在顶层目录下进行
生成config配置文件
1 | make -C ${PWD}/kernel/kernel-4.9/ ARCH=arm64 LOCALVERSION="-tegra" CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" O=${PWD}/kernel_out tegra_defconfig |
生成menuconfig配置
1 | make -C ${PWD}/kernel/kernel-4.9/ ARCH=arm64 LOCALVERSION="-tegra" CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" O=${PWD}/kernel_out menuconfig |
生成Image
1 | make -C ${PWD}/kernel/kernel-4.9/ ARCH=arm64 LOCALVERSION="-tegra" CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" O=${PWD}/kernel_out Image -j12 |
生成dtb
主要的设备树文件:tegra194-p2888-0001-p2822-0000.dtb
关注的目录为:kernel_src/hardware/nvidia/platform/t19x/galen/kernel-dts
关注的文件:
tegra234-p3767-0003-p3768-0000-a0.dts
1 | make -C ${PWD}/kernel/kernel-4.9/ ARCH=arm64 LOCALVERSION="-tegra" CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" O=${PWD}/kernel_out dtbs -j12 |
/home/ada/jetson/nvdia_35_4/kernel_src/hardware/nvidia/platform/t23x/p3768/kernel-dts/tegra234-p3767-0003-p3768-0000-a0.dts
生成的文件在这:./kernel_out/arch/arm64/boot/dts/nvidia/tegra234-p3767-0003-p3768-0000-a0.dtb
编译模块
编译
1 | make -C ${PWD}/kernel/kernel-4.9/ ARCH=arm64 LOCALVERSION="-tegra" CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" O=${PWD}/kernel_out modules -j12 |
安装模块 按照linux内核文件架构安装在kernel_out中
1 | make -C ${PWD}/kernel/kernel-4.9/ ARCH=arm64 LOCALVERSION="-tegra" CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" O=${PWD}/kernel_out INSTALL_MOD_STRIP=1 modules_install INSTALL_MOD_PATH=modules |
清除构建
1 | make -C ${PWD}/kernel/kernel-5.10/ ARCH=arm64 LOCALVERSION="-tegra" CROSS_COMPILE="${CROSS_COMPILE_AARCH64}" O=${PWD}/kernel_out clean |
移植移远4G模块
修改内核文件
option.c
修改 [KERNEL_SRC] /kernel/kernel-5.10/drivers/usb/serial/option.c 文件
1.添加USB设备VID和PID
1 | static const struct usb_device_id option_ids[] = { |
2.添加掉电恢复机制
1 | static struct usb_serial_driver option_1port_device = { |
usb_wwan.c
修改 [KERNEL_SRC] /kernel/kernel-5.10/drivers/usb/serial/usb_wwan.c 文件
添加零包机制
1 | static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, |
配置并编译内核
在下载完内核源码之后,我们可以首先手动编译一次,这样我们后续修改文件再次编译内核的时候速度会更快。
执行命令按照手动编译步骤进行即可。
- 生成config配置文件
- 生成menuconfig配置
- 生成Image
- 编译模块
在我们配置menuconfig时按照默认配置是可以编译出ko文件的,有时候我们需要编译出特定几个模块,需要在menuconfig中手动进行配置。
在menuconfig下按下/
键为查找(同vim) 比如我们需要如下图所示USB driver for GSM and CDMA modems
,我们可以利用vscode查找功能在linux内核源码中查找对应模块。
如下图为查找到内容,此时我们直接在menuconfig中键入USB_SERIAL_OPTION
进行查询即可对其进行操作
同样,笔者在第一次编译时并未编译出来qcserial.ko
文件,我们直接在vscode中暴力搜索qcserial,
从图中可以看到其对应配置为CONFIG_USB_SERIAL_QUALCOMM
,选择它按下M即可将其编译成模块,便于后续移植。
配置好之后再次从menuconfig后面执行一遍手动编译操作即可
移植加载内核
将对应.ko文件复制到内核对应文件夹下使用uname -r
查看对应内核版本
1 | $sudo cp option.ko /lib/modules/4.9.253-tegra/kernel/drivers/usb/serial |
加载模块
1 | $sudo depmod -a |
驱动测试
1 | $sudo modprobe usbmon # 加载usbmon驱动模块 |