Can't get Jetson Nano to boot with custom pinmux configuration per Nvidia instructions


I’ve been unsuccessfully trying for a few days to flash my Jetson Nano with a new pinmux configuration per the instructions given at Whilst the flashing process itself is always successful, my Nano doesn’t complete boot up after being flashed but instead gets stuck showing the Nvidia splash screen - it doesn’t register the debug UART or other USB peripherals on my host PC or display any boot messages to the screen, so I am unable to diagnose what is preventing it performing its boot process.

I was originally trying to enable PWM on expansion pins 32 and/or 33 but gave up and went the route of sending serial instructions to an attached Arduio; but I’m interested in understanding why I’m unable to successfully flash my device using the supplied instructions since I’m obviously missing or misunderstanding something fundamental and want to learn.

I’ve tried:

  • doing the compilation and flashing from a clean Ubuntu 18.04 minimal installation on both a Virtualbox VM and a bare metal laptop
  • using both the i686 and x86_64 variants of the Linaro toolchain (Nvidia’s doc above recommends the i686 variant, but their L4T docs mention both i686 and x86_64 over at
  • flashing using the source files and default values that one gets from pulling down the Nvidia-provided source code in the first doc linked above; flashing using just the default values from the pinmux config template spreadsheet (ie: export without changing anything); as well as using a lightly modified config template with just cell AR32 changed to PWM, AS32 to Output, and AT32 to blank - all with the exact same results
  • different 32GB and 16GB SD cards as well as purchasing a brand new one just to be sure
  • with and without the root filesystem included in the build
  • many different combinations of the above

My Nano is powered via the DC barrel jack, and works perfectly with an SD card flashed using the normal NVidia image.

Looking at the boot flow at it seems I make it to Cboot (because the HDMI display initializes and I see the Nvidia boot logo) but then either Cboot don’t hand off to U-boot or I get stuck in Cboot because something is wrong with the device tree passed to Cboot from TegraBoot?

To reproduce what I’ve been attempting, I’ve created a Dockerfile for the build environment with Nvidia sources, and a script to automate the steps in Nvidia’s docs to compile in the new pinmux configurations. The Docker file and script along with simple instructions to build and launch the container, plus execute the script to build the pinmux configs are over at

In essence though, I:

  • take a minimal Ubuntu 18.04 installation
  • add basic packages for the build process (libc6-i386 and lib32z1 were from my own googling to satisfy failed link dependencies: aarch64-linux-gnu-gcc from the i686 linaro toolchain is 32bit ELF binary that wants to link against a missing /lib/ library which I believe libc6-i386 satisfies, but perhaps this is wrong?)
  • pull down and unpack the linaro 7.3.1 i686 toolchain
  • set environment variables for CROSS_COMPILE (there’s a typo in the Nvidia doc - I added a trailing hyphen) and PATH (for the correct dtc executable to be found)
  • pull down and unpack Nvidia Jetpack 32.2.1 sources
  • sync the Nvidia source tree
  • git clone the pinmux-scripts
  • pull down my own build script
  • follow the Nvidia doc to use the .csv and .dtsi files to recompile U-boot and CBoot using my Nano’s device tree version of b00
  • put my nano into Force Recovery mode and flash it with ‘sudo ./ jetson-nano-qspi-sd mmcblk0p1’. Interestingly the flash script says mmcblk0p1 is to boot off eMMC which my Nano doesn’t have, but I’ve tried mmcblk1p1 and that didn’t work either.

I’d appreciate some assistance figuring out where I’m going wrong!


I’ve found that the Excel spreadsheet produces dts/dtsi files that mess up the qspi and sdmmc entries so the sdcard never gets initialized properly. The spreadsheet does have a drop-down that let’s you select which device to boot from but it doesn’t seem to work correctly.

Here’s what I did initially to figure out what went wrong…

In Updating the U-Boot Pinmux section, paragraph 5.1. After you copy the new file but before you build, do a “git diff” to see what changed in the header file and make sure than only changes related to the pins you wanted to change are shown. If there are more than that, manually edit the file and change them back. Then build.

In Update the CBoot Pinmux section paragraph 2. After copying the files, do the same “git diff” and make sure only the changes you wanted are shown and fix if not. Then build.

If that still fails, let me know exactly what you changed in the spreadsheet and I can give you correct header and dts/dtsi files.


Thanks for having taken the time to reply.

Originally I did diff my .h and .dtsi files against the defaults and noticed quite a few differences - but the fact that I couldn’t get the board to boot when compiling just the default setup made me think the problem lay elsewhere.

I didn’t actually notice the dropdown to select the boot device (and I’m still somewhat confused as to whether to choose eMMC or QSPI give that the datasheet is for the production module and not the dev module with SD instead of eMMC and that the first parameter (target_board) to the flash command is ‘jetson-nano-qspi-sd’ and the second parameter (root_device) is ‘mmcblk0p1’ meaning eMMC where I would have expected ‘mmcblk1p1’ for SDCARD per the script documentation. It seems to me that all references to SD Card in the datasheet and other docs actually mean a separate SD-card reached via pins on the SO-DIMM connector vs the built-in SD Card of the development kit module?

So I spent a few hours this weekend flashing all the combinations of parameters and spreadsheet-generated boot options with the same results before sucking it up and diving into the source code.

It turns out that:
(a) I hadn’t realized one needs to run the script after completing the instructions in The adaptation guide (for whomever else might read this thread in future) over at was useful in highlighting that. So that explains one reason all my flash attempts were failing
(b) The Expansion Header guide states that you detect the device tree version of your board by executing ‘cat /proc/device-tree/nvidia,dtsfilename’ which in my case gives /dvs/git/dirty/git-master_linux/kernel/kernel-4.9/arch/arm64/boot/dts/…/…/…/…/…/…/hardware/nvidia/platform/t210/porg/kernel-dts/tegra210-p3448-0000-p3449-0000-b00.dts and therefore indicates b00 as the version name to use in all generated files. Turns out that the script pulls in code from p3448-0000.conf.common which based on my board version 200 pulled from EEPROM actually calculates the device tree version as a02 and not the b00 that the instructions give. This is probably not such a big deal in and of itself, but since I was following the instructions this means that none of the files I was generating with b00 in the filename was being used by the flash script in any flash attempts! The flash script would always pull in the a02 version no matter what I had done. So that’s 3 days of my life pointlessly flashing unused combinations that I’ll never get back!!

So I’ve started a clean build tree with device tree version a02 and have successfully flashed the board using the unmodified source. The flash fails when I apply my spreadsheet generated values, but now I can turn to those diffs as you suggested. I’ll let you know the outcome.

Thanks again


This is a known issue and we are working on the fix. Sorry for inconvenience.

I am also having difficulty getting it to boot after following these instructions. Any progress?


News about custom pinmux configuration?
I would need PWMs. I have had difficulties and I’m waiting for notifications.

Thank you


I managed to do rebuild Linux manually. The basic procedure for me was:

  1. On Linux host machine, run Jetpack SDK to download the latest copy of the Jetson Nano source files. These are stored on the host PC.
  2. Run ./ to update all source documents.
  3. Edit the following files:
    a. Pinmux_config_P3450_porg.h
    b. Tegra210_porg_P3448_common.dtsi
  4. Build the kernel as described in
  5. Put nano into force recovery mode
  6. Format the SD Card on PC using SD card formatter. Insert card into Jetson
  7. Flash the Jetson board from host over USB

Took a while for me to figure it all out, but it works now.

Jetson Nano Developer Kit Pinmux v1.01 is now published:


With new version of Jetson Nano Developer Kit Pinmux (v1.01) I tried again to set PWMs features for pins 33 (GPIO13) and 32(GPIO07) - GPIO_PE.06 to PM3_PWM2, and GPIO_PV.00 to PM3_PWM0, both set as output - of a Jetson Nano Developer Kit with L4T R32.2.3 (tag: tegra-l4t-r32.2.3-1 from (I successfully tried with SD card image and also with sdkmanager Jetpack 4.2.3).

I’m using dual boot Ubuntu 18.04 host computer and I have been following the guide into “customizing_the_jetson_nano_40-pin_expansion_header_v1.2.pdf”.
I have been able to complete the procedure and flash to Jetson Nano (in forced recovery mode), but with several warnings I’ll later speaking about.
After flashing and rebooting Jetson Nano, the board stays blocked on NVIDIA logo screen, it is not detected by my host linux pc (as L4T-README device) and I can do nothing.

So, I don’t understand what have been wrong and I report my warnings below.

  • when I run “./ p3450-porg” into “tegra-pinmux-script”:
    WARNING: uart2_rts: F3 mismatch CSV ‘rsvd2’ vs SOC ‘uart’
    WARNING: uart2_cts: F3 mismatch CSV ‘rsvd2’ vs SOC ‘uart’

  • when I run “./ p3450-porg > pinmux-config-p3450-porg.h” in the same folder:
    WARNING: Unconfigured pin batt_bcl

Due to these warnings, I think there is something wrong with created CSV (but what?)

  • when I try to build U-Boot by

set CROSS_COMPILE variable
make distclean make p3450-porg_defconfig
$ make

procedure successfully completes with a lot of warnings (not reportered here, If someone can help me I can share them).

Next steps work fine.

Could someone help me?
I’m using a Raspberry Pi for not wasting time, but I need to use the Jetson.

Thank you



Some things for you to try:

  • Can you attach a USB/serial adapter to Jetson and view the output; that might help show why the system isn't booting.
  • If you flash an unmodified version of L4T, does the system still boot?
  • If you build the DTB and U-Boot from source, without any modifications at all, does the system still boot?
  • The warnings from the pinmux script are likely not an issue; I believe they stem from the fact that the spreadsheet restricts the set of visible pinmux options to those validated on Jetson, whereas the pinmux scripts support a wider set of use-cases of the Tegra chip.

    What warnings do you get when compiling U-Boot? I see zero warnings when compiling an unmodified version of U-Boot (at least our latest internal version anyway).

    Thank you for reply @StephenWarren

    I have other jobs in my agenda right now, so I’m going to try next days.

    In the meanwhile here the output of U-Boot compiling (even if warnings are not an issue):



    Those warnings during the U-Boot compilation aren’t an issue; The U-Boot device trees don’t completely conform to the Linux kernel’s schema and so new versions of the device tree compiler will warn about this. However, the device tree content isn’t affected by the warning, and the files have worked correctly for U-Boot for years, so this isn’t a practical problem.

    Hi Jacopo,

    I have tested the latest pinmux spreadsheet for Jetson Nano v1.01 and I am unable to reproduce the problem you are seeing.

    In addition to Stephen’s comments can you confirm when you sync’ed the source you used the tag ‘tegra-l4t-r32.2.3-1’? Admittedly it may not have been 100% clear what tag you needed to use for r32.2.3.

    Also I wanted to let you know that we have just released L4T 32.3.1 and we now have a tool for re-configuring the 40-pin header that does not require re-building or re-flashing. For more details please see …


    Thank you @StephenWarren and @jonathanh both

    I’m directly trying new L4T 32.3.1 release with new tool for pin header configuration.
    I appreciate this released tool.

    So, I’m following, but after creating as suggested (sudo find /opt/nvidia/jetson-io/ -mindepth 1 -maxdepth 1 -type d -exec touch {}/ ;) and successfully running, I can see the interface for a moment before it disappeares without errors.

    Waiting for reply (in the meanwhile I’m trying to fix it)

    Thank you so much


    Hi Jacopo,

    We have identified another issue with the tool when using the SD card image for upgrading to r32.3.1. Can you try the following …


    You might also need to run

    eval `resize`

    before running Jetson-IO. That would require the xterm package to be installed, since it provides the resize binary.

    Thank you @StephenWarren and @jonathanh both again

    Finally I was able to set PWM functionalities with L4T 32.3.1 release and following (to fix new tool issue)

    Thank you so much!

    Best Regards


    I’m again in trouble with Jetson Nano and hope you can help me.

    My board successfully generates PWM signal to dedicated pins, but I have some problems:
    I have to send command to a camera (FLIR duo pro R) through 3.3-5V pwm signals, I tested it with a Raspberry and nice worked. Before directly attach this camera, I tested jetson pwm with generic arduino servomotor and It can reach the signal, but with camera doesn’t work and I don’t know why.

    In this situation I power the board via USB, could it work with 5V 4A power supply? (I mean could this be voltage/current issue?)

    Thank you


    Since you’ve verified that the PWM signal is generated as requested, I can’t really guess what the problem is. It’s quite unlikely that the power source is related to the problem, since a PWM signal is a low current signal.

    All I can suggest is to make sure you have the correct PWM frequency and duty cycle selected, and confirm that using a logic analyzer of oscilloscope.

    (BTW, it’s best to start a new thread for new issues; then you can give the new thread a meaningful title related to the new issue, and more people might look at a new thread than a long-running old thread.)