☰
NVIDIA 开源 GPU 内核模块:四大 .ko 分工与完整编译指南一次讲清
2026/10/5 15:35:30 网站建设 项目流程

NVIDIA 开源 GPU 内核模块:四大 .ko 分工与完整编译指南一次讲清

【免费下载链接】open-gpu-kernel-modulesNVIDIA Linux open GPU kernel module source项目地址: https://gitcode.com/GitHub_Trending/op/open-gpu-kernel-modules

NVIDIA 开源 GPU 内核模块(open-gpu-kernel-modules)把过去藏在闭源驱动里的 GPU 与 Linux 内核接口完整放了出来,面向 Turing 及更新架构的显卡,在 Linux 内核 4.15 及以上环境提供一套可定制、可审计的内核态实现。当前公开版本为 580.95.05。这篇文章不照搬官方文档,而是回答几个更实际的问题:代码为什么被切成两层、四个内核模块各自管什么、性能优化具体落在哪些文件里,以及怎样从零把它编译、安装起来。

先看懂分层:操作系统无关层 vs 内核接口层

这套代码的拆法,本质上是在回答一个问题:哪些逻辑跟具体内核版本无关,哪些逻辑必须跟着内核走。

  • 操作系统无关层(src/):GPU 的核心控制逻辑都在这里,跟 Linux、Windows 无关,体积大、编译慢。所以 NVIDIA 官方的.run安装包通常把它做成预编译二进制,省掉这一步。
  • 内核接口层(kernel-open/):这一层贴着 Linux 内核 API 写,内核一升级就可能要重新适配,因此必须针对你手头那台机器的内核现场编译。

两个目录的对应关系很直白,kernel-open/下每个子目录都是某一个.ko模块的"内核适配壳",而它真正调用的核心逻辑在src/里同名或就近的目录中:

open-gpu-kernel-modules/ ├── kernel-open/ # 内核接口层:必须针对目标内核编译 │ ├── nvidia/ # nvidia.ko 的内核适配 │ ├── nvidia-drm/ # nvidia-drm.ko 的内核适配 │ ├── nvidia-modeset/ # nvidia-modeset.ko 的内核适配 │ ├── nvidia-uvm/ # nvidia-uvm.ko 的内核适配 │ ├── nvidia-peermem/ # nvidia-peermem.ko:与 RDMA/InfiniBand 共享显存 │ └── common/ # 各模块共享的内核态公共头文件 └── src/ # 操作系统无关层:核心 GPU 逻辑 ├── nvidia/ # nvidia.ko 核心实现(内含 hal 硬件抽象) ├── nvidia-modeset/ # nvidia-modeset.ko 核心实现 ├── common/ # 公共工具、NVLink、NvSwitch 等 └── uproc/ # 处理器固件相关

一句话记住:src/决定"做什么",kernel-open/决定"怎么在 Linux 上落地"。

四大 .ko 模块如何分工

模块名里的.ko是 Linux 内核对象(Kernel Object)的文件后缀,也就是一个能被内核加载的驱动模块。NVIDIA 这套驱动由四个模块协作完成,外加一个可选的内存共享模块,它们与 Linux DRM 子系统的关系如下图:

nvidia.ko:直接对话硬件的底座

这是整套驱动的入口和重心,负责 GPU 初始化、硬件资源管理、电源状态切换,以及与底层硬件直接打交道的一切。kernel-open/nvidia/ 里是它的内核适配层,真正的功能主体在 src/nvidia/,其中硬件抽象层(HAL)按 GPU 架构分层,让同一套上层代码能覆盖不同芯片。对初学者来说,可以把它理解成"其他三个模块都依赖它"的根。

nvidia-drm.ko:面向桌面与渲染的 DRM 接口

Direct Rendering Manager(DRM)是 Linux 内核里管理图形显示的标准子系统。这个模块把 NVIDIA 的显示能力接进 DRM,支持原子模式设置、PRIME 缓冲区共享这类现代桌面功能,让用户态应用能顺畅地走 GPU 渲染路径。

它的初始化逻辑在 nvidia-drm.c 的nv_drm_init里,核心动作是先校验与nvidia-modeset.ko的版本是否匹配,匹配通过后再去探测设备:

