In my last post I detailed the method I used to find the JTAG pinout.
This time, I’ll show how I configured openocd, loaded a custom u-boot via JTAG, and rooted the hub.
Step 1 – Setting Up OpenODC
The version of openocd in the Ubuntu Trusty repo is 0.7 and I wanted to use the latest (currently 0.10), so I compiled it from source. The process is fairly painless if you have all the prerequisites installed:
$ git clone git://git.code.sf.net/p/openocd/code openocd-code $ ./bootstrap $ ./configure --enable-buspirate --enable-ftdi $ make -j4 $ sudo make install
On my first attempt to connect to the hub I got an “memory write caused data abort”, but a quick search led me to a helpful post with a solution. Click here to download my config file for the Wink hub that incorporates the fixes to the startup script.
You can also download my config the Olimex ARM-USB-OCD.
once openocd is built and your config files are in place you can start it with:
openocd -f olimex-arm-usb-ocd.cfg -f imx28evk.cfg
Step 2 – Loading A Custom U-Boot
The goal here is to build a custom version of u-boot, load it to RAM and execute it in place of the factory bootloader. This makes it easy to root the hub without risking damage to the hardware or filesystem corruption like some folks over at the XDA Developers forum have reported.
If you connect a 3.3V serial adapter to the UART on the hub you will see :
U-Boot 2014.01-14400-gda781c6-dirty (Apr 30 2014 - 22:35:38)
And this gives you an idea of where to start. To build the custom u-boot:
$ git clone git://git.denx.de/u-boot.git $ cd u-boot $ git checkout v2014.01 -b tmp $ export ARCH=arm $ export CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- $ make mx28evk_nand_config $ wget http://jalderman.org/wink-files/wink-hub.patch $ patch -p1 < wink-hub.patch $ make -j4
My patch sets up the environment to (mostly) match the Wink u-boot, but sets init=/bin/sh and enables the “Hit any key to stop autoboot” function. As an aside, I searched for the Wink u-boot sources and wasn’t able to find them. This seems to be a GPL license violation.
Assuming u-boot compiles successfully, you need to know where to load it into memory using openocd:
$ grep __image_copy_start u-boot.map *(.__image_copy_start) .__image_copy_start 0x0000000040000100 __image_copy_start
Now start openocd in one terminal:
$ sudo openocd -f olimex-arm-usb-ocd.cfg -f imx28evk.cfg
And connect via telnet in another:
$ telnet localhost 4444 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Open On-Chip Debugger
Now reset and halt the CPU and load our custom bootloader into memory. NOTE: I’ve observed that the halt command doesn’t always work. Sometimes it’ll take multiple reset/halt commands to get the CPU actually halted and in a state where we can write to RAM. Watch the serial terminal output and it’ll be obvious when the CPU is properly halted.
> reset > halt > cd u-boot > load_image u-boot.bin 0x40000100 downloaded 455212 bytes in 12.666913s (35.095 KiB/s) > resume 0x40000100
If the above is successful, you’ll see a new u-boot prompt in your serial terminal window:
U-Boot 2014.01-dirty (Aug 24 2015 - 18:24:43) CPU: Freescale i.MX28 rev1.2 at 454 MHz BOOT: NAND, 3V3 DRAM: 64 MiB NAND: 128 MiB *** Warning - bad CRC, using default environment Video: MXSFB: 'videomode' variable not set! In: serial Out: serial Err: serial Net: FEC0 [PRIME], FEC1 Warning: FEC1 using MAC address from net device Hit any key to stop autoboot: 0
You can interrupt u-boot now, but if you simply let it run it’ll boot with init=/bin/sh which will allow you to remove the root password.
Step 4 – Getting Root
Delete the root password, add a getty to the serial port, and enable ssh. For detailed instructions, go here.
/ # passwd -d root / # echo 'ttyAM0::respawn:/sbin/getty -L ttyAM0 115200 vt100' >> /etc/inittab / # mount -a / # ubiattach -p /dev/mtd3 / # mount -t ubifs ubi1:database /database / # echo '1' > /database/ENABLE_SSH
You’ll also want to add your public key to /root/.ssh/authorized_keys so that you can log in via ssh.
Next up: dumping a NAND image via JTAG.