The following instructions target at 8Gb model with USB drive used as root. This model seems to be more buggy than other, so some steps could probably be omitted on other models. You will likely need USB-to-TTL until USB works.
This board can boot with both mainline and device-specific kernel. On mainline kernel GPIO UART address is /dev/ttyS1 for mainline kernel or /dev/ttyAMA0 for device-specific one.
linux-raspberrypi4 is built to be compatible with other kernels and u-boot package: kernel is moved to rpi4Image, dtbs are located in /boot/broadcom, cmdline.txt and config.txt are renamed to *.rpi4
In the following sections mainline kernel is used. Device-specific kernel doesn’t seem to support serial tty on 8Gb model.
This step is needed even if you want all boot files to be located on USB drive unless you use other image to update eeprom firmware. At this step USB doesn’t work on 8Gb model.
RPi4 firmware expects an MBR device with FAT32 partition with boot files on it. It makes sense to mount this partition as /boot. Other partitions must be readable for whatever stage is started next (i.e. u-boot or kernel itself).
Mount all the partitions and unpack chosen rootfs on them. RPi4 also needs extra firmware provided by raspberrypi-bootloader and raspberrypi-bootloader-x packages from ALARM. If are not running aarch64 linux, just download these packages and unpack their /boot folders to your /boot partition. If you want to use u-boot at this stage, do the same with uboot-raspberrypi package. At this point you have two boot options.
If you use u-boot, create boot.cmd with following contents:
setenv bootargs console=ttyS1,115200 console=tty0 root=/dev/mmcblk1p2 rw rootwait smsc95xx.macaddr="${usbethaddr}"
load mmc 0:1 ${kernel_addr_r} /Image
load mmc 0:1 ${ramdisk_addr_r} /initramfs-linux.uimg
load mmc 0:1 ${fdt_addr_r} /dtbs/broadcom/bcm2711-rpi-4-b.dtb
booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r}
Create boot sript with “mkimage -A arm -T script -d boot.cmd boot.scr”. You also need to create u-boot image for initrd: “mkimage -A arm -T ramdisk -d initramfs-linux.img initramfs-linux.uimg”. If you want to use device-specific kernel, replace kernel, initramfs and dtb names with the appropriate ones. You still need to run mkiamge in this case.
If you want to boot kernel directly, configure /boot/config.txt and /boot/cmdline.txt as follows:
config.txt:
enable_uart=1
arm_64bit=1
kernel=/Image
initramfs /initramfs-linux.img followkernel
device-tree=/dtbs/broadcom/bcm2711-rpi-4-b.dtb
cmdline.txt:
console=ttyS1,115200 earlyprintk=serial,ttyS1,115200 root=/dev/mmcblk1p2 rw rootwait smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0
Since u-boot is not used in this case, you don’t need to create any additionale images.
Now you can start your RPi4. You may encounter problems with wireless interface detection. In some cases removing the following files can help:
On running RPi4 build and install AUR package rpi-eeprom-git. In /etc/default/rpi-eeprom-update set FIRMWARE_RELEASE_STATUS=“stable”. After that run “rpi-eeprom-update -a -d” to install newer version (you need at least version 000138a1 from 16 Jan 2021 to make USB boot possible). Before you reboot, run “rpi-eeprom-config -e” and set BOOT_ORDER=0xf41. It is also recommended to set BOOT_UART=1 to see debug messages before loading kernel.
Now your board will be able to boot from USB drive.
After you updated and configured eeprom you can make your RPi4 boot directly from USB.
To let kernel read root partition from USB you need to add MODULES=(pcie_brcmstb) to /etc/mkinitcpio.conf and rebuild initramfs by “mkinitcpio -p linux-aarch64”. If you don’t have working aarch64 device, you can perform this step on RPi4 booted from SD card and copy /boot/initramfs-linux.img to USB drive /boot folder.
Partition scheme is same as for sdcard. Installation process consists of same steps but you can have problems if using u-boot. You can boot kernel directly with the following config.txt (for mainline kernel):
enable_uart=1
arm_64bit=1
kernel=/Image
initramfs /initramfs-linux.img followkernel
device-tree=/dtbs/broadcom/bcm2711-rpi-4-b.dtb
and cmdline.txt:
console=ttyS1,115200 earlyprintk=serial,ttyS1,115200 kgdboc=ttyS1,115200 root=/dev/sda2 ro rootwait smsc95xx.turbo_mode=N dwc_otg.lpm_enable=0
It is also recommended to sync rootflags= option with / mount options in /etc/fstab to make sure root will be remounted read-write. Mounting it read-only is recommended here since for some reason fsck is often needed after reboots.
In order to boot from USB remove SD card or remove bootable files from it. After that board will automatically find needed files on USB drive and boot from them. However, in order to prevent periodical spamming messages about absent sdcard in dmesg, insert SD card after kernel is started.
If you have to perform fsck too often and lose data on reboots, try using btrfs.