Compiling haikuports.cross for PPC

If I recall, there is no efi bootloader for PPC, only open firmware. This means that one would need to go with the option 2. But perhaps building a disk image would not be needed, I think extracting boot loader from built package and creating a simple boot cd image could be enough perhaps.

1 Like

Yes, there currently isn’t, but that could be added. The only reason it doesn’t exist is the lack of platform to test it with.

And also it’s not only open firmware: @mmu_man has been working on support for the Sam440ex (which uses U-Boot, but no EFI because it’s an old version), and also the BeBox, which is something else entirely. I think both of these are less advanced than the OpenFirmware one, but then there is a bug report on Haiku bugtracker saying that the OpenFirmware loader may not actually work with OpenBIOS: #6071 (ppc: OpenFirmware boot loader hangs on QEMU) – Haiku so I’m not sure if that is a good way forward either.

As I said, time for the people who know a bit about PowerPC to join in :slight_smile:

2 Likes

Yes, there seems to be code for u-boot loader in the tree, but it is not build with the bootstrap image, and it seems that build system only builds Open Firmware loader for PPC, and I have no idea how to build the u-boot loader.

The OpenFirmware loader might be broken on OpenBios, and perhaps on other OF implementations too, last time I played with it it reported some error regarding MMU if I recall.

Not implying that you should continue with that, I’ll just write my observations here, so if anyone with proper knowledge and inspiration to continue fixing PPC build comes along, they do not need to dig everything themselves. I wish I knew enough to fix it, It would be a nice project, although I think the ship for PPC has sailed a long ago, I still have a soft spot for the platform and some hardware I’d love to run Haiku on.

Using ARC firmware instead of Openfirmware may have better results.

“What developer Rairii – who calls himself Wack0 on Github – has done is ported a version of the PowerPC ARC firmware, plus a loader to get it into RAM, and some basic drivers to bring up keyboard, mouse, IDE and a framebuffer to certain models of Apple gear: the tray-loading iMac G3, PowerMac G3 “Blue and White”, PowerBook G3 “Lombard”, and PowerMac G4 “Yikes”. This is a remarkable achievement: while he’s taken code from several other projects, including OpenBIOS and Coreboot, this is still a hugely impressive effort.”

I posted links to build ARC firmware:

I don’t see how switching to an even more obscure firmware that Haiku has no support for whatsoever could possibly help.

We have an openfirmware bootloader that has a chance of working (with maybe a few patches on openbios), and we have an EFI loader that has chances of working in U-boot. Why would we go through the trouble of:

  • Compiling another firmware that isn’t part of the things supported by QEMU
  • Writing a completely new backend for Haiku bootloader, making sure we generate an executable in the proper format, that we can print text to the screen, read the keyboard, access disks, enable the MMU, switch to graphic mode and set up the bootscreen

This is a few weeks of work, for a firmware that doesn’t exist on any of the target machines by default? Why would we want to try that, when there are simpler and better documented solutions for which we have already done 99% of the work?

4 Likes

For fun, try something new and discover different solutions!

ARC firmware uses C language and closer to UEFI, Openfirmware uses Forth language.

“For the RISC machines of the 1990’s, there was an effort to rally around a common firmware
standard. An industry group referred to as Advanced RISC Computing (ARC) [6] aimed to unify
the boot environment for MIPS CPU and DEC Alpha. ARC shared some features with UEFI,
including the support of a FAT file system in the firmware, firmware boot variables, and a C-
callable interface. But ARC lacked, GPT, the extensibility of UEFI, and clear legal specification
governance or an evolution path like the UEFI Forum and UEFI specification. As a design,
another issue with ARC was that it specified platform design definitions. This design mandated
that various components must exist in a platform, thereby limiting diversity of platform
designs. Also, ARC was never ported to a volume architecture such as IA-32® or x64.
Another effort that is similar in its role to the PC/AT BIOS-based platform occurred with Open
Firmware (OF) [4] and the Common Hardware Reference Platform (CHRP). CHRP was a set of
common platform designs and hardware specifications meant to allow for interoperable designs
among PowerPC (PowerPC) platform builders. Open Firmware, also known as IEEE-1275 [4],
has issues in that it is an interpreted, stack-based byte-code. Very few programmers are facile
in Forth programming, and it is renowned as being “write-once/understand-never”, and having
poor performance, and non-standard tools. Also, Open Firmware has a device tree essentially
duplicating ACPI static tables. As such, the lack of Forth programmers, prevalence of ACPI,
and the fact that UEFI uses standard tools and works alongside ACPI—versus instead-of—
helped spell Open Firmware’s lack of growth. In fact, it is used on SPARC and PowerPC, but it
is unsuitable for high-volume machines and thus prevent it from making the leap from niche
server & workstation markets.”

