Updating the DTB while running on usb boot

Hi! I ran the USB SDD upgrade as per the Jetson Hacks instructions. All is well and good until I try to update the DTB via jetson-io to use hardware pwm and it doesn’t ever get updated. Prior to an SSD upgrade I’ve gotten this to work.

I read here that:

Creates a new DTB or Device Tree overlay (DTBO) for the list of functions provided. If the command creates a new DTB file, the Linux boot configuration file (/boot/extlinux/extlinux.conf) is updated with a new option to boot using this DTB.

These are the contents of my extlinux.conf (Scroll down in text):

TIMEOUT 30
DEFAULT JetsonIO

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} quiet

# When testing a custom kernel, it is recommended that you create a backup of
# the original kernel and add a new entry to this file so that the device can
# fallback to the original kernel. To do this:
#
# 1, Make a backup of the original kernel
#      sudo cp /boot/Image /boot/Image.backup
#
# 2, Copy your custom kernel into /boot/Image
#
# 3, Uncomment below menu setting lines for the original kernel
#

# 4, Reboot
# LABEL backup
#    MENU LABEL backup kernel
#    LINUX /boot/Image.backup
#    INITRD /boot/initrd
#    APPEND ${cbootargs}

LABEL JetsonIO
        MENU LABEL Custom 40-pin Header Config
        LINUX /boot/Image
        FDT /boot/tegra210-p3448-0000-p3449-0000-b00-user-custom.dtb
        INITRD /boot/initrd
        APPEND ${cbootargs}

hello lackdaz,

you may update device tree by flash DTB partition.
please refer to Flashing a Specific Partition by using -k options to update DTB parttion.
thanks

@JerryChang

Hmmm could I trouble you to provide specific instructions on how to assign both PWM pins (32, 33) and back? I’m not exactly certain of what I’m doing and I didn’t develop on the TX devices. I’ll definitely play around after I get a grip of what I’m doing.

I’m assuming I need to use the -d option to provide a path to the device tree file?

Just wonder why it doesn’t work. Your extlinux.conf has the LABEL JetsonIO and it is using tegra210-p3448-0000-p3449-0000-b00-user-custom.dtb.

DTB via jetson-io to use hardware pwm and it doesn’t ever get updated.

it could be the path to the file is wrong, the rootfs is actually on my usb HDD.

Hi,

Yes, it sounds reasonable. I guess we didn’t verify jetson-io with external storage.
Where is this extlinux.conf located? Is it on usb hdd or emmc?

I guess currently your kernel image is still loading from sdcard. But I am not sure about the dtb.

Your uboot log should tell us which path is in use.

Its on the USB HDD, I’m still using the devkit and I don’t believe there’s emmc (that’s the 16gb on the production module)

Does running running jetson-io override my modified extlinux.conf? It previously had a custom kernel to boot form USB.

Is there a good way to capture uboot logs? I can probably try to catch it with the serial terminal.

I ran findmnt

$ findmnt -T .
TARGET SOURCE    FSTYPE OPTIONS
/      /dev/sdb1 ext4   rw,relatime,stripe=8191,data=ordered

which corresponds to my external hdd:

$ lsblk
NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
loop0          7:0    0    16M  1 loop 
sda            8:0    1   120M  0 disk 
└─sda1         8:1    1 119.3M  0 part /media/A87B-A154
sdb            8:16   0 465.8G  0 disk 
└─sdb1         8:17   0 458.3G  0 part /media/737927df-a7f8-4498-9e23-ec1f362fd054
mtdblock0     31:0    0     4M  0 disk 
mmcblk0      179:0    0 119.1G  0 disk 
├─mmcblk0p1  179:1    0 119.1G  0 part /media/seth/cf9d96ca-f7c4-45f5-9064-652345026106
├─mmcblk0p2  179:2    0   128K  0 part 
├─mmcblk0p3  179:3    0   448K  0 part 
├─mmcblk0p4  179:4    0   576K  0 part 
├─mmcblk0p5  179:5    0    64K  0 part 
├─mmcblk0p6  179:6    0   192K  0 part 
├─mmcblk0p7  179:7    0   384K  0 part 
├─mmcblk0p8  179:8    0    64K  0 part 
├─mmcblk0p9  179:9    0   448K  0 part 
├─mmcblk0p10 179:10   0   448K  0 part 
├─mmcblk0p11 179:11   0   768K  0 part 
├─mmcblk0p12 179:12   0    64K  0 part 
├─mmcblk0p13 179:13   0    80K  0 part 
└─mmcblk0p14 179:14   0   128K  0 part 
zram0        252:0    0   3.9G  0 disk [SWAP]
zram1        252:1    0   3.9G  0 disk [SWAP]
zram2        252:2    0   3.9G  0 disk [SWAP]
zram3        252:3    0   3.9G  0 disk [SWAP]

Hi,

Sorry, I modified my comment to sdcard. The uboot log could be captured by serial console.
I guess it is using kernel on sdcard because IIRC uboot does not support usb at all.

yeah I’m using an initrd-xusb.img on my sd /boot but it isn’t reflected in my extlinux.conf. I’m guessing that jetson-io overwrites the extlinux.conf file.

I’ll poke my ftdi serial programmer and post the uboot logs

Ok back to the original question, how can I flash the pins via -k. Most of my root files are located on an external HDD.

You may notice the original extlinux.conf does not have DTB field because the dtb could be read from either partition or rootfs.

Below command could flash the dtb to DTB partition.

sudo ./flash.sh -r -k DTB board_name mmcblk0p1 (or sdx1 if you are using usb hdd)

Got it. Let me test those out on a mint OS and I’ll post the changes.

Left some comment on your jetson-io post. You could check that part too.

Hi I just want to update that I managed to update the DTB using the bootloader instead.

I tried the flash.h methods from an ubuntu host machine but was unable to get the DTB flashed. Upon trying jetson-nano-qspi-sd instead of just the qspi the flash failed and I had to restart from scratch.

Here is my extlinux.conf for future reference:

TIMEOUT 30
DEFAULT primary

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd-xusb.img
      FDT /boot/tegra210-p3448-0000-p3449-0000-b00-user-custom.dtb
      APPEND ${cbootargs} root=UUID=<your-ssd-uuid> rootwait rootfstype=ext4

LABEL sdcard
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} quiet

# When testing a custom kernel, it is recommended that you create a backup of
# the original kernel and add a new entry to this file so that the device can
# fallback to the original kernel. To do this:
#
# 1, Make a backup of the original kernel
#      sudo cp /boot/Image /boot/Image.backup
#
# 2, Copy your custom kernel into /boot/Image
#
# 3, Uncomment below menu setting lines for the original kernel
#
# 4, Reboot

# LABEL backup
#    MENU LABEL backup kernel
#    LINUX /boot/Image.backup
#    INITRD /boot/initrd
#    APPEND ${cbootargs}

where you replace with your own hardware uuid. The trick is to add the FDT entry with your custom dtb file located on your sdmmc instead of the external rootfs.

1 Like

So to revive this thread I started messing about with the arducam and that requires its own custom image/kernel.

@WayneWWW
I’ve tried declaring multiple device trees on the uboot but that didn’t work. Is there some way I can still use my custom dtb with arducam’s?. To be clear, I’m just modifying the DTB to use pins 32, 33 as PWM.

Here is my extlinux.conf

TIMEOUT 30
DEFAULT primary

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/arducam/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} quiet

FDT /boot/arducam/tegra210-p3448-0000-p3449-0000-b00.dtb

# When testing a custom kernel, it is recommended that you create a backup of
# the original kernel and add a new entry to this file so that the device can
# fallback to the original kernel. To do this:
#
# 1, Make a backup of the original kernel
#      sudo cp /boot/Image /boot/Image.backup
#
# 2, Copy your custom kernel into /boot/Image
#
# 3, Uncomment below menu setting lines for the original kernel
#
# 4, Reboot

# LABEL backup
#    MENU LABEL backup kernel
#    LINUX /boot/Image.backup
#    INITRD /boot/initrd
#    APPEND ${cbootargs}

if I understand correctly, you would like to modify pins 32, 33 as PWM.
you could disassembler the original dtb file into text file for customization,
$ dtc -I dtb -O dts -o results.dts tegra210.dtb
then, convert the DTS into another new DTB file.
$ dtc -I dts -O dtb -o output.dtb results.dts

after that, update the new device tree to verify the results,
thanks

You could just use jetson-io once and use it as an example to do your next FDT case in extlinux.conf.

