Allwinner H700 Firmware extraction¶
The following page describes how to extract the bootloader, u-boot, and kernel from an Allwinner H700 based device. The following devices are based on this processor and these instructions are valid for all of them:
- RG35xx Plus
- RG35xx H
- RG35xx 2024
Tools and repositories required¶
- android unpackbootimg to unpack/pack and create boot.img
- OrangePi Build includes all the necessary tools for repackaging the boot-package (u-boot)
- OpenixCard to extract the stock firmware image (in AWIMAGE format)
Firmware building blocks¶
There are four different blocks that are required for the Allwinner H700 BSP to work.
Boot0¶
The Boot0 is the secondary program-loader, and it's loaded by the BROM during the boot-process. You can read more about this in the linux sunxi boot0 page
The typical location of this boot0 is either on position 8KB or 256KB. Stock uses 8KB position
The boot0 has the following signature:
Boot package¶
Boot package contains the u-boot and the device tree (DT) of the device. The boot package is located at an offset of 16,400 KB.
The boot package has the following signature:
The u-boot is included in the boot-package.fex image
Boot Image¶
Contains the kernel, ramdisk, and bootargs.
The boot.img goes into the first partition of the sdcard with an offset 36,864 KB.
Boot.img follows an android boot image and can be unpacked (and packed again) with the android unpackbootimg
To extract the boot.img to the folder boot_image
:
$ unpackbootimg -i boot.img -o boot_image/
BOARD_KERNEL_CMDLINE .BT0
BOARD_KERNEL_BASE 645ee563
BOARD_NAME for boot0
BOARD_PAGE_SIZE 1948279909
BOARD_HASH_TYPE sha256
BOARD_KERNEL_OFFSET 00008000
BOARD_RAMDISK_OFFSET fd058b12
BOARD_SECOND_OFFSET 9c087c09
BOARD_TAGS_OFFSET 080a7c03
BOARD_OS_VERSION 49.91.109
BOARD_OS_PATCH_LEVEL 2070-12
BOARD_DT_SIZE 1634541679
The following files will be extracted into the boot_image
folder:
boot.img-base boot.img-cmdline boot.img-hash boot.img-oslevel
boot.img-pagesize boot.img-ramdiskoff boot.img-secondoff boot.img-zImage
boot.img-board boot.img-dtb boot.img-kerneloff boot.img-osversion
boot.img-ramdisk.gz boot.img-second boot.img-tagsoff
To repack the boot.img after doing any changes:
mkbootimg --kernel boot.img-zImage --ramdisk boot.img-ramdisk.gz --dt boot.img-dtb \
--board sun50i_arm64 --base 40078000 --kernel_offset 00008000 --ramdisk_offset 01f88000 \
--second_offset 00e88000 --tags_offset fff88100 --cmdline "earlyprintk=ttyS0,115200
loglevel=8 initcall_debug=0 console=tty0 console=ttyS0,115200 rootwait root=/dev/mmcblk0p3
init=/sbin/init" -o updated_boot.img
Env Image¶
Env image contains the environment variables used by u-boot.
The image can be extracted just with strings env.img > env.txt
.
The environment variables follow this format:
earlyprintk=sunxi-uart,0x05000000
initcall_debug=0
console=ttyS0,115200
nand_root=/dev/nand0p4
mmc_root=/dev/mmcblk0p5
init=/init
loglevel=4
selinux=0
cma=64M
mac=
wifi_mac=
bt_mac=
specialstr=
keybox_list=hdcpkey,widevine
setargs_nand=setenv bootargs earlyprintk=${earlyprintk} initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} gpt=1
setargs_mmc=setenv bootargs earlyprintk=${earlyprintk} initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${mmc_root} rootwait init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} selinux=${selinux} specialstr=${specialstr} gpt=1
boot_normal=sunxi_flash read 45000000 boot;bootm 45000000
boot_recovery=sunxi_flash read 45000000 recovery;bootm 45000000
boot_fastboot=fastboot
recovery_key_value_max=0x13
recovery_key_value_min=0x10
fastboot_key_value_max=0x8
fastboot_key_value_min=0x2
bootdelay=0
bootcmd=run setargs_nand boot_normal
To convert a valid environment file (e.g. env.cmd
) into an environment image you have to use the mkenvimage
command:
Obtaining the stock firmware¶
There are three ways to obtain the stock firmware:
- Obtain the original recovery PhoenixCard image from Garlic 2.0 bootloader repo
- Use the SDCARD included with your device
- Download the firmware from Anbernic's website (working link as of 2024/04/16):
- Note: download the 16GB firmware (e.g.
cxm_35xxh-en16gb-240330_2024-04-01_0402.zip
)
- Note: download the 16GB firmware (e.g.
Firmware extraction¶
This section describes the different methods to extract the firmware
Using the original PhoenixCard firmware¶
The original recovery firmware image (h700_linux_tv_uart0_20231108.zip
) was posted as part of the Garlic 2.0 development. That included the bootloader for the original RG35XX as well as the one for the RG53XX Plus. You can download it from here (original link from the GarlicOS bootloader GitHub repository)
This firmware image can be extracted with several tools, but OpenixCard works well for these types of Allwinner firmware images. With the image downloaded and OpenixCard tools installed, first extract the image from the archive:
$ unzip h700_linux_tv_uart0_20231108.zip
Archive: h700_linux_tv_uart0_20231108.zip
inflating: h700_linux_tv_uart0_20231108.img
Then run OpenixCard to extract the actual image:
$ OpenixCard -u h700_linux_tv_uart0_20231108.img
_____ _ _____ _
| |___ ___ ___|_|_ _| |___ ___ _| |
| | | . | -_| | |_'_| --| .'| _| . |
|_____| _|___|_|_|_|_,_|_____|__,|_| |___|
|_| Version: 9ffafbb Commit: 1
Copyright (c) 2022, YuzukiTsuru <GloomyGhost@GloomyGhost.com>
[OpenixCard INFO] Converting input file: h700_linux_tv_uart0_20231108.img
[OpenixIMG INFO] Decrypting IMG header...
[OpenixIMG INFO] IMG version is: 0x300
[OpenixIMG INFO] Decrypting IMG file contents...
[OpenixIMG INFO] Writing the IMG config data...
[OpenixCard INFO] Unpack Done! Your image file is at h700_linux_tv_uart0_20231108.img.dump
The image will be extracted to the h700_linux_tv_uart0_20231108.img.dump
folder, and it should contain the following files:
arisc.fex boot0_nand.fex boot-resource.fex dlinfo.fex rootfs.fex sunxi_mbr.fex toc1.fex usbtool.fex vmlinux.fex
aultls32.fex boot0_sdcard.fex cardscript.fex env.fex split_xxxx.fex sys_config.fex u-boot-crash.fex Vboot.fex Vrootfs.fex
aultools.fex boot.fex cardtool.fex fes1.fex sunxi.fex sys_partition.fex u-boot.fex Vboot-resource.fex
board.fex boot_package.fex config.fex image.cfg sunxi_gpt.fex toc0.fex usbtool_crash.fex Venv.fex
From the files extracted you can identify the four files mentioned above:
- boot0_sdcard.fex is the boot0
- boot_package.fex is the boot package image
- boot-resource.fex is the boot.img
- env.fex is the env.img
Using the stock SDCARD or image¶
You can use the stock sdcard that came with your console, or download the image from anbernic's firmware page.
This method requires to play with some offsets to get the correct boot0 and boot_package partitions.
If you have the firmware image (RG35XXH-EN16GB-OS240330.IMG), then you can extract boot0 with the dd command:
And for boot-package:
For boot.img and env.img, those are coming directly from partitions 1 and 2 of that image. To extract those, first run fdisk -l against the image:
$ fdisk -l RG35XXH-EN16GB-OS240330.IMG
Disk RG35XXH-EN16GB-OS240330.IMG: 14.41 GiB, 15476981760 bytes, 30228480 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: AB6F3888-569A-4926-9668-80941DCB40BC
Device Start End Sectors Size Type
RG35XXH-EN16GB-OS240330.IMG1 73728 8880127 8806400 4.2G Microsoft basic data
RG35XXH-EN16GB-OS240330.IMG2 8880128 8945663 65536 32M Microsoft basic data
RG35XXH-EN16GB-OS240330.IMG3 8945664 8978431 32768 16M Microsoft basic data
RG35XXH-EN16GB-OS240330.IMG4 8978432 9109503 131072 64M Microsoft basic data
RG35XXH-EN16GB-OS240330.IMG5 9109504 25886719 16777216 8G Microsoft basic data
RG35XXH-EN16GB-OS240330.IMG6 25886720 30226431 4339712 2.1G Microsoft basic data
Then extract partitions 1 and 2 with:
dd if=RG35XXH-EN16GB-OS240330.IMG of=boot.img bs=512 skip=73728 count=8806400
dd if=RG35XXH-EN16GB-OS240330.IMG of=env.img bs=512 skip=8880128 count=8945663
If you use the SDCARD, just replace RG35XXH-EN16GB-OS240330.IMG
with the device of your sdcard. In this example is /dev/sdh but you will need to identify the correct device.
And for boot-package:
To extract the boot.img and env.img (partitions 1 and 2) we can just dump the sdcard partitions directly:
Putting everything back together¶
Once you have the main elements (boot0.img, boot-package.img, boot.img, and env.img) you can reconstruct a working SDCARD:
- Create a new gpt based SDCARD with 4 partitions and make sure the first partition starts at block 73728.
- Flash the internal partitions boot0 and boot_package.img:
sudo dd if=boot0.img of=/dev/sdh bs=1024 seek=8
sudo dd if=boot_package.img of=/dev/sdh bs=1024 seek=16400
- Flash the boot.img and env.img
Partition 3 of the sdcard is boot-resource, that typically contains bootlogo.bmp
that is the boot splash screen logo, as well as the rootfs in squashfs format (boot/batocera
).