NetBSD has good documentation on ARC firmware:

Hello,
I’m pretty impressed how fast you people fixed up the cross-compile environment!
Sorry for not contributing that much currently, I have to learn for some exams.

Yesterday I could not build the bootstrap, but that’s apparently because gnome’s gitlab instance had some trouble, but it seems to work now.

I’ve tried booting the openfirmware bootloader, first on Qemu by creating a hfs image with both boot_loader_openfirmware and haiku_loader.openfirmware on it.
In both cases openboot refused to boot them. However on my Powerbook it did load boot_loader_openfirmware and went to a black screen with a jittering text cursor. Once my exams are over I’ll try getting openfirmware to boot something.

kind regards,
zeldakatze

4 Likes

Hello again,

I’ve gotten boot_loader_openfirmware to load on qemu by putting it into
a disk image. I’ve created a script to quickly do this (GitHub - TheZeldakatze/createHFSfile: creates a bootable 50MB hfs image). (It is mostly copied from GitHub - thamugadi/powerpc-ofw-boot: Bootable stuff for PowerPC-based macs ).

The openfirmware loader does load, however the console is broken and doesn’t output anything. Copying the puts function from powerpc-ofw-boot, it works under qemu.

Patch
diff --git a/src/system/boot/platform/openfirmware/console.cpp b/src/system/boot/platform/openfirmware/console.cpp
index 8b743c3461..87f4a25354 100644
--- a/src/system/boot/platform/openfirmware/console.cpp
+++ b/src/system/boot/platform/openfirmware/console.cpp
@@ -95,6 +95,20 @@ Console::ReadAt(void */*cookie*/, off_t /*pos*/, void *_buffer,
        return bytesTotal;
 }
 
+void HackyPuts(char* str, int len)
+{
+       char cmd[len+8]; 
+       cmd[0] = '.'; cmd[1] = '"';
+       cmd[2] = ' ';
+       for (int i = 3; i < len+3; i++)
+       {
+               cmd[i] = str[i-3];
+       }
+       cmd[len+3] = '"'; cmd[len+4] = ' ';
+       cmd[len+5] = 'c'; cmd[len+6] = 'r';
+       cmd[len+7] = 0;
+       of_interpret(cmd, 0, 0, 0, 0);
+}
 
 ssize_t
 Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
@@ -123,7 +137,9 @@ Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
                }
 
                if (length > 0) {
-                       fWriteHandle.WriteAt(NULL, -1, string, length);
+                       //fWriteHandle.WriteAt(NULL, -1, string, length);
+                       
+                       HackyPuts((char*) string, length);
                        string += length;
                        bufferSize -= length;
                }