I’ve tried that but arducam’s dts/boot/arducam/tegra210-p3448-0000-p3449-0000-b00.dtb has some special sauce that causes the camera to not be detected when I use the custom dtb generated. I’m looking through @JerryChang’s solution now but gosh the DTS is long and I can’t tell for sure what to change.

@WayneWWW if you mean use it as an example to check for differences with the original b00 dtb, I’m probably going to do that now

Hi,

I meant jetson-io will show you how to add FDT field in extlinux.conf.
Not related to the content of your dts.

Yeah I know how to add FDT lines to extlinux.conf but I run both the arducam dtb and the custom dtb which includes the hardware pwm mapping (which I know jetson-io does well, and I’ve studied it to make it work for my usb boot).

is there some resource I can use/read to see how to change the pwm pins manually in the .dtsi?

I did a diff between a jetson-io saved custom dtb file converted to dts and the original dtb converted to dts. I can’t really tell what to configure pins 32, 33 to pwm

seth@tegra:/boot$ diff custom.dts original.dts 
1452,1453c1452,1453
<               pinctrl-names = "default";
<               pinctrl-0 = <0x12c>;
---
>               pinctrl-names = "default", "drive", "unused";
>               pinctrl-0 = <0x38>;
1459,1531d1458
<               header-40pin-pinmux {
<                       phandle = <0x12c>;
<                       linux,phandle = <0x12c>;
< 
<                       pin33 {
<                               nvidia,enable-input = <0x0>;
<                               nvidia,tristate = <0x0>;
<                               nvidia,pull = <0x0>;
<                               nvidia,pins = "pe6";
<                               nvidia,function = "pwm2";
<                       };
< 
<                       pin32 {
<                               nvidia,enable-input = <0x0>;
<                               nvidia,tristate = <0x0>;
<                               nvidia,pull = <0x0>;
<                               nvidia,pins = "lcd_bl_pwm_pv0";
<                               nvidia,function = "pwm0";
<                       };
< 
<                       pin28 {
<                               nvidia,io-high-voltage = <0x1>;
<                               nvidia,enable-input = <0x1>;
<                               nvidia,tristate = <0x0>;
<                               nvidia,pull = <0x0>;
<                               nvidia,pins = "gen1_i2c_scl_pj1";
<                               nvidia,function = "i2c1";
<                       };
< 
<                       pin27 {
<                               nvidia,io-high-voltage = <0x1>;
<                               nvidia,enable-input = <0x1>;
<                               nvidia,tristate = <0x0>;
<                               nvidia,pull = <0x0>;
<                               nvidia,pins = "gen1_i2c_sda_pj0";
<                               nvidia,function = "i2c1";
<                       };
< 
<                       pin10 {
<                               nvidia,enable-input = <0x1>;
<                               nvidia,tristate = <0x1>;
<                               nvidia,pull = <0x2>;
<                               nvidia,pins = "uart2_rx_pg1";
<                               nvidia,function = "uartb";
<                       };
< 
<                       pin8 {
<                               nvidia,enable-input = <0x0>;
<                               nvidia,tristate = <0x0>;
<                               nvidia,pull = <0x0>;
<                               nvidia,pins = "uart2_tx_pg0";
<                               nvidia,function = "uartb";
<                       };
< 
<                       pin5 {
<                               nvidia,io-high-voltage = <0x1>;
<                               nvidia,enable-input = <0x1>;
<                               nvidia,tristate = <0x0>;
<                               nvidia,pull = <0x0>;
<                               nvidia,pins = "gen2_i2c_scl_pj2";
<                               nvidia,function = "i2c2";
<                       };
< 
<                       pin3 {
<                               nvidia,io-high-voltage = <0x1>;
<                               nvidia,enable-input = <0x1>;
<                               nvidia,tristate = <0x0>;
<                               nvidia,pull = <0x0>;
<                               nvidia,pins = "gen2_i2c_sda_pj3";
<                               nvidia,function = "i2c2";
<                       };
<               };
< 
9024d8950
<               bootargs = "root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0  ";
9028a8955
>               bootargs = "kmemleak=on earlycon=uart8250,mmio32,0x70006000";
9175d9101
<               hdr40_pinmux = "/pinmux@700008d4/header-40pin-pinmux", "";

So I used @JerryChang’s suggestion to decompile, edit after analysing the differences between the dts files of the jetson-io and compiling again after editing the changes in line by line.

And it worked! But this is extremely hacky… Are there any better methods?