2

I recently acquired a quite nice Chinese ARM computer board, the ITX-3588J from Firefly (aka. T-Chip) and with core processor made by RockChip. By itself, the board is an integrated single-board computer (SBC) so it requires no extra expansion cards or drives to work, however it supports adding up to 4 SATA drives and 1 PCIe x8 card. By itself, it reads both its operating system and firmware off of a flash MMC chip built into the board, and MMC flash packages were available from the vendor both for pre-made Android 12 and Ubuntu 20.04 installs.

But given the limited storage on the MMC, I added an SSD drive with 250 GB capacity, and was also hoping I could install a newer version of Ubuntu, namely 22.04, and am wondering if it's possible to do this. The trouble is, there's virtually no real good information on doing this because this board is so new - it was literally premiered this year, and all the Firefly/Rockchip offerings from before were smaller and considerably less powerful. Nonetheless, I've been hacking at it ever since I got it, with no full success yet.

The included flash package for the MMC contains a "U-Boot" base bootloader/firmware type package, which then boots extlinux, and finally fires up the main kernel. What I'd like to know is if there's some way to (particularly using the first bootloader or another) rig this to boot an Ubuntu 22.04 USB stick image, in particular the "jammy-desktop-arm64.iso" from

https://cdimage.ubuntu.com/jammy/daily-live/current/

website with aim to install to the hard drive. And I never knew of such a thing called "U-Boot" until now, and this is literally my first time having had any experience with it and everything else I've found about it seems geared to advanced users who already know it in and out, and other use cases than mine - no information I've found covers "how to boot an Ubuntu USB .iso for ARM via U-Boot"! And the documentation, again, seems to be written from the point of view of a board manufacturer or vendor, not a user.

So, is this possible? If so, how do you do it? Do you need to upgrade the U-Boot - the version that came with that package was 2017.04, and it looks to be missing some featuers that are present in the 2022 release such as "bootefi" and I note the USB stick has some .efi files. Installing a new U-Boot looks tricky because the latest Rockchip board-specific bit that is in the mainline U-Boot package for download is RK3568 - not surprised given this board was literally premiered in April of this year, but still, and suggests custom code from the vendor was added to produce the Ubuntu flash pack, though the vendor does apparently offer a board SDK available "on request".

But ideally, I'd like to not have to mess with all that if it is not absolutely necessary and there's some way to hook into the chain the ability to boot that USB stick another way. Is there?

ADD:

The output from U-Boot "help" is

