rndtrash/nt4.0onmac

Nice attempt.

Wack0 opened this issue · 4 comments

You need to consider endianness here. Jumping to ppc little endian code with ppc and memory controller in big endian mode won't work :)

Although it is possible. I'm working on my port now, using same ideas/high level arc firmware implementation/... as my NT4 PPC port to Wii (which is on hold due to weird issues, I don't have a USB Gecko and getting an iBook G3 from Yahoo Auctions was cheaper!)

It requires endianness swapping all code on load (and hooking all PE loading code for that); and patching all 16/32-bit load/store instructions to invalid instructions, and then emulating those by program exception handler.

That's the basics, additional kernel patches are required for getting past kernel init, and dealing with page tables, and low level exception handler stuff, etc.

Additionally, OF maps 1:1 physical->virtual address. NT boot requires a mapping where (the first 256MB of) physmem is at virtual address 0x8000_0000 (this is used in kernel-mode when kernel is running, osloader loads kernel and boot drivers/etc there), which is like the GameCube/Wii but not like OF. On UniNorth systems the mac-io device is mapped at 0x8000_0000 to 0x8008_0000, with usb controllers each using a page after that.

The trick here is that the ARC system table must be at 0x8000_4000, and 0x4000 bytes of MMIO there is afaict entirely unused by Apple's OF (it might be a mirror, I'm not sure), so one can make a loader that unmaps that area and remaps it to physical address 0x4000, maps physmem starting from 0x8009_0000, loads second stage ELF there and jumps to it (the hooks would require being based in the same mapping as NT uses)

Here's setupldr running on real iBook G3, erroring out due to osloader checking PVR against a hardcoded list, with extra patches for that required (basically assuming everything not in that list is a 750 which is the latest processor supported by NT4 PPC). Works under QEMU emulation too, and boot currently gets through early kernel init and calls the HAL, which is yet to be written.

Theoretically little endian mode should work on grackle systems (the reason why it's notorious for bricking is because the old grackle endianness switching code remained in place on uninorth systems, hence a crash when OF comes up after the bong and attempts to switch endianness). Apple even mapped the mac-io controller there to 0x8080_0000 so veneer could run, veneer maps first 8MB physmem unconditionally for the NT boot/kernelmode mapping.

Hey, nice to meet you! I saw your posts, and I want to say you've done great work! 🥂

I have little to no experience working with this stuff, so I was copying the code from yaboot and OpenBSD's bootloader until it worked. I thought that it would be possible to change the endianess to a little before jumping to the code, and then changing the endianess back and forth when calling OF, which I guess is slow, but that's not a problem if Windows runs at all :^)

Your comment made it clear why it never worked on the real hardware. Where can I read more about the internal workings of a G3? All I had was the OpenFirmware specification.

Sadly, I can't test the project on real hardware anymore, and I have a course work to be done, so the project is on a hiatus. I guess after compiling GCC+Binutils for 5 days straight and 7 attempts at installing an alternative OS (they all showed a black screen after a reboot, both Linuxes and *BSD's), the graphics chip fell off - my $25 iBook chimes, but the screen is black. DingusPPC looks promising, though. I'm going to try again as soon as they'd support the New World Macs.

By the way, do not read the code unless you want to contribute to ReactOS in the future🥴 (I am no longer welcome here)

I thought that it would be possible to change the endianess to a little before jumping to the code, and then changing the endianess back and forth when calling OF

That was my first thought when I started the Wii port. It turns out that MSR_LE only changes the addresses being accessed on the bus, it still needs support in the memory controller for doing the remainder (grackle has this, but uni-north as far as I can tell does not). This changed at some more modern powerpc implementation, but that doesn't really matter here.

Where can I read more about the internal workings of a G3?

The documentation is in lots of different places, including PowerPC 750/750CX/750CXe/750FX user manual, there's some other documentation which describes things like BATs and page tables, although practically I've just used the mario kart wii forum posts on those topics for the most part.

That was my first thought when I started the Wii port. It turns out that MSR_LE only changes the addresses being accessed on the bus, it still needs support in the memory controller for doing the remainder (grackle has this, but uni-north as far as I can tell does not). This changed at some more modern powerpc implementation, but that doesn't really matter here.

Damn, that sucks. Do you think that at this point it's more rational to just build the leaked NT code with big-endian support?

The documentation is in lots of different places, including PowerPC 750/750CX/750CXe/750FX user manual, there's some other documentation which describes things like BATs and page tables, although practically I've just used the mario kart wii forum posts on those topics for the most part.

Mario Kart Wii? Wow. Gonna take a look, thanks!

Do you think that at this point it's more rational to just build the leaked NT code with big-endian support?

Good luck with that. I had to hack a toolchain together for building PPC PEs in the first place, and even then there's no SEH support (because I don't need it).