@@ -131,7 +147,9 @@ Console::WriteAt(void */*cookie*/, off_t /*pos*/, const void *buffer,
                if (newLine) {
                        // this code replaces a single '\n' with '\r\n', so it
                        // bumps the string/bufferSize only a single character
-                       fWriteHandle.WriteAt(NULL, -1, "\r\n", 2);
+                       //fWriteHandle.WriteAt(NULL, -1, "\r\n", 2);
+                       
+                       HackyPuts((char*) string, length);
                        string++;
                        bufferSize--;
                }

It then errors out because there is no mapping for the exception handlers.

However the bootloader loads and outputs stuff on my real powerbook. You can briefly see the bootloader log displaying before it enters the boot menu. You can see the labels of the buttons, however the boot loader crashes shortly after. I still find it interresting that the openfirmware loader works better on real hardware than on qemu.

I’ll have another look at the console and exception handler mapping shortly.

kind regards,
zeldakatze

1 Like

This should already be done in Haiku build scripts, but you have to use the right image type (I think it is @bootstrap-cdrom instead of @bootstrap-raw). I have not tried that with the bootstrap image, however.

The entry point for that would be CDBootImage « images « jam « build - haiku - Haiku's main repository

It is more a problem of different firmwares, as qemu does not run a complete openfirmware implementation. If there is a way to run an actual Apple ROM inside QEMU, that would possibly work better, but I don’t know if that’s actually possible at all.

Otherwise, you have to figure out if similar services are available under different names, as I had to do when working on the SPARC port (also uses some variant of Open Firmware, but a few things were done differently).

I assume not much has changed since 2009:

Hello,
The console should now work, stdin and stdout were mixed up.

However the bootloader still only properly loads on real hardware, on
qemu it hangs on line 891 in mmu.cpp:
ppc_set_segment_register((void *)(i * 0x10000000), sSegments[i]);
which seems to be the external function of /cpus that is mentioned in the other thread.

I’ll have a look at how some some other bootloaders work, openbsd seems to also panic on boot

I built a bootstrap build on a clean environment (a fresh vm of debian 12)
and I’ve noticed that at least textlive seems to link against the host ncurses library.
Also there seem to be some problems with Haikuporter on a crossbuild if for example cmake is not installed. I’ll create a ticket about that soon.

kind regards,
zeldakatze

4 Likes

Hello,

Thanks a lot for pushing this through ! I’m really excited to see some progress on the port (and my apologies for those typos I left in the gcc source :frowning: )
I can’t access anything remotely looking like a dev environment these days, but I’d be very interested to get your insight on how virtual memory is set on other bootloaders. If I remember correctly most of them don’t bother with segment and only use BAT (at least at this stage)
I kinda remember disabling the set_segment_register and getting the bootloader to proceed on qemu (disabling data / instr address translation too ? it’s a bit fuzzy) which is a shame 'cause it’s a so easier to see progress on that early stage on virtual hardware (at least it is for me)…Anyway hope your exams went well !
Cheers,

1 Like

If I remember correctly from the ARM port, the bootloader configures things so that all relevant areas (IO space, kernel code and data area) are identity mapped (virtual address == logical address) then enables the MMU. Then the kernel takes over, and can map any extra things it needs.

However, depending on the physical memory layout, this may not always work. In any case, the idea is that the kernel starts with the MMU already enabled and the basic things already mapped where they should be, then the kernel takes over from there and adds more mappings as needed.

Will it work correctly? Kernel usually use high virtual addresses, but boot loader is usually loaded at low addresses. So non-identity mapping is needed.

On RISC-V I setup non-trivial virtual memory mapping that prepares ready to use kernel environment: haiku/src/system/boot/platform/efi/arch/riscv64/arch_mmu.cpp at ae8d7152a0d01fd69115d133e6a32a0684eab8f2 · haiku/haiku · GitHub.

1 Like

Hello,

I’m still prep’ing a proper patch for the issue, but if you add 1024 to each virtual_segment_id you should avoid locking in set_sr.

so : src/system/boot/platform/openfirmware/arch/ppc/mmu.cpp around line 830

        for (int32 i = 0; i < 16; i++)
                sSegments[i].virtual_segment_id = i;

should become

        for (int32 i = 0; i < 16; i++)
                sSegments[i].virtual_segment_id = i * 0x400;

(@ilzu tested the modification, and it’s also working on physical hardware)

Next stop will be correct detection of boot drive.
Cheers,

4 Likes

Qemu still hangs on set_sr after applying that, I have not tried that on real hardware

EDIT: I’ve tried it on a real mac, there it errors out with an invalid instruction access, maybe I’ve made a mistake somewhere

At least on real hardware, the boot loader actually detects the drives. It seems to scan the hard disk as well but there it can’t find a partition, even when the partition is marked as Be_BFS, so I’m guessing that it has trouble reading the apple partition map. However it does detect partitions on the cd drive and tries to boot from them (loading kernel kernel_ppc), however that fails with

Couldn't find both text and data segment
loading kernel failed: 80000010

Haiku itself doen’t yet support apple partition maps nor HFS(+), does it?

As far as I know, you could use openfirmware to access many basic devices (framebuffer, keyboard, mouse, even ethernet) if I understand correctly which would be slow though, as everything is interpreted

It does support Apple partition tables. On x86 this is availabne in the haiku_extras packages, but on ppc it can be added to the main package. However, I don’t think this affects the bootloader, it’s only for kernel support.

Does the bootloader need to parse that partition table by itself, or can it rely on openfirmware to do it?

This is because bootloaders elf loader needs the kernel to have both data and text sections mapped to their own segments (See elf.cpp « loader « boot « system « src - haiku - Haiku's main repository). On x86(_64) and arm64 it seems that the compiler/linker does it by default, on sparc this is done in linker script. @Yn0ga has a linker script with this added on his ppc-work branch on github.

@Yn0ga and me have played a bit with the PPC last week and gotten it a bit further, I think yn0ga got into the kernel _start already.

6 Likes

Hello,

Here’s the modified kernel linker script that should gets you further :

Cheers,

I hope Haiku

you get further with PPC Haiku

to - once time - develop Haiku

on PPC architecture in itself - without cross development ;))

Then we can reuse Power based Apple machines and their clones with Haiku …
Of course new HW as well, but for some of us those old ones more enchanting.

1 Like