int nv_drm_init(void) { #if defined(NV_DRM_AVAILABLE) if (!nvKmsKapiGetFunctionsTable(&nvKmsFuncsTable)) { NV_DRM_LOG_ERR( "Version mismatch: nvidia-modeset.ko(%s) nvidia-drm.ko(%s)", nvKmsFuncsTable.versionString, NV_VERSION_STRING); return -EINVAL; } nvKms->setCallbacks(&nv_drm_kapi_callbacks); return nv_drm_probe_devices(); #else return 0; #endif }

它做的事很简单:拿到nvidia-modeset暴露的函数表、确认两边版本一致,注册回调后开始探测 GPU 设备——版本对不上就直接报错退出,避免两个模块"各说各话"。

nvidia-modeset.ko:内核态的显示模式设置

它负责显示输出的具体细节:分辨率、多屏配置、时序参数,实现了 NVIDIA 的 KMS(Kernel Mode Setting,内核模式设置),让"设定显示模式"这件事发生在内核空间而不是用户空间,换来更快的启动和更稳的显示。它和nvidia-drm.ko紧挨着工作,前者管底层模式,后者对上暴露 DRM 接口。

nvidia-uvm.ko:让 CPU 和 GPU 共享地址空间

UVM 是 Unified Virtual Memory(统一虚拟内存)的缩写。它让 CPU 与 GPU 能共用同一段虚拟地址,省去大量手动搬运数据的麻烦,对异构计算应用尤其友好。它的职责包括 GPU 内存的分配/释放、页面迁移,以及访问越界时的故障处理。模块入口文件 uvm.c 的uvm_open就体现了它的一个设计取舍——给每个进程独立的地址空间隔离:

mapping = uvm_kvmalloc(sizeof(*mapping)); if (!mapping) return -ENOMEM; address_space_init_once(mapping); mapping->host = inode; mapping->a_ops = inode->i_mapping->a_ops; filp->f_mapping = mapping;

这里为每个打开的文件单独分配并初始化mapping,把虚拟地址映射隔离到进程内部,避免不同进程的 UVM 映射互相干扰。

四个值得单独看的性能优化点

以下每一点都能独立阅读,对应的源码位置都标了出来,方便你顺着看。

细粒度内存管理

UVM 不是"整块分配、整块释放",而是用 uvm_va_range.h 和 uvm_va_block.h 这类结构,把虚拟地址空间切成可控的片段,按需扩张或回收,减少无效占用。

智能页面迁移

数据该放 CPU 内存还是 GPU 显存,UVM 会依据访问热度自动搬移,目标是少一次拷贝就少一次开销。实现主要在 uvm_migrate.c 与 uvm_migrate_pageable.c。

NVLink 多卡协同

多张 GPU 之间的高速互联由 src/common/nvlink/ 承担,提供卡间通信的底层通道,是多卡并行系统的基础设施。

动态电源管理

驱动会根据负载调整 GPU 的电源状态与时钟,避免"高负载拉不满、低负载还高功耗"。PCI 设备侧的状态切换在 nv-pci.c,平台级电源策略在 nv-platform-pm.c。

从零编译与安装开源 GPU 驱动

前置条件:Turing 及以上架构的 NVIDIA 显卡,Linux 内核 4.15 及以上。整体流程是四步,前两步在本仓库目录内完成,后两步涉及系统级操作:

  1. 获取源码并进入目录:

    git clone https://gitcode.com/GitHub_Trending/op/open-gpu-kernel-modules cd open-gpu-kernel-modules
  2. 针对当前内核编译模块(-j$(nproc)用满所有 CPU 核心加速):

    make modules -j$(nproc)

    需要时可以追加编译选项:NV_VERBOSE=1打开详细日志,DEBUG=1产出带调试信息的版本;交叉编译则设置TARGET_ARCH=aarch64、CC=aarch64-linux-gnu-gcc等变量。

  3. 以 root 身份安装模块(安装前建议先卸载已存在的 NVIDIA 内核模块):

    sudo make modules_install -j$(nproc)
  4. 补齐用户空间组件:开源内核模块必须与同版本的用户态驱动配套,用官方.run文件只装用户空间、跳过内核模块即可:

    sudo sh ./NVIDIA-Linux-x86_64-580.95.05.run --no-kernel-modules

完成后,编译出的内核模块位于/lib/modules/$(uname -r)/kernel/drivers/video/,与用户空间组件版本一致即可正常加载。

从哪里参与

代码读到这里,如果你想改点什么——修一个 bug、补一段适配、优化一处性能——可以先从 CONTRIBUTING.md 入手,那里写明了贡献的规范与流程。这个开源项目把过去不透明的驱动内核摊开在公众视野里,参与它的门槛,比很多人想象的要低。

【免费下载链接】open-gpu-kernel-modulesNVIDIA Linux open GPU kernel module source项目地址: https://gitcode.com/GitHub_Trending/op/open-gpu-kernel-modules

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询