pftf / RPi4

Raspberry Pi 4 UEFI Firmware Images
https://rpi4-uefi.dev
Other
1.21k stars 143 forks source link

Chain load from Uboot? #155

Open adam900710 opened 3 years ago

adam900710 commented 3 years ago

Hi,

I'm wondering what's needed to chain load from Uboot.

The compiled result RPI_EFI.fd doesn't have EFI/PE/ELF header, thus none of the bootefi, booti, bootelf commands work.

Or is there anyway to exact the PE/ELF/EFI part to allow Uboot to chainload?

adam900710 commented 3 years ago

The EFI header seems to begin at offset 0x20000, let me try boot from there.

TheMindVirus commented 3 years ago

The Pi usually boots from one of 3 places: 0x80000 (Aarch64 kernel EL2), 0x8000 (Aarch32 kernel) or 0x0 (armstub EL3). You can specify where it starts from in config.txt with the kernel_address, kernel_old, kernel and armstub options, but it has to match what RPI_EFI.fd has in its compiler/linker script (link.ld).

For me on Pi4 it loads to address 0x0 and from there it may branch to somewhere like 0x20000. Keep it at 0x0 for linker consistency.

You'll also need to have start.elf/start4.elf, fixup.dat/fixup4.dat and for Pi's that don't have it built-in bootcode.bin. It will also need the device tree file of the Pi you're using (e.g. bcm2711-rpi-4-b.dtb) plus the overlays folder if necessary.

adam900710 commented 3 years ago

Sorry, I mean chainloading from Uboot.

This means, I already have Uboot running, being able to load whatever I need, and already have the infrastructure, and no need to bother config.txt

The problem is, there is no command allowing Uboot to try to boot from RPI_EFI.fd.

TheMindVirus commented 3 years ago

It will still need to boot from address 0x0. Have you tried a sequence of fatload, nm and go for that? All the Pi has to do is a single branch ideally, so having 3 different commands to resolve the 0x0 clash is a bit awkward.

adam900710 commented 3 years ago

I can load the RPI_EFI.fd to address 0x0, and crash if go 0x0.

What nm commands needs to be executed to let Uboot execute the proper code segement other than the padding header?

TheMindVirus commented 3 years ago

It would be something like what's written on this page to fill memory from 0x0 with RPI_EFI.fd before branching to it: https://www.denx.de/wiki/DULG/UBootCmdGroupMemory A better approach may be to branch from a u-boot C module: https://www.denx.de/wiki/view/U-Bootdoc/StandalonePrograms

If you got u-boot from the Mainline distribution, USB support doesn't work. There are other branches available here: https://elinux.org/RPi_U-Boot

adam900710 commented 3 years ago

Sorry, but maybe I'm too stupid, but what did you mean by "branching" to it?

From what I understand, the RPI_EFI.fd is an arm stub, which means it's an image with ATF at its head I guess? And since it's using ATF, it's not really a good idea to execute from Uboot as it has its own initialization or things like that.

For the USB support it doesn't matter, I have loaded RPI_EFI.fd to the ESP partition where the Uboot (default) locates and can access without problem.

Anyway, consider how complex it is, it doesn't really seem worthy now.

TheMindVirus commented 3 years ago

Branching/Jumping/Calling changes the address of the next instruction (with optional link to specify an address to return to). This is address 0x0 for when RPI_EFI.fd is loaded (copied) to address 0x0 beforehand. It doesn't need to return so no link, just b. It should have no other initialisation (except it did on ARM32 Pi1).

Chain-loading/Launching an App from u-boot is a perfectly acceptable thing to want to do but it has no C/Shell abstraction as simple as it is in Assembly Language (like many other SoC features, there's an entire unexplored world in there).

paulwratt commented 2 years ago

So U-Boot is EFI compliant, and the resulting RP_EFI.fd (UEFI) will find everything, including Variables and DeviceTree, to make available to resulting OS?

If you still need bootcode.bin then this chain wont work as implied (with presets from U-Boot).

wmjb commented 1 year ago

simple, assuming the TXT_BASE address in the firmware is 80110000 and the UEFI firmware is on usb port 1 partition 1, in u-boot console

load usb 0:1 80110000 RP_EFI.fd go 80110000

that's it.