Skip to content

NVIDIA’s open-source drivers

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.

Leave a Reply

Your email address will not be published. Required fields are marked *