Experimenting with the U-Boot on the EasyBox 904 ================================================ Abstract: This text describes a way to load and start another U-Boot via a running U-Boot. Reasons ======= 1. The eb904 can easily be bricked when writing an experimental U-Boot into flash. Though, for the EasyBox 904 in the meantime I could successfully try out the debrick procedure as described here: https://wiki.openwrt.org/inbox/arcadyanastoria/arcadyan_astoria_easybox_904xdsl_r01#debricking For shortcutting the two pins on power-on, I needed a magnifying lense, a screwdriver with narrow blade, and tried not to quiver. 2. When writing U-Boot to NAND flash, you stress exactly the most important area of flash which is relevant for proper working. AFAIK, there is no bad erase block handling implemented when loading U-Boot. Neither in the ROM-builtin IPL (initial program loader) which loads a small first stage part of U-Boot into RAM. Nor in the first stage part of a NAND-capabale U-Boot which loads the main part into RAM. According to this Wiki section, NAND flash endurance should be at least 1000 rewrites: https://en.wikipedia.org/wiki/Flash_memory#Write_endurance This should be enough for most cases, shouldn't it? Well, anyway, if we can avoid flashing, let's avoid it. But is this at all possible and reasonable? =========================================== Well, according to this FAQ it is not :-) https://www.denx.de/wiki/DULG/CanUBootBeConfiguredSuchThatItCanBeStartedInRAM Anyway, I felt that you cannot lose anything trying it. And the result is: it _seems_ to work. But I always keep in mind that testing the U-Boot this way is not the real thing, i.e. it is not the real test. Added 20181120: Last time I tried, networking (tftp, ping) did not work when starting another U-Boot from the initial one. Don't know why; I think it worked before. How can it be done? =================== The way I do it: 1. Build the U-Boot for the EasyBox 904 and have a file "u-boot.asc" generated. 2a. Convert this file to a binary with the script listed below with argument "u-boot.asc". That is for example: ./convert-asc-to-bin.sh u-boot.asc It will create a file named u-boot.asc-0xA0400000.bin. 2b. Another method, found later: cd to the directory where u-boot files are generated and use the objcopy tool. There should be an "elf" binary named "u-boot". > cd build_dir/target-mips_24kc_musl/u-boot-2018.03/ > objcopy -O binary -I elf32-big u-boot u-boot-0xA0400000.bin 2c. Heck, did I overlook this before? There directly is a file u-boot.bin which can be loaded to 0xA0400000. 3. Provide this .bin file to an tftp server which responds to requests at adress 192.168.2.100. 4. On the U-Boot prompt of your eb904, enter: (note: no need to use a "0x" prefix for the address, i.e. to use "0xA0400000; it is interpreted as hex anyway) tftp a0400000 u-boot.asc-0xA0400000.bin (or use whatever filename is appropriate) go a0400000 (note: "go", not "bootm" command!) ----------------------------------------------------------------------- cat convert-asc-to-bin.sh << EOF #! /bin/sh # # Create a U-Boot binary from an .asc file # # This script needs 'grep' and 'xxd' installed. # INFILE="$1" OUTFILE=$(grep -I -m1 '^a' "$INFILE") if [ "$?" != "0" ] then echo $INFILE: Invalid file format exit 1 fi OUTFILE="${OUTFILE%${OUTFILE#????????}}" OUTFILE="$(echo $OUTFILE | tr '[:lower:]' '[:upper:]')" OUTFILE="${INFILE}-0x${OUTFILE}.bin" echo Creating $OUTFILE grep -i '^a' $INFILE | sed 's/^........//' | xxd -r -p > "$OUTFILE" EOF chmod a+x convert-asc-to-bin.sh ----------------------------------------------------------------------- Thinking again: why can this work? ================================== Questions asked to myself and answered to myself with some assumptions. Q: AFAIK the 128MB RAM of the Easybox 904 is mapped in the address range 0x80000000-0x87FFFFFF. So why can the U-Boot be loaded and started at 0xA0400000? A: According to https://randomprojects.org/wiki/Vodafone_EasyBox_904_xDSL#Hardware there also is: 2M x 4banks x 16bits SDRAM, 166MHz/CL3 : Winbond W9812G6JH-6, markings "Winbond W9812G6JH-6 1311W 624607500ZX" (datasheet)" So there might be an additional RAM of size 4MB mapped to 0xA0400000-A07FFFFF? kovz replies to that speculation (https://forum.openwrt.org/t/support-for-easybox-904-lte/14478/52?u=arnysch): IMHO this Winbond memory is used by Ralink rt3883 WiFi SoC. At least on PCB it placed close to WiFi SoC and traces are routed in direction to it. Could it be some mapping magic? Q: When the currently running U-Boot loads another U-Boot to 0xA0400000, doesn't it overwrite itself? A: Defining "DEBUG 1" in include/common.h produces interesting messages and reveals: U-Boot uncompresses itself to the upper part of the normal RAM, i.e. directly below 0x88000000. So the 4MB RAM at 0xA0400000 ist not used any longer. Q: Something else interesting? The size of the RAM at 0xA0400000 (4MB) is larger than the original U-Boot delivered by the vendor (about 200k). The uncompressed size of the stuff in u-boot.lq seems to be around 800kB. Compressed and uncompressed version easily fit together in the 4MB RAM, with still 3MB left. This means that there probably would be no problem if the U-Boot would be larger. The current limitting factor is the small U-Boot partition (size 0x40000 = 256kB = 2 erase blocks) in the eb904. But of course we could change the partition layout and enlarge the U-Boot partition. I tried out adding UBI features to U-Boot, and this extended U-Boot's size to a 3rd erase block. The U-Boot version from 2010 required a lot of extra stuff for UBI: mtd, gzip lib, lzo lib, ... Maybe not all is really needed for UBI, and a newer U-Boot version would result in a smaller binary? BTW, the UBI functions I tried when building U-Boot (version from 2010, used by Qauge repo) seem not to work correctly. On every "ubi part" command, it claimed that it initialized the UBI partition. This was even the case when specifying a "VID header" offset of 2048 ("ubi part ubi 2048"). Maybe a later U-Boot version solves this? DDR tuning ---------- (Addendum 20181105 and later) Arcadian's U-Boot saves DDR tuning parameters in 24 bytes at offsets 0x3FE8..0x3FFF in its own 1st erase block. It overwrites itself! The starting bytes of this area are marked by hex value 88888888. If this part is incorrect (no 88888888 or checksum error), then U-Boot starts an autotune function which runs some RAM tests to determine reasonable/best/whatever DDR parameters. AFAIK if these bytes seem to be flashable (eg. contain 0xFF only), then U-Boot ovewrites (i.e. flashes) this part with the retrieved parameters. For my eb904, this was: 1. 00003fe8: 88888888 Magic 2. 00142104 -> DDR_CCR39 3. 00003ff0: 00142104 -> DDR_CCR40 4. 00566504 -> DDR_CCR43 5. 00566504 -> DDR_CCR44 6. 00000000 Checksum exclusive-or of 2., 3., 4., and 5. After an U-Boot reflash there was as slight difference: 1. 00003fe8: 88888888 2. 00142104 3. 00003fe8: 00142204 4. 00566504 5. 00566404 6. 00000200 To show that from a running U-Boot, you can use: (note that all values ar hex based) VR9 # nand read 80000000 3fe8 18 NAND read: device 0 offset 0x0000000000003fe8, size 0x0000000000000018 0x18 bytes read: OK VR9 # md.l 80000000 6 80000000: 88888888 00142104 00142204 00566504 ......!..."..Ve. 80000010: 00566404 00000200 .Vd..... VR9 # U-Boot log when DEBUG 1 is defined ---------------------------------- U-Boot 2010.06-Lv2.0.40-A0.5 (Nov 01 2018 - 21:47:31) CLOCK CPU 500M RAM 250M DRAM: 128 MiB Top of RAM usable for U-Boot at: 88000000 Reserving 512k for U-Boot at: 87f80000 Reserving 4352k for malloc() at: 87b40000 Reserving 36 Bytes for Board Info at: 87b3ffdc Reserving 36 Bytes for Global Data at: 87b3ffb8 Reserving 256k for boot params() at: 87afffb8 Stack Pointer at: 87afff98 Now running in RAM - U-Boot at: 87f80000 NAND: NAND device: Manufacturer ID: 0xec, Chip ID: 0xdc (Samsung NAND 512MiB 3,3V 8-bit) 512 MiB Bad block table found at page 262080, version 0x01 Bad block table found at page 262016, version 0x01 nand_read_bbt: Bad block at 0x000004200000 nand_read_bbt: Bad block at 0x0000142c0000 In: serial Out: serial Err: serial Net: LZMA: Image address............... 0xa0120048 LZMA: Properties address.......... 0xa0120048 LZMA: Uncompressed size address... 0xa012004d LZMA: Compressed data address..... 0xa0120055 LZMA: Destination address......... 0xa0140000 LZMA: Uncompresed size............ 0x40100 LZMA: Compresed size.............. 0xf1f0 Internal phy(GE) firmware version: 0x040b vr9 Switch Type "run flash_nfs" to mount root filesystem over NFS ### main_loop entered: bootdelay=4 ### main_loop: bootcmd="run flash_flash$(bootid)" Hit any key to stop autoboot: 0 rtl8367rb init done .... VR9 #