Allwinner Boot / FEL / FES / NAND Dump

NES Classic Talk Notes

Notes on boot process, FEL/FES mode and how to dump the NAND storage and kernel. Part of the notes for Shall We Play A Game Talk

Boot Process

Most of these notes are taken almost directly from http://linux-sunxi.org/BROM with a few additional pieces of information from elsewhere on the internet or my own research

After power-up the SoC boots from an integrated 32kb ROM (aka Boot ROM or BROM).

The BROM is split into two parts: * FEL mode (at 0xffff0000) * eGON.BRM (at 0xffff4000)

eGON Boot

The eGON Boot ROM performs a few tasks:

  • does some co-processor setup (c15, (virtual) System Control Coprocessor).
  • disables the WatchDog Timer
  • setups CPU, AXI, AHB and APB0 clocks
  • enables AHB Gating
  • enables APB0 Gating
  • sets the Stack Pointer to 32K
  • then it jumps to ‘boot’ which immediately jumps to check_uboot
  • check_uboot setups up some registers, then checks the status pin (often called FEL pin, BSP pin or uboot)
    • if the pin is low (connected to GND) executes FEL mode at 0xffff0020.
    • If the pin is high it continues trying to boot from the following media and on failure continues to the next in order.
    • SD Card0 also known as MMC0
    • Internal NAND flash also known as NAND
    • SD Card2 also known as MMC2
    • SPI connected NOR flash also known as SPI
    • If all fails, FEL/USB Boot mode is executed from 0xffff0020

As you can see from the above there are multiple ways to get to FEL mode and perform a recovery which means its incredibly hard to brick the NES Classic console.

FEL Mode

FEL is a low-level USB programming and recovery mode built into the Boot ROM on Allwinner SoC’s.

With the device in FEL Mode and the sunxi-fel tool you can read & write to memory as well as execute code in memory.

Because the FEL Mode code is stored in the Boot ROM it makes it very hard to brick the NES Classic console, no matter how badly you mess up the firmware image you can always go back into FEL mode and re-upload a known working image.

U-Boot

U-Boot is a first and second stage boot loader. In the NES its launched by the Boot ROM and is responsible for finding and loading the Linux Kernel and initial root filesystem.

The NES Classic uses the standard opensource U-Boot with a few tweaks by Nintendo. The source is contained in the GPL code release from Nintendo. Additional patches have been made available by madmonkey in the hakchi software release that fix a few issues with the original Nintendo releasd version of the software.

Dump Kernel & NAND using FEL Mode

Power on the console while holding the reset button to boot the device into FEL mode.

NB Booting the device like this into FEL mode causes it to not initialise the RAM.

Step 1 - Initialise DRAM and switch to FES Mode

Upload fes1.bin ( https://github.com/ClusterM/hakchi2/blob/stable/data/fes1.bin) - Could be built using using the Nintendo uboot source.

Upload fes1.bin

sunxi-fel write 0x2000 fes1.bin

Execute code

sunxi-fel exec 0x2000

Step 2 - Upload uboot

Upload uboot.bin ( https://github.com/ClusterM/hakchi2/blob/stable/data/uboot.bin) - Could be built using using the Nintendo uboot source.

DRAM starts at 0x40000000
uboot starts at dram + 0x7000000 = 0x47000000

Upload uboot.bin

sunxi-fel write 0x47000000 uboot.bin

Step 3 - Patch uboot bootcmd

We need to write the following command to a specific portion of the uboot binary we loaded in memory so that it’ll run this command on boot and not attempt to boot the kernel sunxi_flash phy_read 47400000 30 20;efex_test (needs to be \0 terminated)

To be able to do this easily from the command line, we can write the above command to the kernel_dump_bootcmd file and then write the contents of the file (kernel_dump_bootcmd) to the offset where uboot’s bootcmd= is in memory.

sunxi-fel write 0x470604ff kernel_dump_bootcmd

Step 4 - Execute uboot

Execute uboot

sunxi-fel exec 0x47000000

Step 5 - Dump Kernel

You need to wait a few seconds here, unsure exactly why this is required. If you attempt to dump the kernel too soon you’ll get a usb_bulk_send() ERROR -7: Operation timed out error.

Finally dump Kernel to file

sunxi-fel read 0x47400030 0x600000 kernel.dump

See also