Custom Kernel Build for a Jetson AGX Xavier

Dear Nvidia Community,

I am new to this forum. Therfore I would like to introduce me. I am a german developer working in the automobile industry at a known OEM.

Since we are using this technology for autonomous driving, we using the DrivePX2 and Jetson technology very frequently.

Recently, my job got to be making a new kernel with adjusted parameters.

After quite some time I managed to build the kernel sources in addition to its modules. I got the Image file plus vmzlinuz with the config file and put those into /boot/.

Unfortunately, this didn’t work. With uname -r I saw, that the old Image was still active.

After installing grub and updateing it with sudo update-grub, it found my freshly built Image and greated a config file.

Still, after a reboot, the old Image has been loaded.

Any suggestions how I can get the new kernel running?

Thanks in advance!

Best Regards,

Some time back various parts of boot became signed. That content, if not signed correctly, will cause boot failure. In addition to this, Xavier does not use U-Boot…it boots directly from CBoot (I don’t know if PX2 uses U-Boot or not). Thus much of the content which was in “/boot” now has to be in a partition (CBoot does not understand ext4).

Also note that embedded systems do not have a BIOS or UEFI. GRUB depends on that as a uniform interface to hardware. No GRUB is possible in any embedded system without the BIOS/UEFI. Everything done in a PC’s BIOS/UEFI is done in custom software for the Xavier (of which CBoot is part of that…in other Jetsons, so is U-Boot).

The official docs mention how to use (part of the driver package…which is in turn downloaded by JetPack or SDKM). This is the Xavier forum, and so if you have access to the PX2 forum it might be a better place to ask:

Thank you for your answer. We were using a DrivePX2 in the past. At the moment, ht eJetson AGX Xavier is the board of interest.

During the past time I am trying to flash the image onto the board. Unfortunately, with little success.

I Followed the instructions to put the board into recovery-mode, still with no success.

The flash script fails with the following error message:

./ Zeile 599: ./tegrarcm_v2: No Permission
Error: probing the target board failed.
Make sure the target board is connected through
USB port and is in recovery mode.

This is driving me crazy since yesterday.

Is it possible to use the GUI in order to flash a custom image onto the board?

The permission error could be a number of things, but basically, on the host, the driver package “” command must be run with sudo, as well as the step. Some other parts of flash must not be sudo. In the case of using JetPack or SDK Manager you would run this as non-root (non-sudo), and enter your password so that sudo can be accessed (JetPack or SDKM then takes care of which steps to do sudo or not). I’m guessing that somewhere in the steps sudo was or wasn’t used at the right time. Something became root-only which shouldn’t be, or else sudo is not working on something which mandates sudo.

You will want to start over by completely deleting the directory produced by JetPack or SDKM. Then run JetPack or SDKM without sudo, but make sure it has the correct password for sudo.

For custom images realize that the “Linux_for_Tegra/” subdirectory is actually the driver package, and this is where the flash work is done. During a regular flash (not a custom image) the “rootfs/” content has some boot content added, but is a nearly exact copy of what gets turned into an image. The raw image generated during a regular flash becomes “bootloader/system.img.raw”, and a smaller sparse image becomes “bootloader/system.img”. This command is basically what creates the images and also flashes:

sudo ./ jetson-xavier mmcblk0p1

If you want to avoid regenerating the image and use the image which already exists, then you would use the “-r” (reuse) option:

sudo ./ <b>-r</b> jetson-xavier mmcblk0p1

Any image which is placed at “bootloader/system.img” will get flashed. It doesn’t matter if this is a clone, a raw image, or a sparse image, it’ll do the job. If you have an image already generated, then put a copy at “bootloader/system.img”, and then flash with “-r”. Keep in mind that if your image is not the same size as the default, then you might need to specify size.

Look at your image’s exact byte size. Determine its size in terms of MiB or GiB. If you can evenly divide by “10241024", then that is the size in MiB. If you can divide that exact byte size evenly by "10241024*1024”, then that is the size in GiB. “” can take the “-S #MiB” or “-S #GiB” argument as well. As an example I have an image which is “30064771072” bytes. Dividing twice by 1024 implies I can use “-S 28672MiB”. I can divide one more time by 1024, and this too is an even number, so this is also the same as “-S 28GiB”. If this were a custom image and I wanted to make sure the size is set correctly, then this would be my flash command:

sudo ./ <b>-r -S 28GiB</b> jetson-xavier mmcblk0p1

Note that you can tell SDKM to download, but not flash. This should produce the driver package “Linux_for_Tegra/” subdirectory at “~/nvidia/nvidia_sdk/JetPack_4.2_Linux_P2888/Linux_for_Tegra/”. “” should be there, and the “bootloader/” subdirectory of that is where you place your custom image as “system.img”.

Other variations exist for flashing just a kernel or device tree. It depends on what you are doing.

Dear linuxdev,

thank you for your help. As I mentioned, I am kinda new to the nviida/linux developer community and I am overwhelmed how good the support is. I decided to give you guys something back.

So in the meanwhile I could fix my problem with flashing a custom kernel to the Jetson AGX Xavier.

Some how I managed to flash a kernel to the board, which made it unable to boot.

So, for those who are going to read this article and have somewhat the same problems, those are the steps I performed to get my custom kernel running.

  1. Re-install the Jetson with its JetPack 4.1.1 DP Toolchain.
    My board was delivered with the NVIDIA Kernel version R31.0.1. JetPack 4.1.1 DP is going to install R31.1. Since, those versions a kind of similar, I chose to use it.

  2. After I could verify, that my board was booting in the OS again, I started building the custom kernel again.

  3. BE AWARE: DO NOT USE A VIRTUAL MACHINE. I tried this several times, but the flash process abborted every time I tried to flash it. After some research I found out, that the USB drivers can’t handle the flashing, since the USB device will be ejected once to restart the process. SOLUTION: Install Ubuntu 16.04 LTS (Xenial) natively. This did the trick for me.

  4. What I did additionally, but I can not confirm if this was helpful was updating my freshly installed Ubuntu with apt-get update/upgrade.

  5. Here comes the trick: For sure, if you are very familiar with linux and embedded hardware, you can use the l4t toolchain from nvidia in order to flash it manually. See the post above. I used several shell scripts from a git repository, which guide you through the process of building/cross compiling the kernel and flashing it to the board.

  6. Just look up jetson-agx-build on gihub. Download the trunk version and you are good to go. I am at work and cannot look up the github link, since this portal is blocked by my proxy server.

  7. If you follow the steps in 5) (github page), the flashing is done very easily.

  8. After successfluyy flashing the kernel onto the board, you should login to your jetson and verify the new version. With

uname -r

you should be able to see your kernel version with build date.

I hope this helps someone else, who wants to do the same as I did.

Nice! Thanks for the feedback!