Build#

Compiling the Kernel (Kernel 6.1)#

This topic contains instructions for compiling the Linux kernel source in your Linux SDK product.

  1. Set up the environment macros: The LOCAL_VERSION environment variable appends -rt-tegra to the kernel version and modules.

    export KERNEL_NAME="nvidia-6.1"
    export ARCH=arm64
    export CROSS_COMPILE="${PWD}/toolchains/aarch64--glibc--bleeding-edge-2024.02-1/bin/aarch64-buildroot-linux-gnu-"
    export LOCALVERSION="-rt-tegra"
    export n_threads=`nproc`
    export TEMP_DIR=/tmp/$KERNEL_NAME
    export NV_BUILD_SYSTEM_TYPE="embedded-linux"
    
  2. Prepare the output folders.

    cd ${NV_WORKSPACE}/drive-linux/
    rm -rf $TEMP_DIR/kernel
    mkdir -p $TEMP_DIR/kernel/$KERNEL_NAME $TEMP_DIR/kernel/conftest
    cp -rf kernel/nvidia-6.1/source/* $TEMP_DIR/kernel/$KERNEL_NAME
    cp -rf kernel/common/nvidia-oot $TEMP_DIR/kernel
    cp -rf kernel/common/nvgpu $TEMP_DIR/kernel
    cp -rf kernel/common/hwpm $TEMP_DIR/kernel
    cp -rf kernel/common/nvidia-oot/scripts/conftest $TEMP_DIR/kernel/conftest/nvidia
    
  3. Apply the rt-patches and SoC-specific patches.

    cd $TEMP_DIR/kernel/$KERNEL_NAME
    bash scripts/generic-rt-patch.sh apply-patches
    
  4. Install the packages to prepare the kernel building workspace.

    apt-get -f -y install imagemagick graphviz dvipng python3-venv fonts-noto-cjk latexmk librsvg2-bin texlive-xetex flex bison kmod
    
  5. Configure and build the kernel.

    For dev_nsr PCT:

    export NV_BUILD_KERNEL_CONFIG_NAME=defconfig
    

    For prod_nsr and test_nsr PCTs:

    export NV_BUILD_KERNEL_CONFIG_NAME=tegra_prod_defconfig
    

    Build the kernel.

    cd $TEMP_DIR/kernel/$KERNEL_NAME
    make ARCH=arm64 CROSS_COMPILE=${CROSS_COMPILE} O=$TEMP_DIR/kernel/out-linux $NV_BUILD_KERNEL_CONFIG_NAME
    make ARCH=arm64 CROSS_COMPILE=${CROSS_COMPILE} O=$TEMP_DIR/kernel/out-linux -j$n_threads
    
  6. Build OOT modules.

    cd $TEMP_DIR/kernel
    export IGNORE_MISSING_MODULE_SYMVERS=1
    export NV_BUILD_CONFIGURATION_EXPOSING_T26X=1
    
    make src=$TEMP_DIR/kernel/conftest/nvidia obj=$TEMP_DIR/kernel/conftest/nvidia CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld NV_KERNEL_SOURCES=$TEMP_DIR/kernel/$KERNEL_NAME NV_KERNEL_OUTPUT=$TEMP_DIR/kernel/out-linux -f $TEMP_DIR/kernel/conftest/nvidia/Makefile
    
    ARCH=arm64 CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld make -j$n_threads -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/hwpm/drivers/tegra/hwpm srctree.hwpm=$TEMP_DIR/kernel/hwpm kernel_name=oot system_type=$NV_BUILD_SYSTEM_TYPE V=1 modules CONFIG_TEGRA_OOT_MODULE=m CONFIG_TEGRA_VIRTUALIZATION=y srctree.nvconftest=$TEMP_DIR/kernel/conftest
    
    ARCH=arm64 CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld make -j$n_threads -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/nvidia-oot srctree.nvidia-oot=$TEMP_DIR/kernel/nvidia-oot srctree.nvidia=$TEMP_DIR/kernel/nvidia-oot srctree.hwpm=$TEMP_DIR/kernel/hwpm srctree.nvconftest=$TEMP_DIR/kernel/conftest kernel_name=oot system_type=$NV_BUILD_SYSTEM_TYPE KBUILD_EXTRA_SYMBOLS=$TEMP_DIR/kernel/hwpm/drivers/tegra/hwpm/Module.symvers V=1 modules CONFIG_TEGRA_OOT_MODULE=m CONFIG_TEGRA_VIRTUALIZATION=y
    
    ARCH=arm64 CC=${CROSS_COMPILE}gcc LD=${CROSS_COMPILE}ld make -j$n_threads -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/nvgpu/drivers/gpu/nvgpu srctree.nvidia-oot=$TEMP_DIR/kernel/nvidia-oot srctree.nvidia=$TEMP_DIR/kernel/nvidia-oot srctree.nvconftest=$TEMP_DIR/kernel/conftest kernel_name=oot system_type=$NV_BUILD_SYSTEM_TYPE KBUILD_EXTRA_SYMBOLS=$TEMP_DIR/kernel/nvidia-oot/Module.symvers V=1 modules CONFIG_TEGRA_OOT_MODULE=m CONFIG_TEGRA_VIRTUALIZATION=y
    
  7. Consolidate the built kernel modules.

    export INSTALL_MOD_PATH=$TEMP_DIR/kernel/out-linux
    make ARCH=arm64 -C $TEMP_DIR/kernel/out-linux O=$TEMP_DIR/kernel/out-linux INSTALL_MOD_STRIP=1 modules_install
    make ARCH=arm64 -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/nvidia-oot INSTALL_MOD_STRIP=1 modules_install
    make ARCH=arm64 -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/hwpm/drivers/tegra/hwpm INSTALL_MOD_STRIP=1 modules_install
    make ARCH=arm64 -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/nvgpu/drivers/gpu/nvgpu INSTALL_MOD_STRIP=1 modules_install
    
  8. Recompile the display kernel modules.

    Display provides two different variants of drivers in DriveOS.

    • prod_nsr and test_nsr use the tegradisp driver (tegradisp.ko).

    • dev_nsr uses OpenRM (nvidia.ko, nvidia_modeset.ko, nvidia_drm.ko).

    1. For tegradisp (prod_nsr/ test_nsr):

    cd $TEMP_DIR/kernel
    tar -xf $NV_WORKSPACE/drive-linux_src/tegradisp-sources.tar.gz
    cd tegradisp-opensrc
    
    ARCH=arm64 CC=${CROSS_COMPILE}gcc \
    LD=${CROSS_COMPILE}ld make -j$n_threads \
    -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/tegradisp-opensrc \
    srctree.nvidia=$TEMP_DIR/kernel/nvidia-oot kernel_name=oot \
    srctree.nvconftest=$TEMP_DIR/kernel/conftest \
    KBUILD_EXTRA_SYMBOLS=$TEMP_DIR/kernel/nvidia-oot/Module.symvers \
    V=1 modules CONFIG_TEGRA_OOT_MODULE=m CONFIG_TEGRA_VIRTUALIZATION=y
    
    # Install step
    make ARCH=arm64 -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/tegradisp-opensrc INSTALL_MOD_STRIP=1 modules_install
    
    1. For OpenRM (dev_nsr):

    # Unify headers and Module.symvers for display module compilation:
    cd $TEMP_DIR/kernel
    cat nvidia-oot/Module.symvers >> out-linux/Module.symvers
    rsync -avzpq nvidia-oot/include/ out-linux/include
    
    # Untar the display source code.
    # The NVIDIA-kernel-module-source-<Version>.tar.xz source code is supplied as a .xz file. Untar the file. Its location is ${NV_WORKSPACE}/drive-linux_src/.
    tar -xvf ${NV_WORKSPACE}/drive-linux_src/NVIDIA-kernel-module-source-TempVersion.tar.xz
    
    # Compile the display kernel module.
    export IGNORE_PREEMPT_RT_PRESENCE=1
    cd NVIDIA-kernel-module-source-TempVersion
    
    make modules \
       SYSSRC=$TEMP_DIR/kernel/$KERNEL_NAME \
       SYSOUT=$TEMP_DIR/kernel/out-linux \
       SYSSRCHOST1X=$TEMP_DIR/kernel/nvidia-oot/drivers/gpu/host1x/include \
       LD=${CROSS_COMPILE}ld.bfd \
       CC=${CROSS_COMPILE}gcc \
       AR=${CROSS_COMPILE}ar \
       CXX=${CROSS_COMPILE}g++ \
       OBJCOPY=${CROSS_COMPILE}objcopy \
       TARGET_ARCH=aarch64 \
       ARCH=arm64
    
    # Copy the display modules to the module_install path.
    make ARCH=arm64 -C $TEMP_DIR/kernel/out-linux M=$TEMP_DIR/kernel/NVIDIA-kernel-module-source-TempVersion/kernel-open INSTALL_MOD_STRIP=1 INSTALL_MOD_DIR=updates/opensrc-disp INSTALL_MOD_PATH=$TEMP_DIR/kernel/out-linux modules_install
    

Note

The steps (1–8) can also be run using:

NV_BUILD_KERNEL_CONFIG_NAME="defconfig" \
KERNEL_NAME=nvidia-6.1 \
$NV_WORKSPACE/drive-linux/kernel/compile_kernel.sh
  1. Copy built Images and kernel modules to SDK default paths.

    # Copy the uncompressed (Image) kernel images to SDK kernel directory paths with the following command:
    export PROD_SUFFIX=<str> # "" for standard, "_prod" for production kernel
    rm -fv ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/images/*
    mkdir -p ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/images/
    cp -v $TEMP_DIR/kernel/out-linux/arch/arm64/boot/Image $TEMP_DIR/kernel/out-linux/vmlinux $TEMP_DIR/kernel/out-linux/System.map ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/images/
    
    # CAUTION: Before copying the new kernel images, back up the default kernels provided.
    rm -rf ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/modules/*
    mkdir -p ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/modules/
    cp -a $TEMP_DIR/kernel/out-linux/lib/modules/* ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/modules/
    
  2. Copy built modules to root file system.

    Create a Build-FS JSON file named update_rfs.CONFIG.json at ${NV_WORKSPACE}/drive-linux/filesystem/.

    The FilesystemType parameter <fstype> should be set depending on the list of modules to be copied to the filesystem:

    • standard should be used for dev_nsr PCT.

    • production_debug should be used for test_nsr PCT.

    • production should be used for prod_nsr PCT.

    Example JSON:

    {
      "OS": "linux",
      "Output": "driveos-updated-rfs",
      "Base": "${NV_WORKSPACE}/drive-linux/filesystem/targetfs-images/${FILESYSTEM}_${DISTRO}_thor_rfs.img",
      "FilesystemType": "<fstype>",
      "CopyTargets": [
        "${COPYTARGETYAML_DIR}/copytarget-kernel-modules-6.1.thor.yaml"
      ],
      "PostInstalls": {
        "/etc/nvidia/run-once/nv-run-once-run-ldconfig": "target",
        "/etc/nvidia/run-once/nv-run-once-run-depmod": "target"
      }
    }
    
  3. Rebuild the filesystem.

    export FILESYSTEM=dev_nsr_desktop # Assuming PCT is dev_nsr here. If PCT is test_nsr or prod_nsr, please set FILESYSTEM to test_nsr or prod_nsr respectively
    export DISTRO=ubuntu-24.04
    export NVRTKERNELNAME=$(basename ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/modules/*rt*-tegra)
    export NV_SDK_NAME_LINUX=drive-linux
    
    /usr/bin/python3 -B ${NV_WORKSPACE}/drive-common/filesystems/build-fs/18/bin/build_fs.py -w ${NV_WORKSPACE}/ -i ${NV_WORKSPACE}/drive-linux/filesystem/update_rfs.CONFIG.json -o ${NV_WORKSPACE}/drive-linux/filesystem/targetfs-images/
    
  4. Update initramfs with built modules.

    # If Building a production kernel for prod_nsr/test_nsr PCTs, then please set:
    export INITRAMFS_IMAGE=${NV_WORKSPACE}/drive-linux/filesystem/initramfs/initramfs-nvidia-6.1.cpio
    
    # Else If building a standard kernel for dev_nsr PCT, please set:
    export INITRAMFS_IMAGE=${NV_WORKSPACE}/drive-linux/filesystem/initramfs/prod-initramfs-nvidia-6.1.cpio
    
    # Extract the initramfs.
    rm -rf ./initramfs; mkdir -p ./initramfs; cd ./initramfs
    cpio -imdu --quiet < ${INITRAMFS_IMAGE}
    
    # Run copytarget to copy kernel modules.
    export NVRTKERNELNAME=$(basename ${NV_WORKSPACE}/drive-linux/kernel/nvidia-6.1/preempt_rt${PROD_SUFFIX}/modules/*rt*-tegra)
    export NV_SDK_NAME_LINUX=drive-linux
    rm -rf lib/modules/*
    ${NV_WORKSPACE}/drive-common/filesystems/copytarget/1.4/copytarget.py $PWD ${NV_WORKSPACE}/ ${NV_WORKSPACE}/drive-linux/filesystem/copytarget/manifest/copytarget-initramfs.yaml --filesystem-type boot_initramfs
    
    # Create the depmod and alias
    for k in $(ls -d ./lib/modules/*); do
      echo "Running depmod for kernel modules at $k"
      depmod -b . -a $(basename $k)
    done
    
  5. Rebuild updated initramfs.

    find . | cpio --quiet -H newc -o > ${INITRAMFS_IMAGE}
    
  6. Pass the absolute path of the updated rootfs image using the bind_partitions command-line argument: LINUX_RFS_IMG_PATH=<absolute path of rootfs image> as seen in the example below.

    cd /drive/drive-foundation
    ./make/bind_partitions -b p3960-10-sw01 drive_av.linux -p dev_nsr LINUX_RFS_IMG_PATH=/drive/drive-linux/filesystem/targetfs-images/driveos-updated-rfs.img
    
  7. Flash the target to the board using the SDK bootburn tool.

  8. Boot the board. The built kernel modules will auto-load on boot.