=> help                                                                         
?       - alias for 'help'                                                      
android_print_hdr- print android image header                                   
atags   - Dump all atags                                                        
base    - print or set address offset                                           
bdinfo  - print Board Info structure                                            
bidram_dump- Dump bidram layout                                                 
blk     - Block device sub-system                                               
boot    - boot default, i.e., run 'bootcmd'                                     
boot_android- Execute the Android Bootloader flow.                              
boot_fit- Boot FIT Image from memory or boot/recovery partition                 
bootavb - Execute the Android avb a/b boot flow.                                
bootd   - boot default, i.e., run 'bootcmd'                                     
booti   - boot arm64 Linux Image image from memory                              
bootm   - boot application image from memory                                    
bootp   - boot image via network using BOOTP/TFTP protocol                      
bootz   - boot Linux zImage image from memory                                   
charge  - Charge display                                                        
cmp     - memory compare                                                        
coninfo - print console devices and information                                 
cp      - memory copy                                                           
crc32   - checksum calculation                                                  
crypto_sum- crypto checksum engine                                              
dhcp    - boot image via network using DHCP/TFTP protocol                       
dm      - Driver model low level access                                         
download- enter rockusb/bootrom download mode                                   
dtimg   - manipulate dtb/dtbo Android image                                     
dump_irqs- Dump IRQs                                                            
dump_resource- dump resource list                                               
echo    - echo args to console                                                  
editenv - edit environment variable                                             
env     - environment handling commands                                         
exit    - exit script                                                           
ext2load- load binary file from a Ext2 filesystem                               
ext2ls  - list files in a directory (default /)                                 
ext4load- load binary file from a Ext4 filesystem                               
ext4ls  - list files in a directory (default /)                                 
ext4size- determine a file's size                                               
false   - do nothing, unsuccessfully                                            
fastboot- use USB or UDP Fastboot protocol                                      
fatinfo - print information about filesystem                                    
fatload - load binary file from a dos filesystem                                
fatls   - list files in a directory (default /)                                 
fatsize - determine a file's size                                               
fatwrite- write file into a dos filesystem                                      
fdt     - flattened device tree utility commands                                
fstype  - Look up a filesystem type                                             
go      - start application at address 'addr'                                   
gpt     - GUID Partition Table                                                  
help    - print command description/usage                                       
iomem   - Show iomem data by device compatible(high priority) or node name      
lcdputs - print string on video framebuffer                                     
load    - load binary file from a filesystem                                    
loop    - infinite loop on address range                                        
ls      - list files in a directory (default /)                                 
md      - memory display                                                        
mdio    - MDIO utility commands                                                 
mii     - MII utility commands                                                  
mm      - memory modify (auto-incrementing address)                             
mmc     - MMC sub system                                                        
mmcinfo - display MMC info                                                      
mtd_blk - MTD Block device sub-system                                           
mw      - memory write (fill)                                                   
nfs     - boot image via network using NFS protocol                             
nm      - memory modify (constant address)                                      
part    - disk partition related commands                                       
ping    - send ICMP ECHO_REQUEST to network host                                
printenv- print environment variables                                           
pxe     - commands to get and boot from pxe files                               
rbrom   - Perform RESET of the CPU                                              
reboot  - Perform RESET of the CPU, alias of 'reset'                            
reset   - Perform RESET of the CPU                                              
rkimgtest- Test if storage media have rockchip image                            
rockchip_show_bmp- load and display bmp from resource partition                 
rockchip_show_logo- load and display log from resource partition                
rockusb - Use the rockusb Protocol                                              
run     - run commands in an environment variable                               
save    - save file to a filesystem                                             
saveenv - save environment variables to persistent storage                      
setcurs - set cursor position within screen                                     
setenv  - set environment variables                                             
sf      - SPI flash sub-system                                                  
showvar - print local hushshell variables                                       
size    - determine a file's size                                               
source  - run script from memory                                                
sspi    - SPI utility command                                                   
sysboot - command to get and boot from syslinux files                           
sysmem_dump- Dump sysmem layout                                                 
sysmem_search- Search a available sysmem region                                 
test    - minimal test like /bin/sh                                             
tftp    - download image via network using TFTP protocol                        
tftpbootm- tftpbootm aosp/uImage/FIT image via network using TFTP protocol      
tftpflash- flash image via network using TFTP protocol                          
tftpput - TFTP put command, for uploading files to a server                     
true    - do nothing, successfully                                              
ums     - Use the UMS [USB Mass Storage]                                        
usb     - USB sub-system                                                        
usbboot - boot from USB device                                                  
version - print monitor, compiler and linker version   

The output from U-Boot "printenv" is

