My Haiku ARM (UEFI) port progress

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.

crash comes from BCollator::SetStrength because fICUCollator is NULL.
I did the fallback to icu-66 already but maybe even that is broken. I guess i’ll have to go back to icu-57.

Note that icu67 is broken for me.

Is it possible to reproduce result with running userland?

I think you did the bootstrap build yourself? Have you checked if your port trees are outdated? ICU in bootstrap might also be lagging behind with fixes.

Sounds like we should add a NULL check there and return an error code instead of crashing?

i tried both icu67 and icu66, neither seems to work unfortunately

that might be a bit tricky as fICUCollator is initialized in BCollator’s constructor with a call to Collator::createInstance so we can’t return an error code there. throwing an exception is probably also not a good idea as it’s called from libbe initialize_after() function without any exception handler block.

The way it’s usually done in the BeAPI:

  • Add a status_t BCollator::InitCheck() that must be called after constructing an object. This returns a status_t stored in the class members (usually named fInitStatus), and that can be initialized from the UErrorCode error local variable in the constructor (there is a function somewhere to convert ICU errors to status_t
  • In BCollator::SetStrength, add:
if (fInitStatus != B_OK)
    return fInitStatus;

It is then the responsibility of API users to check InitCheck() and handle the error appropriately. Other functions in BCollator can also check the fInitStatus before doing anything, to avoid crashes.

1 Like

I took the lazier approach now: just reverted to icu-57.2.
Now libbe is able to initialize and launch_daemon starts. Then it either gets blocked or crashes.

11 Likes

yes and yes: I’m using my own bootstrap build, and now that I checked, it turned out that my tree is in fact outdated.
i’ll try a rebuild with a more up to date checkout.

1 Like

Hi First post here!

Launch Daemon ends up in a data abort loop and from what I can read in this thread , very expected.

Good progress!

Is there a way to get the exception handler (for arm exceptions) to stop and where is the handler?

Is it possible to find symbols using relative offset from PC (or LR)? Might be a stupid question , sorry if so.

R00=72b6a120 R01=80a33d58 R02=00000400 R03=80aaa5a4
R04=0000002f R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=808bd900 R11=00000000
R12=801bc4e8 SP=820c8ad0 LR=80137ae4 PC=80157d94 CPSR=60000053
FAR: 72b6a120, isWrite: 1, thread: launch_daemon

3 Likes