My Haiku ARM (UEFI) port progress

sure, I pushed to github: https://github.com/davidkaroly/haiku/commits/dev/arm/virtio-block

10 Likes

I haven’t looked into enter_userspace yet as I was trying to consolidate my patches for the previous phases first.

Boostrapping:

  • currently bootstrapping fails for ARM because of the float-abi issue and outdated package version
  • I was able to get a successful gcc_bootstrap by adding -nostartfiles to the compiler options for libgcc-boot.a etc. If I also update the package versions then we get a successful ARM bootstrap. (even though the bootloader is still built with hard-float)
    So the question… do you guys think it’s a good approach to use nostartfiles to avoid linking libgcc-boot to the glue or should we rather try to build a glue-boot with softfloat instead?

Bootloader:

  • it’s still built with hardfloat, probably the compile flags will need to be adjusted in ArchitectureRules
  • MMU setup seems to be good enough for the kernel to start, even though maybe a bit too many things are still identity-mapped
  • we need a fixup in the ELF relocation routine - the kernel is located in high addresses above 0x80000000 in virtual address space but currently the bootloader uses the physical addresses for relocation

Kernel - virtio initialization - reviews are open, I got a few comments so I’ll try to rework my patches

Page table initialization: I found a few issues in this area, this probably needs to be cleaned up before we can switch to user space

  • page table allocation and alignment needs to be adjusted
  • switch TTBR on thread context switch - this is not implemented yet, the remaining identity-mapped regions have to be removed to get it working.
7 Likes

You can see my RISC-V code as reference: haiku_loader.riscv, haiku_loader.efi. But on 32 bits mapping of whole RAM memory may be not possible.

It is hard to tell from such a short description of the problems. Are there bugreports to reference for this? Are they up to date on what’s happening? It would help discussing the issue.

What I remember from my previous attempts (probably out of date):

  • By default, ARM compiler are built in multilib mode, which means they create several versions of libgcc for different ABIs (soft and had floats, etc)
  • I could not get this to work with our build which expected libraries to be built in hardcoded locations at the time (but now our 64bit compiler is also multilib, so maybe this issue is solved?)
  • So I had tried to build everything with multilib disabled, and a single hardfloat libgcc. At the time we were planning to use uboot without UEFI, so it made sense to use hadfloat for everything. Now if we use EFI, it seems that requires usage of a softfloat ABI to call the EFI functions (if I understand things correctly, I could be wrong here).

Ideally we would build gcc normally (in multilib mode) and adjust our buildsystem and recipes to work correctly with that. Then we can use gcc with various compiler flags to build things with hardfloat or softfloat easily and without recompiling a full gcc everytime. It would be a lot simpler.

How is this done on x86 and other architectures? My understanding is we start with identity mapping because it allows us to switch from “mmu disabled” to “mmu enabled” transparently, but after that there is no reason to remain in identity mapping mode. There was also some confusion here because for various devices we tried, the space at 80000000 was not always free (for example, all physical RAM was there on some devices, and after identity mapping it there was no space left for the kernel). Does EFI provide some kind of standardization of the virtual memory space, or is it still completely hardware dependant?

No fixed address are needed, everything can be allocated completely dynamically like it is done on RISC-V. EFI provides API for physical memory allocation. Virtual memory layout is under complete OS control, EFI is running with identity mapping or MMU disabled.

2 Likes

In the bootloader the ELF loader we have map functions but only for UEFI and ELF64. They do translation before entering kernel. However that code only exist for ELF64. When transitioning to kernel we need to do the real mapping with MMU.

Why not the same for 32 bits? I think that 32 and 64 code should be unified including boot loader ↔ kernel address translation.

1 Like

That is what we should do. The only reason it does not exist for ELF32 is because the UEFI port focused on x86_64 and at the time there were not many known 32 bit UEFI usecases.

Here is a code example: https://github.com/haiku/haiku/blob/38eb9fb0eb050aefd2ca57bd87210a1cce158aa4/src/system/boot/loader/elf.cpp#L140

1 Like

That all should go in platform_bootloader_address_to_kernel_address (why so long name?).

I have 32 x86 EFI only tablet that probably can run Haiku when 32 bit EFI support will be added.

No idea about the name. You can run 32 bit UEFI in QEMU. So porting UEFI to 32 bit should not be that hard for x86.

I don’t see how the name could be shorter. The platform_ prefix indicates this function is platform specific (there will be implementations for efi, openfirmware, bios, … as needed). And the remaining part of the function clearly indicates what this does. In the lack of any documentation, there isn’t much choice but to be very explicit in function names, so people working on the code have a chance to understand what’s going on. And no one wants to read or even write documentation.

4 Likes

Yes, I found ticket #16763 with matching error messages from gcc.

1 Like

I haven’t posted in a while… some slower progress with the ARM port lately.

Bootstrap build: now it almost works, one (hopefully last) remaining issue is the build of make_bootstrap.
see issue #6417 in haikuports github repo.

Once that’s settled, perhaps we can try do to an unbootstrap, and then instruct the regular (non-bootstrap) build process to start using the newly unbootstrapped packages… but this bootstrap/unbootstrap concept is not very clear for me unfortunately.

5 Likes

I’m trying to achieve something similar here:
https://review.haiku-os.org/c/haiku/+/4675

4 Likes

Does it enable 32 bit haiku_loader?

This process is a bit of a hack.

The way the bootstrap process was initially designed is:

  • Do a bootstrap build
  • Boot this build
  • Use it to run haikuporter and compile packages
  • These packages can be published on haiku package repository
  • From then on, nomal non-bootstrap builds become possible

This works reasonably well for architectures that already boot to the desktop, but not so much when you are working on bringing up a new architecture. So an alternative process was designed for this:

  • Do a bootstrap build
  • You don’t need to boot it
  • Get the hpkg files from your build and copy them to an Haiku system
  • Run the unbootstrap.sh script that will convert the “bootstrap” packages to non-bootstrap one (it just does some renaming and changes in package metadata)
  • Upload the resulting packages to haiku package server

Once this is done, people can reuse these packages to do a “normal” build of Haiku, which is faster (no need to build all these packages, they can instead just be downloaded).

The process to upload packages on the haiku server is also not very clear to me. I know a way to do it (which I have documented at HaikuPorts build-packages repository — Haiku internals documentation ) but this does not work for architectures that don’t have an haikuports builder set up.

I don’t know the process to do it without a builder. Kallisti5 explained some things to me but it involves running some commands as root user on our main server and I don’t feel confident to try that without a well written documentation. So the current process is, send your unbootstrapped packages to kallisti5 and wait until he does it?

6 Likes

i’m using it for 32-bit ARM EFI bootloader, it seems to work quite well

if your question refers to 32-bit EFI boot on x86, probably this change it not enough and some changes will be needed in kernel/arch/x86/arch_elf.cpp to invoke boot_elf32_set_relocation()

1 Like

Yes, it was about 32-bit EFI boot on x86. Thanks for clarification.

BTW, do you think you can fix that while you’re at it? I’m not sure if Qemu supports that though.

arch/x86/ is almost empty in boot/plarform/efi so some porting will be needed. I can try to have a look at it.

3 Likes