时间轴
时间轴
2026-07-18
init
源码
1 | git clone https://github.com/NVIDIA/open-gpu-kernel-modules.git |
交叉工具链
本文使用 Arm GNU Toolchain 11.2-2022.02(aarch64-none-linux-gnu-三元组)。
ARM目前总共发布了8种架构:ARMv1、ARMv2、ARMv3、ARMv4、ARMv5、ARMv6、ARMv7、ARMv8。
针对于支持ARMv8指令集的处理器可以使用-march=armv8-a参数编译代码,ARM GNU编译器可通过下面的链接下载
推荐使用ARM官网的编译器,它是Portable的,解压后即可使用。
本文使用的是11.2版本的交叉编译器
可以将其添加到环境变量
1 | # ~/.bashrc或~/.bash_profile |
使用11.2.1版本的aarch64-none-linux-gnu-gcc

如果工具链三元组是
aarch64-linux-gnu-(如 Ubuntu 的gcc-aarch64-linux-gnu包),把下面所有aarch64-none-linux-gnu-替换成aarch64-linux-gnu-即可。
编译
1 | make -j$(nproc) modules \ |
要点:
- ARCH=arm64 给 Kbuild,TARGET_ARCH=aarch64 给 NVIDIA 的 utils.mk(两者不能混)。
- 工具链通过 PATH + 显式 CC/CXX/LD/AR 双保险,因为 utils.mk 不读 CROSS_COMPILE。
- SYSSRC/SYSOUT 指向已用同一工具链配置好的 linux-5.10.238。
要清理的话:
1 | make clean \ |
1 | make -j$(nproc) modules \ |
说明
- 原生编译不需要 CROSS_COMPILE,工具用本机 gcc 即可。仍要显式传 CC/CXX/LD/AR,因为 utils.mk 不读 CROSS_COMPILE。
- 和 arm64 的区别只在 ARCH/TARGET_ARCH:arm64 时是 ARCH=arm64 + TARGET_ARCH=aarch64;x86_64 时两者都是 x86_64。注意 utils.mk 里没有叫 arm64 的 TARGET_ARCH,只有 aarch64。
清理
1 | make clean \ |
目录结构
1. 顶层目录结构
1 | open-gpu-kernel-modules/ |
核心机制:两层构建模型
理解该仓库的关键在于其两层构建模型。这个仓库并不是一个单一的 Linux 内核模块,而是由 NVIDIA OS 无关核心 与 Linux 内核适配层 拼装组合,最终生成 5 个 .ko 模块。

第一层产物: 产生在
src/nvidia/_out/Linux_<ARCH>/nv-kernel.o。代码使用-ffreestanding和-fno-stack-protector编译,从而能在不同的操作系统(如 Linux、FreeBSD 等)间复用核心逻辑。第二层: 将第一层生成的 .o 文件当作“黑盒二进制”链接进最终的 .ko 模块中,并包装上 Linux 专属的钩子代码。
2. src: OS 无关核心
(约 211 万行)
1 | src/ |
3.src/nvidia/src/kernel/gpu/子目录(GPU IP 引擎)
这是驱动最核心的硬件控制部分,按硬件引擎划分:
- gr/:Graphics(光栅化/着色/渲染核心)
- fifo/:命令提交队列管理
- ce/:Copy Engine(高性能内存拷贝引擎)
- intr/:中断处理
- sec2/:安全引擎
- falcon/:Falcon 微控制器核心框架
- gsp/:★ GSP(GPU System Processor) 核心
- fsp/:Firmware Security Processor
- gsplite/:轻量级 GSP 逻辑
- pmu/:性能监控单元
- nvdec/ nvenc/ nvjpg/ ofa/:视频编解码及光流加速引擎
- bif/ bus/:PCIe 总线接口及总线控制
- mem_mgr/ mem_sys/ mmu/ mig_mgr/:显存管理、MMU 页表、MIG 实例切分
- disp/:显示输出控制
- perf/ hwpm/ rc/ timer/ …:性能、硬件监控、Reset 恢复及定时器
架构演进背景: 现代 NVIDIA GPU 的 RM(资源管理器)核心主要运行在 GPU 内部的 GSP(一个 RISC-V 微处理器)上。src/nvidia 里的很大一部分代码实际上就是 GSP 固件本身的源码——这也是 NVIDIA 在 2020 年后逐步走向开源的关键底层演进。
4. kernel-open/ Linux 适配层
(约 22 万行)
1 | kernel-open/ |
conftest.sh机制: 这是 NVIDIA 驱动能“一份源码兼容无数内核版本”的核心秘密。在编译前,它会针对目标内核进行大量的片段编译测试(例如检测是否存在 kmem_cache_create_usercopy、pgprot_t 等)。测试结果会被写入 conftest/headers.h,随后源码中通过#if NV_IS_ENABLED(...)宏来条件编译对应的兼容代码。
最终生成的内核模块
| 模块名称 | 主要作用 | 主要源码构成 |
|---|---|---|
nvidia.ko | 主驱动核心:创建/dev/nvidia*设备节点,提供核心 ioctl 业务入口。 | kernel-open/nvidia/+src/nvidia/编译出的nv-kernel.o |
nvidia-modeset.ko | 显示模式设置:控制分辨率、刷新率、多屏显示拼接等。 | kernel-open/nvidia-modeset/+src/nvidia-modeset/编译出的核心.o |
nvidia-drm.ko | DRM/KMS 集成:现代 Linux 图形栈(如 Wayland)必需的直接渲染管理器适配。 | kernel-open/nvidia-drm/ |
nvidia-uvm.ko | 统一虚拟内存管理:实现 CPU/GPU 内存统一寻址。HPC 和 AI 计算的核心,体积巨大。 | kernel-open/nvidia-uvm/(约 15 万行独立实现) |
nvidia-peermem.ko | RDMA P2P 支持:允许第三方 PCIe 设备(如 Mellanox 网卡)通过 GPUDirect 直接读写显存。 | kernel-open/nvidia-peermem/ |
代码量分布
1 | src/nvidia 150 万行 ████████████████████ ← RM/GSP 核心,绝对主体 |