=> printenv
arch=arm
autoload=no
baudrate=1500000
board=evb_rk3588
board_name=evb_rk3588
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf
boot_net_usb_start=usb start
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_targets=mmc1 mmc0 usb0 pxe dhcp 
bootargs=storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal  storagenode=/mmc@fe2e0000
bootcmd=boot_android ${devtype} ${devnum};boot_fit;bootrkp;run distro_bootcmd;
bootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi;
bootcmd_mmc0=setenv devnum 0; run mmc_boot
bootcmd_mmc1=setenv devnum 1; run mmc_boot
bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
bootcmd_usb0=setenv devnum 0; run usb_boot
bootdelay=0
cpu=armv8
devnum=0
devplist=3
devtype=mmc
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
eth1addr=ce:20:d9:ee:5d:8d
ethaddr=ca:20:d9:ee:5d:8d
fdt_addr_r=0x0a100000
fileaddr=0xedf00000
filesize=0x1f34a
kernel_addr_c=0x05480000
kernel_addr_r=0x00400000
mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi
partitions=uuid_disk=${uuid_gpt_disk};name=uboot,start=8MB,size=4MB,uuid=${uuid_gpt_loader2};name=trust,size=4M,uuid=${uuid_gpt_atf};name=misc,size=4MB,uuid=${uuid_gpt_misc};name=resource,size=16MB,uuid=${uuid_gpt_resource};name=kernel,size=32M,uuid=${uuid_gpt_kernel};name=boot,size=32M,bootable,uuid=${uuid_gpt_boot};name=recovery,size=32M,uuid=${uuid_gpt_recovery};name=backup,size=112M,uuid=${uuid_gpt_backup};name=cache,size=512M,uuid=${uuid_gpt_cache};name=system,size=2048M,uuid=${uuid_gpt_system};name=metadata,size=16M,uuid=${uuid_gpt_metadata};name=vendor,size=32M,uuid=${uuid_gpt_vendor};name=oem,size=32M,uuid=${uuid_gpt_oem};name=frp,size=512K,uuid=${uuid_gpt_frp};name=security,size=2M,uuid=${uuid_gpt_security};name=userdata,size=-,uuid=${uuid_gpt_userdata};
pxefile_addr_r=0x00600000
ramdisk_addr_r=0x0a200000
rkimg_bootdev=if mmc dev 1 && rkimgtest mmc 1; then setenv devtype mmc; setenv devnum 1; echo Boot from SDcard;elif mmc dev 0; then setenv devtype mmc; setenv devnum 0;elif mtd_blk dev 0; then setenv devtype mtd; setenv devnum 0;elif mtd_blk dev 1; then setenv devtype mtd; setenv devnum 1;elif mtd_blk dev 2; then setenv devtype mtd; setenv devnum 2;elif rknand dev 0; then setenv devtype rknand; setenv devnum 0;elif rksfc dev 0; then setenv devtype spinand; setenv devnum 0;elif rksfc dev 1; then setenv devtype spinor; setenv devnum 1;elsesetenv devtype ramdisk; setenv devnum 0;fi; 
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x00500000
serial#=1bc8feb9d8c82bd2
soc=rockchip
stderr=serial,vidconsole
stdout=serial,vidconsole
usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
vendor=rockchip

Environment size: 3949/32764 bytes

ADD: GAAH! some of the lines above unfortunately got rudely truncated by minicom

ADD: Now I have the full output above with NO truncation. Could not get line wrapping to work so I instead used minicom's "captures" feature to capture everything to a file

ADD: I have also tried now some more experimentation with this. After examining the contents of the downloaded 22.04 Ubuntu image USB stick, I figured that it contains a kernel to be booted in /casper/vmlinuz, with a ramdisk /casper/initrd. I scraped the board FDT file from the stock Ubuntu 20.04 MMC image, which was located at /boot/rk3588-firefly-itx-3588j.dtb onto the USB stick at the same location, and then I tried the following U-Boot commands:

usb start
setenv bootargs 'root=/dev/sda1'
load usb 0:1 $kernel_addr_r /casper/vmlinuz
load usb 0:1 $ramdisk_addr_r /casper/initrd
load usb 0:1 $fdt_addr_r /boot/rk3588-firefly-itx-3588j.dtb
bootz $kernel_addr_r $ramdisk_addr_r $fdt_addr_r

which I gathered from reading about just "how to boot a kernel". All the commands go through, but then the last just says at most, "Fdt Ramdisk skip relocation", and returns me straight to the U-Boot prompt. Re-issuing the command simply does nothing at all. What does that mean?

0

1 Answer 1

2

What I'd like to know is if there's some way to (particularly using the first bootloader or another) rig this to boot ...

U-Boot is a widely-used second- or even third-stage boot program, especially on ARM SBCs.
The first-stage boot program is typically in ROM integrated into the SoC. U-Boot is designed to execute in RAM (just like the image it loads/boots), so there may be a second-stage boot program that loads U-Boot, which (typically) makes U-Boot a third-stage boot program.
U-Boot source code includes such a precursor program, which is referred to as the SPL, secondary program loader, to load U-Boot.

the vendor does apparently offer a board SDK available "on request".

To rebuild and/or customize U-Boot, you will have to obtain the source code for that specific board. The mainline version of U-Boot primarily supports development boards, rather than consumer-grade products. In theory per the GPL, the product manufacturer is supposed to make available the Open Source code to owners, but this is often ignored/violated by small companies.

