Natalie's Nonsense Nook

U-boot Config Tool, and a Medium Dive on U-Boot Vars

Published on

While working on my OpenWRT for Cradlepoint adventures, I needed to modify some boot variables so that I could actually obtain a UART console for my router. Specifically, in my case, I needed to disable silent mode and increase the bootwait time. I had never worked with U-boot variables outside of simply setting them in a U-boot shell, so I spent a bit of time spinning my wheels trying to figure out how it all worked. This post is mostly meant as a small primer for how the bootvars are stored in flash and how to tweak them for fun and profit.

So, my end goal is to change the boot variables so that I can actually get into the U-boot shell of this thing. First, let’s look at the structure of the config partition. Let’s take an example dump of my modified IBR1700 config:

000E0000 D7 AD 37 F7 43 50 43 6F 6E 66 69 67 3D 79 65 73    ....CPConfig=yes
000E0010 00 49 6D 61 67 65 32 75 70 67 72 61 64 65 3D 6E    .Image2upgrade=n
000E0020 6F 00 62 61 75 64 72 61 74 65 3D 31 31 35 32 30    o.baudrate=11520
000E0030 30 00 62 6F 6F 74 63 6D 64 3D 62 6F 6F 74 69 70    0.bootcmd=bootip
000E0040 71 00 62 6F 6F 74 64 65 6C 61 79 3D 31 30 00 65    q.bootdelay=10.e
000E0050 74 68 61 63 74 3D 65 74 68 30 00 66 69 6C 65 61    thact=eth0.filea
000E0060 64 64 72 3D 38 35 32 30 62 66 63 34 00 66 69 6C    ddr=8520bfc4.fil
000E0070 65 73 69 7A 65 3D 30 30 30 30 34 32 30 30 00 66    esize=00004200.f
000E0080 6C 61 73 68 5F 74 79 70 65 3D 30 00 69 70 61 64    lash_type=0.ipad
000E0090 64 72 3D 31 39 32 2E 31 36 38 2E 31 2E 31 31 00    dr=192.168.1.11.
000E00A0 6D 61 63 68 69 64 3D 38 30 31 30 32 30 31 00 71    machid=8010201.q
000E00B0 63 6F 6D 75 73 62 6D 6F 64 65 3D 61 75 74 6F 33    comusbmode=auto3
000E00C0 30 00 73 69 6C 65 6E 74 3D 6E 6F 00 73 74 64 65    0.silent=no.stde
000E00D0 72 72 3D 73 65 72 69 61 6C 00 73 74 64 69 6E 3D    rr=serial.stdin=
000E00E0 73 65 72 69 61 6C 00 73 74 64 6F 75 74 3D 73 65    serial.stdout=se
000E00F0 72 69 61 6C 00 00 00 00 00 00 00 00 00 00 00 00    rial............
000E0100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

In my case the config “partition” was 0xFFFF bytes long. Already you can probably see a pattern here. It’s just a key-value store with pairs separated by a null terminator (0x00), then the rest of the “partition” is padded out with nulls. The first 4 bytes are a little-endian order CRC32/ISO-HDLC checksum of the whole partition minus the CRC (0xFFFF - 4 bytes). Knowing this I wrote a quick script to manage parsing and modifying the U-boot environment variables. It handles converting from a binary dump of a SPI flash ship containing U-boot variables and creates a JSON file of the variables. You can tweak those variables and splice a modified bootvar partition into the flash dump, to then be programmed back onto the flash chip.

You can find the script at https://gist.github.com/nyaaaaaaatalie/e8b55caeff6a67997ddd16955ca1d2b9. Comments and stars are always welcome!