UEFI Haiku boot loader for ARM

You are correct @X512 , is 64bit ARM (* CPU: 64-bit Quad-core 1.2 GHz ARM Cortex A-53 * GPU: MALI-400MP2). If I can help, let me know, though beware I got no skill on porting stuff, I struggle with Python and GDScript :joy::rofl:

Thanks and regards!
RR

Allwinner 64 bit SoCs start in aarch32 execution state. hence uboot is also 32 bit. it uses some Allwinner hack, to force it to reset into 64 bit if needed (bootm, booti but not go). maybe this will work with UEFI payload to uboot (bootefi), probably not, but you can try. when I first ran my bare metal code with Pine64+, having the same A64 SoC as pinephone does, and used the go command, my aarch64 code, caused the SoC to spit the undefined instruction exception. switching to using bootm and booti, worked fine with the same code. That’s because exactly on executing those commands, 32 bit uboot was making the trick. it was some time ago and since then uboot could switch to 64 bit for itself. but as I said above, you hardly will see anything, unless uboot on pinephone does support GOP (LCD panel) and the OSL in question and Haiku itself uses framebuffer address transferred through GOP.

Good day @val,

As I always say, “Ignorance knows no fear”, so bear this in mind, as my ignorance on this topic is broad. Actually, while I do get an idea on what you mean, I really have no clue on how to reproduce anything you or @X512 do, lack of knowledge and skill. That being said, at the moment I just would like to see the Haiku boot icons on the screen. That would be enough for now, just for marketing purposes and to draw/drive attention on Haiku.

I presume that it would be easier with a Pine Rock64 board, I mean, to do the testing (standard keyboard, mouse, hdmi out), but it’s the Pinephone what I have now. Nonetheless, (ignorance speaking again) and I say this without yet being able to work seriously with the Layout API, if it is well designed, it would be a nice contender for a phone/touch sized device, as none of the available environments adapts well to the phone screen when scaling, in case they allow scaling. UBPorts, Phosh, Plasma Mobile, Gnome, all have plenty of issues, and only UBPorts (UT Tweak) and Plasma allow scaling; Gnome does allow scaling but need to use a external display and keyboard to set it through Tweaks.

Yes, I know Haiku targets desktop computing, not touch devices nor phones. Though the idea of a Haiku device in your pocket… mmmm…:drooling_face::drooling_face::drooling_face:

Regards,
RR

Pinephone seems support GOP: lib/efi_loader/efi_gop.c · master · Pine64 / u-boot · GitLab.

1 Like

I have managed to launch haiku uefi on opensuse:

qemu-system-arm -bios /usr/share/qemu/qemu-uefi-aarch32.bin -M virt -cpu cortex-a7 -m 1024 -cdrom haiku-mmc.image  --device ramfb -serial stdio

And Now the kernel is launched, showing the gray icons:

2021-04-13 21-55-09屏幕截图

And I have add the test code as @X512 mentioned showing the blue screen, now it freezed when setup pl011 uart device.

ArchUARTPL011::InitEarly()
{
	// Perform special hardware UART configuration
	Barrier();

	// ** Loopback test
	uint32 cr = PL01x_CR_UARTEN;
		// Enable UART
	cr |= PL011_CR_TXE;
		// Enable TX
	cr |= PL011_CR_LBE;
		// Enable Loopback mode
	Out32(PL011_CR, cr);

And the qemu report a invalid address accessed, it will break. I have checked the qemu virt machine, the pl011 reg addres is 0x09000000, same as the init process

gArchDebugUART = arch_get_uart_pl011(0x9000000, 0x16e3600);

And I have checked the different code for pl011, and I found little kernel is the most simple: https://github.com/littlekernel/lk/blob/master/platform/qemu-virt-arm/include/platform/qemu-virt.h

#if ARCH_ARM64`Preformatted text`
#define PERIPHERAL_BASE_VIRT (0xffffffffc0000000ULL) // -1GB
#else
#define PERIPHERAL_BASE_VIRT (0xc0000000UL) // -1GB
#endif

/* individual peripherals in this mapping */
#define FLASH_BASE_VIRT     (PERIPHERAL_BASE_VIRT + 0)
#define FLASH_SIZE          (0x08000000)
#define CPUPRIV_BASE_VIRT   (PERIPHERAL_BASE_VIRT + 0x08000000)
#define CPUPRIV_BASE_PHYS   (PERIPHERAL_BASE_PHYS + 0x08000000)
#define CPUPRIV_SIZE        (0x00020000)
#define UART_BASE           (PERIPHERAL_BASE_VIRT + 0x09000000)

when I tried it with:

gArchDebugUART = arch_get_uart_pl011(0xC9000000, 0x16e3600);

it will not meet the segment, but it will hang when reading from reg:

  	while (In32(PL01x_FR) & PL01x_FR_BUSY)
	Barrier();

That’s all about pl011.

maybe we have the different peripherals memory map for setting up registers. Some one could give some valid message?

8 Likes

Normally the peripherals should not be hardcoded this way. Instead they should be found from the device tree. The problem is, it’s hard to debug the device tree code without a serial port.

Also, it’s likely there are problems with the MMU setup, which results in peripherals not being mapped, or not where we think they are. But again, without debugging output it’s hard to know for sure what is happening.

That is fine for start. If I remember correctly, FDT handling was dropped recently.

I created mini OS (screenshot) for experiments with RISC-V that run on TinyEMU, it use graphics for debug output, it have no console support at all. Framebuffer was one of first implemented things.

4 Likes

I found that zircon kernel add the efi table as kernel args, maybe we can use the kSystemTable->ConOut->OutputString as the default debug serial console:

  // pass EFI system table
  uint64_t addr = (uintptr_t)sys;
  hdr.type = ZBI_TYPE_EFI_SYSTEM_TABLE;
  hdr.length = sizeof(sys);
  if (add_bootdata(&bptr, &blen, &hdr, &addr)) {
    return -1;
  }

according to https://github.com/vsrinivas/fuchsia/blob/4f31fb23cea1cd0531808bd96c3adffc010bcf9f/src/firmware/gigaboot/src/zircon.c

And I will try this, maybe tomorrow.

2 Likes

Interesting, maybe exiting EFI boot services can be moved from boot loader to kernel to let kernel use boot services on early stages.

Don’t forget to remove exiting EFI boot services from boot loader.

this is what they do. https://github.com/vsrinivas/fuchsia/blob/4f31fb23cea1cd0531808bd96c3adffc010bcf9f/zircon/kernel/platform/pc/efi.cc

  1. create a vm address space.
  2. map the phys/virt space
  3. Switch into the address space where EFI services have been mapped.
  4. activate the services.

I looked source a bit and found that it exit boot services before running kernel and only EFI runtime services are used in kernel. EFI runtime services have no console output.

After some searching, I have find this https://lore.kernel.org/patchwork/patch/250840/

# efi: Retain boot service code until after switching to virtual mode

The specification makes it clear that the operating system is free to do
whatever it wants with boot services code after ExitBootServices() has been
called. SetVirtualAddressMap() can't be called until ExitBootServices() has
been. So, obviously, a whole bunch of EFI implementations call into boot
services code when we do that. Since we've been charmingly naive and
trusted that the specification may be somehow relevant to the real world,
we've already stuffed a picture of a penguin or something in that address
space. And just to make things more entertaining, we've also marked it
non-executable.

This patch allocates the boot services regions during EFI init and makes
sure that they're executable. Then, after SetVirtualAddressMap(), it
discards them and everyone lives happily ever after. Except for the ones
who have to work on EFI, who live sad lives haunted by the knowledge that
someone's eventually going to write yet another firmware specification.

Maybe we can give it a try.

I managed to run default minimum-raw build of ARM UEFI Haiku on Haiku. I used following command:

qemu-system-arm -bios /boot/home/received/qemu-uefi-aarch32-202102-3.1.noarch/usr/share/qemu/qemu-uefi-aarch32.bin -M virt -m 1024 -hda efi.image -hdb haiku-minimum.image -device ramfb -usb -device qemu-xhci,id=xhci -device usb-mouse -device usb-kbd -serial stdio

qemu-uefi-aarch32.bin is extracted from here.

efi.image is manually constructed FAT32 image with /efi/boot/bootarm.efi copied from objects/haiku/arm/release/system/boot/efi/haiku_loader.efi.

minimum-mmc don’t build because of missing mkimage, I can’t find it in repository and it fail to build from HaikuPorts.

1 Like

if you want to boot haiku efi with the qemu-uefi-aarch32-202102-3.1.noarch/usr/share/qemu/qemu-uefi-aarch32.bin from opensuse. you will meet the issues as below:

  1. it will show no valid boot volume, you could apply this patch https://review.haiku-os.org/c/haiku/+/3834 to solve this issue.

  2. it will hang when enter booting environment, you should comment out code as blelow to disable menu select (which doesn’t work for this firmware, the kBootServices->WaitForEvent(1, &event, &index); can’t be activated when key pressed.):

     //comment this out to disable menu select
    

    //menu->Run();

    apply_safe_mode_options(safeModeMenu);
    apply_safe_mode_options(debugMenu);
    apply_safe_mode_path_blocklist();
    add_safe_mode_settings(sSafeModeOptionsBuffer.String());
    delete menu;

then you will got the grey boot splash.

It is working perfectly fine for me without any changes. It automatically detect boot volume and boot kernel. Boot menu can be displayed by pressing space.

1 Like

wow, the qemu with opensuse is really buggy. Maybe I should try developing with haiku now. :wink:

Also using another disk for EFI boot loader may be related.

And with my patch, only with the haiku-mmc.image, qemu could launch.

This?

pkgman s cmd:mkimage
Status  Name          Description                            
-------------------------------------------------------------
        u_boot_tools  Utilities for working with 'Das U-Boot'