Since the vendor does offer a BSP, then you should make the request.

If you search the web, you can find guides and tutorials for building U-Boot for popular ARM SBCs such as RPi and Beaglebone. Guides for NXP/Freescale and Atmel/Microchip will tend to be more technically/professionally oriented.

... there's some way to hook into the chain the ability to boot that USB stick another way. Is there?

Maybe, if USB capabilities have been built into the installed version of U-Boot.

Have you connected to the serial console (115200 baud, 8n1) of your board?
During the boot sequence, interrupt U-Boot by typing any key to obtain a command prompt.
Use the help command to obtain the available commands & capabilities. You need to have usb as a listed command-set in order to access a USB device as a boot medium.

The steps that U-Boot will perform to boot the kernel can be changed at its command line, i.e. load a kernel image (and Device Tree) from device/partition/filesystem X into memory at location Y. These steps can also be saved as an environment variable (bootcmd).


Addendum

Looks like you have a full-featured and customized (by the board manufacturer) version of U-Boot (for a high-capability motherboard). The necessary commands (i.e. usb, fat, and ext2/ext4) to boot from a USB device have been configured into that installed version. There are also numerous nonstandard/custom commands such as boot_android and usbboot. Such customization is a common reason for an apparent "outdated" version of software to to be installed in a consumer-grade board.

Besides the enhanced set of U-Boot commands, numerous environment variables have been defined to facilitate alternate booting schemes, such as using eMMC or SD card (bootcmd_mmc0/bootcmd_mmc1), USB storage devices (bootcmd_usb0), and the network (bootcmd_pxe and bootcmd_dhcp).

You probably do not need to rebuild U-Boot, but acquiring the SDK/BSP for the source code could still be helpful. It may have some documentation regarding the custom commands that were added. Some of the new boot commands and env variables apparently require specific files to be installed on the boot device (e.g. boot.scr.uimg and/or boot.scr).

Either a lot of experimentation is going to be required on your part, or you can acquire and study the "abundant resources" of "SDK, tutorials, tech docs, and dev tools" that Firefly claims to have available for this product.

Rather than use the generic 64-bit ARMv8 Ubuntu desktop image, suggest you stick to the Ubuntu image that Firefly offers. Once you depart from the industry-wide conventions of x86-style PC architecture, you will need knowledge/expertise of configuration schemes such as Device Tree (e.g. fdt file) for successful booting of alternate kernels.


Addendum II

...
load usb 0:1 $kernel_addr_r /casper/vmlinuz  
...
bootz $kernel_addr_r $ramdisk_addr_r $fdt_addr_r

Using a vmlinuz file for booting by U-Boot does not make sense. That is an ELF executable format, but you need to use a ready-to-execute image file, e.g. the Image file.
The low-level details of booting arm64 are described in this document.

The bootz command is intended for a zImage file, a self-decompressing form of an Image file.
Use booti for booting an Image file.
If the Image file has been manually/eternally compressed (e.g. Image.gz), then use a U-Boot command to explicitly decompress the file prior to booting with booti.

13
  • Yes, I have (connected with the serial). I will add some details of the full command list to the post. I know there are USB commands there, as I tried playing with them. Commented Jun 30, 2022 at 9:07
  • I just obtained and appended the information you wanted to the post. Do you see anything of interest? Commented Jun 30, 2022 at 19:28
  • Excellent! help and printenv are the two informative commands for inspecting SBCs. However the output of the latter is truncated on the right side. You need to enable line wrapping in the terminal emulator program. There's some custom commands, such as usbboot. Use help usbboot to get more info. Note that there's already somekind of booting capability from USB, i.e. the usb_boot environment variable, which can be "executed" with run usb_boot command.
    – sawdust
    Commented Jun 30, 2022 at 20:59
  • Just got the full, untruncated output and updated the OP. What do you think? Commented Jun 30, 2022 at 21:18
  • Thanks. Yeah, it looks like "experimentation" would be the only way to install this. One clue I note is that the generic image seems to contain GRUB, but the posted specs seem to suggest it is adopted for EXTLINUX. Moreover, there is a /boot/efi folder on the image, which I'm not sure what to do with in this case (if anything can be done with it). Commented Jul 1, 2022 at 2:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .