My Haiku ARM (UEFI) port progress

I tried the SFTP server today. I’m able to log in but I get permission error for root folder.
Can you double-check?

Oops, that’s my fault. Fixed.

Thank you, now it works fine.
I’ve uploaded the unbootstrapped packages to /build-packages/arm

3 Likes

Anyone tried a bootstrap build recently (for any architecture) i.e. since the switch to gcc-11?
I get failed configure scripts because of an ICE

arm-unknown-haiku-gcc: internal compiler error: in do_spec_1, at gcc.c:5971

reproducible from the command line, it happens if I don’t give any output file name to gcc with -o flag.

This works:

[david@fedora gcc_bootstrap-8.3.0_2019_05_24-obj]$ arm-unknown-haiku-gcc -c test.c
[david@fedora gcc_bootstrap-8.3.0_2019_05_24-obj]$ arm-unknown-haiku-gcc -o test test.o

But these given an error:

[david@fedora gcc_bootstrap-8.3.0_2019_05_24-obj]$ arm-unknown-haiku-gcc test.c
arm-unknown-haiku-gcc: internal compiler error: in do_spec_1, at gcc.c:5971
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
[david@fedora gcc_bootstrap-8.3.0_2019_05_24-obj]$ arm-unknown-haiku-gcc test.o
arm-unknown-haiku-gcc: internal compiler error: in do_spec_1, at gcc.c:5971
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
[david@fedora gcc_bootstrap-8.3.0_2019_05_24-obj]$

Maybe this is not entirely right?

#define LINK_SPEC "%{!o*:-o %b} -m armelf_haiku %{!r:-shared} %{nostart:-e 0} %{shared:-e 0} %{!shared: %{!nostart: -no-undefined}}\
  %{mbig-endian:-EB} %{mlittle-endian:-EL} -X"

The part with %{!o*:-o %b} in particular is really suspicious to me.
As I was able to decode it, it instructs gcc to invoke ld with “-o output_file_basename” if -o flag is NOT specified.
However, there’s the following comment in gcc.c near the line where we got the ICE:

      case 'b':
        /* Don't use %b in the linker command.  */
        gcc_assert (suffixed_basename_length);

Also this %{!o*:-o %b} is not present on the i386. (not sure about RISC-V though, as it has this suspicious clause in LINK_SPEC but maybe no one tried yet RISC-V bootstrap on gcc-11?)

Edit: the clause in question was removed from i386 in 2009 in commit #beaf9299f
If I remove it from gcc/config/arm/haiku.h, the bootstrap get going again, at least it won’t stop with ICE in the configure script. It will take a bit more time to see if it can finish successfully…

1 Like

The patch for -o was for the case where you do “gcc somefile.cpp”. In gcc2 this gives you an executable named “somefile”. In modern gcc this gives you “a.out” instead.

It is not really needed, and indeed our gcc8 (and I assume our gcc11) for x86 does not have this patch anymore. So you can remove it if it doesn’t work correctly.

1 Like

I haven’t updated this topic recently, but meanwhile there was some progress in the background… combatting some regressions, then re-doing the bootstrap build and the “unbootstrapping” with help from Kallisti5.

Now it’s possible to build ARM images from git master, with up to date packages.

The bootloader is still a mess: most of the memory is identity-mapped, the page tables are full of temporary stuff, so that’s a quite straightforward next step to clean it up…

7 Likes

On RISC-V I identity map boot loader memory. Unused parts are freed by kernel later.

https://git.haiku-os.org/haiku/tree/src/system/boot/platform/efi/arch/riscv64/arch_mmu.cpp#n391

2 Likes

Yes I’ve seen it, in fact I used it as a starting point for the ARM memory map :slight_smile:

It’s a bit different on 32-bit arch though, as we don’t have so much virtual address space. The kernel starts at 0x80000000 so basically we can use half of the address space.
e.g. on qemu the physical memory starts at 0x40000000 so even with >1G the memory ranges start to overlap if I use identity mapping.

2 Likes

One more problematic area is the EFI runtime services.
I guess they should be mapped in somehow but I really don’t know what are the requirements.

e.g. do we want to call EFI runtime from the kernel at all.

We want, for example to control boot menu, but it is currently not implemented (x86_64 too).

There is info on how to map runtime services in the UEFI specification 8.4 (p. 264):

If an operating system chooses to make EFI runtime service calls in a
virtual addressing mode instead of the flat physical mode, then the operating system must use the
services in this section to switch the EFI runtime services from flat physical addressing to virtual
addressing.

You need to call ConvertPointer on it, but not sure on the exact calls.

4 Likes

That’s already nice and comfortable :slight_smile:

In the previous attempts we ran into a problem (with the BeagleBone I think) because physical RAM started at 0x80000000. So there was no way we could use identity mapping and also reserve that space for the kernel.

The fun parts of early boot, especially on non-standardized ARM architectures where every chip has its RAM at a totally different place…

1 Like

Maybe identity mapping trampoline code address can be dynamically allocated and copied?

On RISC-V memory can be mapped to any mappable range for kernel/user, not only kernel/user range. So it is possible to have something mapped at low addresses in kernel address space.

3 Likes

Yes, that’s what I’m trying to achieve. The question is: how to find a suitable area that’s available in both virtual and physical address space.

Some trial and error…

  1. Try to allocate memory below 2G with EFI AllocateMaxAddress. This gives us a region that’s available in the virtual address space but the physical allocation might fail (e.g. if all the physical memory starts at a higher address)
  2. Try to allocate physical memory with EFI AllocateAddress, at the next free virtual address returned by get_next_virtual_address()
  3. Allocate some memory with EFI AllocateAnyAddress, typically this will be near the end of the physical memory as both EDK2 and u-boot allocates starting from high towards lower addresses. If it’s above approx. 0x88000000 then I think we’re still good to go…

Any other suggestion or any corner case that I might have missed?

**

the 32-bit architectures (x86, arm) seem to treat addresses below/above 2G differently. e.g. in reserve_boot_loader_ranges() / unreserve_boot_loader_ranges()

3 Likes

what’s the progress?
does arm img work in qemu, do you need to compile the code?

the ARM EFI bootloader is in a good shape

i’ve been looking at the kernel recently, there are a few things to do.
some of the next items that are close (you might see an update this week)

  • address space switch on thread context switching
  • entering userspace
  • syscalls
21 Likes

runtime_loader running in userspace
it’s able to load the launcher_daemon binary and the shared libraries
but then we get a NULL pointer in libbe initialize_after() function

