NVIDIA has multiple different open-source kernel drivers for their GPU and display hardware, used in different scenarios – and working on different sets of NVIDIA devices.
nvgpu driver
The nvgpu
driver is used mainly/almost exclusively on NVIDIA Tegra SoCs. It’s a GPU – as in accelerator block – only driver that doesn’t handle display management – as that’s handled by separate display hardware.
This driver is available at https://nv-tegra.nvidia.com/r/gitweb?p=linux-nvgpu.git;a=summary under MIT license, except the Linux-specific components, which are licensed as GPLv2.
For a Tegra integrated GPUs, nvgpu
isn’t a standalone driver: it relies on the nvmap
and host1x
drivers for memory mapping and communication respectively.
For dedicated GPUs, unified memory isn’t supported with this driver. NVIDIA also doesn’t redistribute a firmware set for this driver for dedicated GPUs.
nvgpu
supports multiple operating systems. It runs on Linux, QNX and Nintendo Horizon. This drivers supports Functional Safety (FUSA) requirements for automotive use.
This driver doesn’t require the usage of the GPU System Processor present on Turing and later, and supports earlier GPUs.
Supported iGPUs by this driver: GM20B, GP10B, GV11B, GA10B
Supported dGPUs by this driver: GP106, GV100, TU104, GA100
Firmware set for Xavier (nvgpu)
-rwxr-xr-x 1 root root 102K avril 6 21:08 NETA_img.bin
-rwxr-xr-x 1 root root 102K avril 6 21:08 NETB_img.bin
-rwxr-xr-x 1 root root 102K avril 6 21:08 NETC_img.bin
-rw-r--r-- 1 root root 97K avril 6 21:08 NETD_img.bin
-rw-r--r-- 1 root root 25K avril 6 21:08 acr_ucode_dbg.bin
-rw-r--r-- 1 root root 25K avril 6 21:08 acr_ucode_prod.bin
-rw-r--r-- 1 root root 528 avril 6 21:08 fecs.bin
-rw-r--r-- 1 root root 108 avril 6 21:08 fecs_sig.bin
-rw-r--r-- 1 root root 528 avril 6 21:08 gpccs.bin
-rw-r--r-- 1 root root 108 avril 6 21:08 gpccs_sig.bin
-rw-r--r-- 1 root root 95K avril 6 21:08 gpmu_ucode.bin
-rw-r--r-- 1 root root 656 avril 6 21:08 gpmu_ucode_desc.bin
-rw-r--r-- 1 root root 95K avril 6 21:08 gpmu_ucode_image.bin
-rw-r--r-- 1 root root 1,3K avril 6 21:08 pmu_bl.bin
-rw-r--r-- 1 root root 108 avril 6 21:08 pmu_sig.bin
Tegra DC driver
tegradc
is a driver for the display controller used on NVIDIA Tegra hardware prior to Orin (t234). It’s fully independent from accelerator hardware.
The mainline kernel uses a DRM tegra
driver for the same purpose – which also has support for 3D acceleration on hardware that pre-dates Tegra K1.
The K1 switched to regular NVIDIA GPU architectures instead of using GeForce ULP.
nvidia driver
Those drivers below are derived from the same root codebase and share the same module names. (nvidia
and nvidia-*
) As such, they cannot be loaded at the same time as one another. You’ll have to pick one of those on a given machine.
Proprietary
The NVIDIA proprietary driver has obfuscated symbols, to (try to) make reverse engineering harder than it could be. Non-GSP firmware is directly included in the binary instead of being separate, unlike nvgpu
which has it stored it in /lib/firmware
.
The proprietary component code sizes for this kernel driver:
1,5M nvidia-modeset/nv-modeset-kernel.o_binary
44M nvidia/nv-kernel.o_binary
The ones on the Open GPU Kernel Modules for comparison, when precompiled by NVIDIA for shorter installation times:
1,8M nvidia-modeset/nv-modeset-kernel.o_binary
6,3M nvidia/nv-kernel.o_binary
GPU System Processor
This driver does support using the GPU System Processor, which is available on Turing GPUs (GeForce GTX 16xx and RTX) onwards.
The GSP firmware is totally optional in this driver. It is not required to be used in any way.
When the GSP driver is used, a significant chunk of the driver is offloaded, which makes open-sourcing that code not necessary in order to not have proprietary code running in the host OS kernel.
An extensive RPC interface is used for communication across the two worlds, not very much unlike what Apple does for the display controller on the A14 onwards.
The GSP firmware weights 39MB on the latest 515.43.04
driver release.
It’s a RISC-V 64-bit ELF binary.
firmware/gsp.bin: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, stripped
Sections on the gsp.bin
firmware file:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .gnext_data PROGBITS 0000000004001000 001000 0021a8 00 WA 0 0 8
[ 2] .ga10x_data PROGBITS 0000000004004000 004000 001090 00 WA 0 0 8
[ 3] .ga100_data PROGBITS 0000000004006000 006000 0010f0 00 WA 0 0 8
[ 4] .tu10x_data PROGBITS 0000000004008000 008000 0010f0 00 WA 0 0 8
[ 5] .gnext_text PROGBITS 000000000400a000 00a000 001830 00 AX 0 0 4
[ 6] .ga10x_text PROGBITS 000000000400c000 00c000 00107c 00 AX 0 0 4
[ 7] .ga100_text PROGBITS 000000000400e000 00e000 001104 00 AX 0 0 4
[ 8] .tu10x_text PROGBITS 0000000004010000 010000 001104 00 AX 0 0 4
[ 9] .bootstrap PROGBITS 0000000004012000 012000 0000c4 00 AX 0 0 4
[10] .gnext_resident_text PROGBITS 0000000004013000 013000 002000 00 WAX 0 0 4
[11] .gnext_resident_data PROGBITS 0000000004015000 015000 001000 00 WA 0 0 32
[12] .ga10x_resident_text PROGBITS 0000000004016000 016000 002000 00 WAX 0 0 4
[13] .ga10x_resident_data PROGBITS 0000000004018000 018000 001000 00 WA 0 0 32
[14] .ga100_resident_text PROGBITS 0000000004019000 019000 002000 00 WAX 0 0 4
[15] .ga100_resident_data PROGBITS 000000000401b000 01b000 001000 00 WA 0 0 32
[16] .tu10x_resident_text PROGBITS 000000000401c000 01c000 002000 00 WAX 0 0 4
[17] .tu10x_resident_data PROGBITS 000000000401e000 01e000 001000 00 WA 0 0 32
[18] .acl PROGBITS 000000000401f000 01f000 000160 00 WA 0 0 1
[19] .manifest PROGBITS 000000000401f160 01f160 000ea0 00 WA 0 0 1
[20] .section_task_init_stack_instance PROGBITS 000000000662a000 021000 002000 00 WA 0 0 1
[21] .section_task_rm_stack_instance NOBITS 000000000662d000 967000 010000 00 WA 0 0 1
[22] .header PROGBITS 0000000004020000 020000 000010 00 WA 0 0 1
[23] .memory_region_init_arguments PROGBITS 0000000004020010 263c010 000060 00 WA 0 0 1
[24] .section_task_rm_elf_rodata_instance PROGBITS 0000000004021000 97e000 11d000 00 A 0 0 8
[25] .section_task_rm_elf_data_instance PROGBITS 000000000413e000 a9f000 1b9d000 00 WA 0 0 8
[26] .section_task_rm_elf_paged_data_instance PROGBITS 0000000005cdb000 263c070 000000 00 W 0 0 1
[27] .section_task_rm_elf_text_instance PROGBITS 0000000005cdb000 023000 944000 00 AX 0 0 4
[28] .section_task_rm_elf_paged_text_instance PROGBITS 000000000661f000 263c070 000000 00 W 0 0 1
[29] .section_task_init_elf_rodata_instance PROGBITS 000000000661f000 97d000 001000 00 A 0 0 8
[30] .section_task_init_elf_data_instance PROGBITS 0000000006620000 967000 001000 00 WA 0 0 8
[31] .fwsignature_ga100 PROGBITS 0000000006621000 968000 001000 00 WA 0 0 8
[32] .fwsignature_ga10x PROGBITS 0000000006622000 969000 001000 00 WA 0 0 8
[33] .fwsignature_tu10x PROGBITS 0000000006623000 96a000 001000 00 WA 0 0 8
[34] .fwsignature_tu11x PROGBITS 0000000006624000 96b000 001000 00 WA 0 0 8
[35] .section_task_init_elf_paged_data_instance PROGBITS 0000000006625000 a9b000 001000 00 WA 0 0 1
[36] .section_task_init_elf_text_instance PROGBITS 0000000006626000 a9c000 003000 00 AX 0 0 4
[37] .section_task_init_elf_paged_text_instance PROGBITS 0000000006629000 97c000 001000 00 WA 0 0 1
[38] .section_task_rm_memset_buffer_instance NOBITS 000000000662c000 023000 001000 00 WA 0 0 1
[39] .section_log_rm_buffer_instance NOBITS 000000000663d000 000000 040000 00 WA 0 0 1
[40] .section_task_rm_args_buffer_instance NOBITS 000000000667d000 000000 001000 00 WA 0 0 1
[41] .section_task_init_dmem_64kb_instance PROGBITS 000000000667e000 96c000 010000 00 WA 0 0 1
[42] .section_log_init_buffer_instance NOBITS 000000000668e000 000000 010000 00 WA 0 0 1
[43] .section_task_rm_message_timing_buffer_instance NOBITS 000000000669e000 97d000 001000 00 WA 0 0 1
[44] .section_task_rm_msgq_work_areas_instance NOBITS 000000000669f000 a9c000 021000 00 WA 0 0 1
[45] .section_task_rm_memcpy_buffer_instance NOBITS 00000000066c0000 a9c000 001000 00 WA 0 0 1
[46] .comment PROGBITS 0000000000000000 263c070 000011 01 MS 0 0 1
[47] .shstrtab STRTAB 0000000000000000 263c081 0004a6 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
R (retain), p (processor specific)
We can see that most executable code is shared between GPU generations in this scenario.
Open GPU Kernel Modules
This driver is the one above, but with only supporting the GPU System Processor offloaded code path and available under an open-source license (dual GPLv2 + MIT).
As it relies on the GSP, this driver only supports Turing and later.
opensrc-disp
opensrc-disp
is derived from the mainline NVIDIA closed-source driver, like the one above. It replaces tegradc
on Orin (t234) and later. It does not drive the GPU accelerator, which is still driven by the nvgpu
driver on Orin.
Currently, this driver only supports T234D and as such, when using a dedicated GPU on Orin, the onboard display controller is lost.
Userspace compatibility
No ABI compatibility is guaranteed between kernel and user land across nvidia
GPU driver versions. nvgpu
has a significantly higher ABI stability level.
nvgpu
and nvidia
do not share ABIs. As such, different sets of user-mode drivers are needed to interface with them.
In both the nvgpu
and nvidia
scenarios, the user-space GPU driver components provided by NVIDIA are proprietary.
edit (May 15): all of the nvgpu
Linux-specific components are licensed as GPLv2.