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 seems to save 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 (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 # 