arch_thread_enter_userspace: entry 0x9a2258, args 0x72b6a100 0x61703000, ustack_top 0x72b6a000
rld: load /boot/system/servers/launch_daemon
malloc(1520) -> 0x00431008
"/boot/system/servers/launch_daemon" at 0x00e07000, 0x28000 bytes (read-only)
malloc(32) -> 0x00431600
"/boot/system/servers/launch_daemon" at 0x00e3f000, 0x2000 bytes (rw)
cleared 0xe40ac4 and the following 0x53c bytes
malloc(48) -> 0x00431628
malloc(24) -> 0x00431660
runtime_loader: search_container_in_path_list() libbe.so in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libbe.so
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libbe.so
runtime_loader: try_open_container(): /boot/system/lib/libbe.so
runtime_loader: open_executable(libbe.so): found at /boot/system/lib/libbe.so
malloc(1520) -> 0x00431680
"/boot/system/lib/libbe.so" at 0x0123f000, 0x251000 bytes (read-only)
"/boot/system/lib/libbe.so" at 0x014a0000, 0x1a000 bytes (rw)
cleared 0x14b95b8 and the following 0xa48 bytes
malloc(88) -> 0x00431c78
runtime_loader: search_container_in_path_list() libnetwork.so in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libnetwork.so
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libnetwork.so
runtime_loader: try_open_container(): /boot/system/lib/libnetwork.so
runtime_loader: open_executable(libnetwork.so): found at /boot/system/lib/libnetwork.so
malloc(1552) -> 0x00431cd8
"/boot/system/lib/libnetwork.so" at 0x00c1c000, 0x35000 bytes (read-only)
"/boot/system/lib/libnetwork.so" at 0x00c61000, 0x2000 bytes (rw)
cleared 0xc621b4 and the following 0xe4c bytes
malloc(72) -> 0x004322f0
runtime_loader: search_container_in_path_list() libbnetapi.so in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libbnetapi.so
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libbnetapi.so
runtime_loader: try_open_container(): /boot/system/lib/libbnetapi.so
runtime_loader: open_executable(libbnetapi.so): found at /boot/system/lib/libbnetapi.so
malloc(1520) -> 0x00432340
"/boot/system/lib/libbnetapi.so" at 0x00d94000, 0x4c000 bytes (read-only)
"/boot/system/lib/libbnetapi.so" at 0x00def000, 0x3000 bytes (rw)
cleared 0xdf15c4 and the following 0xa3c bytes
malloc(72) -> 0x00432938
runtime_loader: search_container_in_path_list() libstdc++.so.6 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libstdc++.so.6
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libstdc++.so.6
runtime_loader: try_open_container(): /boot/system/lib/libstdc++.so.6
runtime_loader: open_executable(libstdc++.so.6): found at /boot/system/lib/libstdc++.so.6.0.29
malloc(1552) -> 0x00432988
"/boot/system/lib/libstdc++.so.6.0.29" at 0x00f18000, 0x1b9000 bytes (read-only)
"/boot/system/lib/libstdc++.so.6.0.29" at 0x010e1000, 0x7000 bytes (rw)
cleared 0x10e7d24 and the following 0x2dc bytes
malloc(48) -> 0x00432fa0
runtime_loader: search_container_in_path_list() libroot.so in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libroot.so
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libroot.so
runtime_loader: try_open_container(): /boot/system/lib/libroot.so
runtime_loader: open_executable(libroot.so): found at /boot/system/lib/libroot.so
malloc(1552) -> 0x00432fd8
"/boot/system/lib/libroot.so" at 0x025a0000, 0xde000 bytes (read-only)
"/boot/system/lib/libroot.so" at 0x0268d000, 0xa000 bytes (rw)
cleared 0x26962e4 and the following 0xd1c bytes
malloc(144) -> 0x004335f0
runtime_loader: search_container_in_path_list() libgcc_s.so.1 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libgcc_s.so.1
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libgcc_s.so.1
runtime_loader: try_open_container(): /boot/system/lib/libgcc_s.so.1
runtime_loader: open_executable(libgcc_s.so.1): found at /boot/system/lib/libgcc_s.so.1
malloc(1520) -> 0x00433688
"/boot/system/lib/libgcc_s.so.1" at 0x011c4000, 0x11000 bytes (read-only)
"/boot/system/lib/libgcc_s.so.1" at 0x011e4000, 0x1000 bytes (rw)
cleared 0x11e4728 and the following 0x8d8 bytes
malloc(168) -> 0x00433c80
malloc(40) -> 0x00433d30
runtime_loader: search_container_in_path_list() libicudata.so.66 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libicudata.so.66
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libicudata.so.66
runtime_loader: try_open_container(): /boot/system/lib/libicudata.so.66
runtime_loader: open_executable(libicudata.so.66): found at /boot/system/lib/libicudata.so.66.1
malloc(1520) -> 0x00433d60
"/boot/system/lib/libicudata.so.66.1" at 0x01e6a000, 0x1000 bytes (read-only)
"/boot/system/lib/libicudata.so.66.1" at 0x01e7a000, 0x1000 bytes (rw)
cleared 0x1e7a68c and the following 0x974 bytes
runtime_loader: search_container_in_path_list() libicui18n.so.66 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libicui18n.so.66
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libicui18n.so.66
runtime_loader: try_open_container(): /boot/system/lib/libicui18n.so.66
runtime_loader: open_executable(libicui18n.so.66): found at /boot/system/lib/libicui18n.so.66.1
malloc(1520) -> 0x00434358
"/boot/system/lib/libicui18n.so.66.1" at 0x01b35000, 0x242000 bytes (read-only)
"/boot/system/lib/libicui18n.so.66.1" at 0x01d86000, 0xd000 bytes (rw)
cleared 0x1d92374 and the following 0xc8c bytes
runtime_loader: search_container_in_path_list() libicuio.so.66 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libicuio.so.66
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libicuio.so.66
runtime_loader: try_open_container(): /boot/system/lib/libicuio.so.66
runtime_loader: open_executable(libicuio.so.66): found at /boot/system/lib/libicuio.so.66.1
malloc(1520) -> 0x00434950
"/boot/system/lib/libicuio.so.66.1" at 0x01ddd000, 0xa000 bytes (read-only)
"/boot/system/lib/libicuio.so.66.1" at 0x01df7000, 0x1000 bytes (rw)
cleared 0x1df79f4 and the following 0x60c bytes
runtime_loader: search_container_in_path_list() libicuuc.so.66 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libicuuc.so.66
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libicuuc.so.66
runtime_loader: try_open_container(): /boot/system/lib/libicuuc.so.66
runtime_loader: open_executable(libicuuc.so.66): found at /boot/system/lib/libicuuc.so.66.1
malloc(1520) -> 0x00434f48
"/boot/system/lib/libicuuc.so.66.1" at 0x0154d000, 0x178000 bytes (read-only)
"/boot/system/lib/libicuuc.so.66.1" at 0x016d4000, 0xc000 bytes (rw)
cleared 0x16df524 and the following 0xadc bytes
malloc(40) -> 0x00435540
runtime_loader: search_container_in_path_list() libz.so.1 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libz.so.1
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libz.so.1
runtime_loader: try_open_container(): /boot/system/lib/libz.so.1
runtime_loader: open_executable(libz.so.1): found at /boot/system/lib/libz.so.1.2.11
malloc(1520) -> 0x00435570
"/boot/system/lib/libz.so.1.2.11" at 0x014e3000, 0x16000 bytes (read-only)
"/boot/system/lib/libz.so.1.2.11" at 0x01508000, 0x1000 bytes (rw)
cleared 0x1508df8 and the following 0x208 bytes
malloc(184) -> 0x00435b68
runtime_loader: search_container_in_path_list() libzstd.so.1 in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libzstd.so.1
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libzstd.so.1
runtime_loader: try_open_container(): /boot/system/lib/libzstd.so.1
runtime_loader: open_executable(libzstd.so.1): found at /boot/system/lib/libzstd.so.1.5.0
malloc(1520) -> 0x00435c28
"/boot/system/lib/libzstd.so.1.5.0" at 0x01a40000, 0xcb000 bytes (read-only)
"/boot/system/lib/libzstd.so.1.5.0" at 0x01b1a000, 0x1000 bytes (rw)
cleared 0x1b1ae94 and the following 0x16c bytes
malloc(40) -> 0x00436220
malloc(16) -> 0x00436250
runtime_loader: search_container_in_path_list() libbsd.so in %A/lib:/boot/system/non-packaged/lib:/boot/system/lib
runtime_loader: try_open_container(): /boot/system/servers/lib/libbsd.so
runtime_loader: try_open_container(): /boot/system/non-packaged/lib/libbsd.so
runtime_loader: try_open_container(): /boot/system/lib/libbsd.so
runtime_loader: open_executable(libbsd.so): found at /boot/system/lib/libbsd.so
malloc(1520) -> 0x00436268
"/boot/system/lib/libbsd.so" at 0x01a10000, 0x6000 bytes (read-only)
"/boot/system/lib/libbsd.so" at 0x01a25000, 0x1000 bytes (rw)
cleared 0x1a257d0 and the following 0x830 bytes
malloc(72) -> 0x00436860
malloc(40) -> 0x004368b0
malloc(16) -> 0x004368e0
malloc(16) -> 0x004368f8
malloc(16) -> 0x00436910
malloc(16) -> 0x00436928
malloc(24) -> 0x00436940
malloc(16) -> 0x00436960
malloc(16) -> 0x00436978
malloc(16) -> 0x00436990
malloc(16) -> 0x004369a8
malloc(56) -> 0x004369c0
malloc(864) -> 0x00436a00
malloc(864) -> 0x00436d68
malloc(32) -> 0x004370d0
free(0x004370d0)
free(0x00436a00)
free(0x00436d68)
malloc(11096) -> 0x00436a00
malloc(11096) -> 0x00439560
malloc(352) -> 0x0043c0c0
free(0x0043c0c0)
free(0x00436a00)
free(0x00439560)
malloc(27152) -> 0x00436a00
malloc(27152) -> 0x008a5008
malloc(856) -> 0x008aba20
free(0x008aba20)
free(0x00436a00)
free(0x008a5008)
malloc(64) -> 0x008a5008
malloc(64) -> 0x008a5050
malloc(16) -> 0x008a5098
free(0x008a5098)
free(0x008a5008)
free(0x008a5050)
malloc(15000) -> 0x008a5008
malloc(15000) -> 0x008a8aa8
malloc(472) -> 0x008ac548
free(0x008ac548)
free(0x008a5008)
free(0x008a8aa8)
malloc(36808) -> 0x00436a00
malloc(36808) -> 0x00944008
malloc(1152) -> 0x0043f9d0
free(0x0043f9d0)
free(0x00436a00)
free(0x00944008)
malloc(688) -> 0x008a5008
malloc(688) -> 0x008a52c0
malloc(24) -> 0x008a5578
free(0x008a5578)
free(0x008a5008)
free(0x008a52c0)
malloc(480) -> 0x008a5008
malloc(480) -> 0x008a51f0
malloc(16) -> 0x008a53d8
free(0x008a53d8)
free(0x008a5008)
free(0x008a51f0)
malloc(1832) -> 0x008a5008
malloc(1832) -> 0x008a5738
malloc(64) -> 0x008a5e68
free(0x008a5e68)
free(0x008a5008)
free(0x008a5738)
malloc(48424) -> 0x00944008
malloc(48424) -> 0x0097d008
malloc(1520) -> 0x0094fd38
free(0x0094fd38)
free(0x00944008)
free(0x0097d008)
malloc(600) -> 0x008a5008
malloc(600) -> 0x008a5268
malloc(24) -> 0x008a54c8
free(0x008a54c8)
free(0x008a5008)
free(0x008a5268)
malloc(2552) -> 0x008a5008
malloc(2552) -> 0x008a5a08
malloc(80) -> 0x008a6408
free(0x008a6408)
free(0x008a5008)
free(0x008a5a08)
malloc(7424) -> 0x008a5008
malloc(7424) -> 0x008a6d10
malloc(232) -> 0x008a8a18
free(0x008a8a18)
free(0x008a5008)
free(0x008a6d10)
malloc(4400) -> 0x008a5008
malloc(4400) -> 0x008a6140
malloc(144) -> 0x008a7278
free(0x008a7278)
free(0x008a5008)
free(0x008a6140)
free(0x004369c0)
inject_runtime_loader_api 0x0269632c <-- 0x009be77c
malloc(56) -> 0x008a5008
788: init dependencies
788:  init: libgcc_s.so.1
init_routine 0x011c64cc
init_array 0x011e4528
init_array[0]: 0x011c67bc
init_array done
788:  init: libroot.so
init_before 0x025c4e4c image_id=0x00000813 gRuntimeLoader at 0x009be77c
init_routine 0x025c1658
init_array 0x0268d218
init_array[0]: 0x025c4e10
init_array[1]: 0x025c4b10
init_array[2]: 0x025c4b58
init_array[3]: 0x025c4b90
init_array[4]: 0x025c4be0
init_array[5]: 0x025c4c2c
init_array[6]: 0x025c4c78
init_array[7]: 0x025c4d24
init_array done
788:  init: libstdc++.so.6
init_routine 0x00fa1454
init_array 0x010e1000
init_array[0]: 0x00fa6b84
init_array[1]: 0x00fa616c
init_array[2]: 0x00fa620c
init_array[3]: 0x00fa6270
init_array[4]: 0x00fa6410
init_array[5]: 0x00fa6594
init_array[6]: 0x00fa65e8
init_array[7]: 0x00fa66d8
init_array[8]: 0x00fa67c8
init_array[9]: 0x00fa6928
init_array[10]: 0x00fa6a88
init_array done
788:  init: libicudata.so.66
init_routine 0x01e6a304
init_array 0x01e7a584
init_array[0]: 0x01e6a3d8
init_array done
788:  init: libicuuc.so.66
init_routine 0x01596688
init_array 0x016d4350
init_array[0]: 0x0159b600
init_array done
788:  init: libicui18n.so.66
init_routine 0x01bf4194
init_array 0x01d8637c
init_array[0]: 0x01bff890
init_array done
788:  init: libicuio.so.66
init_routine 0x01ddf1c4
init_array 0x01df7000
init_array[0]: 0x01ddf878
init_array[1]: 0x01ddf7a8
init_array done
788:  init: libz.so.1
init_routine 0x014e4604
init_array 0x01508b3c
init_array[0]: 0x014e48e0
init_array done
788:  init: libzstd.so.1
init_routine 0x01a45e2c
init_array 0x01b1a8a4
init_array[0]: 0x01a46ac8
init_array done
788:  init: libbe.so
init_before 0x0132ae28 image_id=0x0000080f gRuntimeLoader at 0x009be77c
init_routine 0x01314420
init_array 0x014a0000
init_array[0]: 0x01324010
init_array[1]: 0x01323a7c
init_array[2]: 0x01323b10
init_array[3]: 0x01323b64
init_array[4]: 0x01323bac
init_array[5]: 0x01323bf4
init_array[6]: 0x01323c3c
init_array[7]: 0x01323cc8
init_array[8]: 0x01323d10
init_array[9]: 0x01323d3c
init_array[10]: 0x01323dc8
init_array[11]: 0x01323df0
init_array[12]: 0x01323e38
init_array[13]: 0x01323e80
init_array[14]: 0x01323ec8
init_array[15]: 0x01323f10
init_array[16]: 0x01323f58
init_array done
init_after
vm_page_fault: vm_soft_fault returned error 'Bad address' on fault at 0x0, ip 0x13f9b14, write 0, user 1, exec 0, thread 0x314

next: some code cleanup. then some more troubleshooting.

25 Likes

I think logging text/data base address of each loaded module will help investigating. It will allow to find relative address of crash and lookup it in disassembler. The best would be implement stack trace (globally adding -fno-omit-frame-pointer option may be needed).

2 Likes

This is awesome.