Jetson 内核模块编译与板端验证记录

Jetson 内核模块编译与板端验证记录

记录日期:2026-10-05(依据本次对话中的终端输出整理;实际执行的钟表时间未记录)

实验对象:最小内核模块 led.c → led.ko;代码通过日志演示模块加载和卸载,尚未控制实体 LED 。

相关课程笔记:内核模块的测试:从三要素到验证。

证据边界:下文列出的版本、命令和输出来自本次实际记录。模块从虚拟机传到开发板的具体命令、IP 和交叉编译器完整路径没有出现在终端记录中,不作为已验证事实。

1. 本次实验完成了什么

在 x86_64 Ubuntu 虚拟机中,先识别出当前 Ubuntu 与 Jetson 使用的不同内核 ,再用 Jetson 的内核构建目录交叉编译出 AArch64 led.ko。模块传到 Jetson 后,板端 insmod、lsmod、dmesg、rmmod 的输出证明加载入口和卸载入口都执行成功。

text 复制代码
Ubuntu 虚拟机:x86_64 / 5.15.0-139-generic
        │ 交叉编译:Jetson 4.9.253-tegra 构建目录 + ARCH=arm64
        ▼
led.ko:AArch64 / vermagic 4.9.253-tegra
        │ 文件已到达 Jetson 的 /home/aidb
        ▼
Jetson:aarch64 / 4.9.253-tegra → 加载 → 查日志 → 卸载

2. 先分清虚拟机与开发板

环境 终端提示符 uname -r uname -m 用途
Ubuntu 虚拟机 yhai@yhai:~/sharef/LED$ 5.15.0-139-generic x86_64 编辑和交叉编译模块。
Jetson 开发板 aidb@ubuntu:~$、aidb@linux:~$ 4.9.253-tegra aarch64 加载并运行最终模块。

开发板的 /proc/version 还显示:4.9.253-tegra、SMP PREEMPT,内核由 Linaro GCC 7.3.1 编译。在虚拟机里运行 uname 只能得到虚拟机的信息;要确认目标内核,必须在开发板终端运行。

3. 选择匹配的内核构建目录

老师 Makefile 中的 KERNELDIR ?= ~/linux 是老师自己的路径。最开始在虚拟机中用 /lib/modules/$(uname -r)/build 得到:

text 复制代码
/usr/src/linux-headers-5.15.0-139-generic

这可以编译给 Ubuntu 虚拟机加载 的模块,但生成文件显示 ELF ... x86-64,modinfo -F vermagic led.ko 是 5.15.0-139-generic SMP mod_unload modversions,所以不能把它当作 Jetson 模块。

进一步查到两个 4.9.253-tegra 候选目录:

候选目录 已核对的情况 本次决定
/home/yhai/bsp/Linux_for_Tegra/rootfs/usr/src/linux-headers-4.9.253-tegra-ubuntu18.04_aarch64/kernel-4.9 有 Makefile、.config、Module.symvers、include/generated/autoconf.h;其中 scripts/mod/modpost 是 ARM aarch64 程序。 本次编译主机是 x86_64,不选这个目录。
/home/yhai/bsp/Linux_for_Tegra/source/public/kernel/kernel-4.9 同样有上述构建文件;kernel.release 为 4.9.253-tegra;其中 scripts/mod/modpost 是 x86-64 程序。 本次选为 KERNELDIR。

在 ~/sharef/LED/Makefile 中,将老师示例路径换为:

make 复制代码
KERNELDIR := /home/yhai/bsp/Linux_for_Tegra/source/public/kernel/kernel-4.9

KERNELDIR 指目标内核的构建目录 ,不是 led.c 所在目录,也不是虚拟机当前运行内核的头文件目录。这里的 Module.symvers、.config 等文件已存在;仅找到一个叫 kernel-4.9 的文件夹,并不足以证明它可用于外部模块编译。

4. 虚拟机中的编译记录

最初在 ~/sharef 执行 make,报"没有指明目标并且找不到 makefile";进入包含 Makefile 与 led.c 的 ~/sharef/LED 后,才开始模块编译。

切换目标架构前,先清理此前编给 x86-64 的产物,然后在虚拟机执行:

bash 复制代码
cd ~/sharef/LED
make clean
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
file led.ko
modinfo -F vermagic led.ko

关键构建输出:

text 复制代码
make -C /home/yhai/bsp/Linux_for_Tegra/source/public/kernel/kernel-4.9 M=/mnt/hgfs/ShareFolder/LED modules
CC [M]  /mnt/hgfs/ShareFolder/LED/led.o
MODPOST 1 modules
LD [M]  /mnt/hgfs/ShareFolder/LED/led.ko

产物检查结果:

text 复制代码
file led.ko
→ ELF 64-bit LSB relocatable, ARM aarch64

modinfo -F vermagic led.ko
→ 4.9.253-tegra SMP preempt mod_unload modversions aarch64

编译时出现"led.o 的修改时间在未来 0.11 秒后"和"检测到时钟错误"提示,发生在 VMware 共享目录 /mnt/hgfs/ShareFolder/LED。本次 make 仍生成了 AArch64 模块,随后也在板端成功加载;若以后出现增量编译结果异常,可把源码放到 Ubuntu 本地文件系统重新清理、编译。本次未记录交叉编译器的完整路径及 --version 输出。

5. 文件传到板上与启动方式

板端命令在 /home/aidb 成功使用 ./led.ko,说明该文件当时已在这个目录。实际传输命令未保留在本次记录中;后续复现实验时,若板上 SSH 服务和网络可用,可从虚拟机使用:

bash 复制代码
scp ~/sharef/LED/led.ko aidb@<板子IP>:/home/aidb/

老师在 U-Boot 中配置的是 NFS 启动/根文件系统 ,便于板子访问主机文件。本次验证只需要让 Linux 板端读到 .ko,不需要为了加载模块而改 U-Boot 的 bootargs、bootcmd。insmod、lsmod、rmmod 都是在板子启动后的 Linux shell 中执行的。若已经有可用 NFS,共享它传文件也可以;本次记录不把 NFS 启动视为已执行步骤。

6. Jetson 板端验证记录

在Jetson 开发板 的 aidb@linux:~$ 提示符下:

bash 复制代码
cd /home/aidb
sudo insmod ./led.ko
lsmod | grep '^led '
sudo dmesg | tail -n 20
sudo rmmod led
sudo dmesg | tail -n 20

实际 lsmod 输出:

text 复制代码
led                     1454  0

这说明模块名 led 当时在已加载列表中。1454 是内核报告的模块大小,最后的 0 是使用计数;0 不代表初始化函数没有运行。

与本模块有关的实际内核日志如下;方括号内是开机后的秒数,不是钟表时间:

text 复制代码
[  435.371220] led: loading out-of-tree module taints kernel.
[  435.376911] led init yhai 1
[  440.212315] led exit
[  571.554719] led init yhai 1
[  571.789900] led exit

435---440 秒是先前的一轮加载与卸载;本次展示的第二轮在 571 秒加载,随后卸载。insmod 和 rmmod 均未报错;入口日志与退出日志分别出现。out-of-tree module taints kernel 是内核记录外部模块的提示,本次并非加载失败。

7. 结果、限制与复现要点

验收项 结果与证据
目标架构正确 file led.ko 显示 ARM aarch64,与板端 uname -m 一致。
目标内核版本正确 vermagic 以 4.9.253-tegra 开头,与板端 uname -r 一致。
模块加载 insmod 无报错;lsmod 有 led;dmesg 有 led init yhai 1。
模块卸载 rmmod 无报错;dmesg 新增 led exit。卸载后的 lsmod 空结果未单独留存。
LED 硬件控制 未验证。当前示例只打印生命周期日志,不含已确认的 GPIO 控制证据。

以后修改 led.c 再试,应先卸载板上的旧模块,在虚拟机清理并重新交叉编译,核对新 .ko 的架构和 vermagic,再覆盖板端文件并重新加载。这样可避免把旧产物或给虚拟机编的 x86-64 模块误当成板端新版本。

相关推荐
aixingkong9212 小时前
Agentic AI时代的处理器算力需求和Nvidia、ARM、AMD等大厂的回答
arm开发·人工智能
女神下凡14 小时前
芯参谋(38):NAND_MCP_电路设计指南
arm开发·单片机·嵌入式硬件·设计规范
剑指offer.19 小时前
ARM裸机开发-SPI
arm开发·嵌入式硬件·嵌入式·arm
sunoo-22920 小时前
【ARM嵌入式学习笔记第十天】i.MX6ULL eLCDIF控制器驱动RGB LCD全解析(硬件原理+寄存器配置+裸机代码)
arm开发·笔记·学习
狂奔蜗牛(bradley)21 小时前
把 EtherCAT 初始化从 FPGA 搬到 ARM:命令通道的接口设计与11个坑
arm开发·人工智能·fpga开发·架构
女神下凡2 天前
芯参谋(37):EEPROM_电路设计指南
arm开发·单片机·嵌入式硬件·fpga开发·设计规范
女神下凡3 天前
芯参谋(30):EMMC eMCP 软件设计规范
arm开发·单片机·嵌入式硬件·设计规范
SKH.3 天前
ARM-uart
arm开发·单片机
AOI小白新手上路3 天前
韦东山《ARM 架构与编程》基于I.MX6ULL 3-1 硬件知识_LED 原理图 · 学习笔记
arm开发·学习·架构