Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Old World loading capabilities #31

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

MCJack123
Copy link

This PR adds an extra build step to the arcloader/stage1 makefile which produces an XCOFF file that can be loaded from Old World Open Firmware versions. It uses a small program from the Linux sources to patch the XCOFF that GCC links, which makes the executable bootable.

This is mostly untested, as I don't have a G3 beige system (and DingusPPC is being weird), but the same process works on my OF 1.0.5 PM7600. I also don't know the blessing procedures quite yet, and if OF 1/2 is even able to detect alternate boot devices without changing boot-device in NVRAM.

This is untested, as I don't have a G3 beige system, but the same process
works on my OF 1.0.5 PM7600.
@Wack0
Copy link
Owner

Wack0 commented Jul 29, 2024

About the blessing procedure, I believe from looking at OSX install images, it uses an APM partition with no data storing raw powerpc code, with base address + entrypoint in the partition table entry. OSX uses a mapped binary with mach-o headers present (IDA loads it fine as a mach-o even) but executable headers aren't required.

I was planning on modifying arcfw for clearing bss, and having a load image for oldworld that was basically loaded arcfw+custom loader in bss, placing it in the cd image then patching it after build (as far as I can tell no tool can set up such an APM partition in a hybrid ISO containing only code yet).

For dualboot, could probably add some boot menu in loader (and enable it only if mac partitions were created). Given the 16KB loader limit will be not present at all for oldworld...

@MCJack123
Copy link
Author

I just tried booting my 10.0 CD in my 7600 (holding C), and it appears that whatever it boots is a small script that sets the following NVRAM parameters:

  • boot-device => scsi-int/@3,0:0 (@3,0:8 under System Disk)
  • boot-command => 1 bootr (0 bootr under System Disk)
  • use-nvramrc? => true
  • nvramrc => some code which defines bootr (which appears to set bootargs before booting), redefines init-program to load other stuff (most of it is in machine code), plus other stuff?
  • load-base => 600000

and then resets the system, letting OF then hand it off to the OS X loader on the CD. System Disk appears to do the same thing when booting to an OS X CD. I also happen to have a Server 1.2 CD which is supported on the 7600, but it boots and installs from a Mac OS 8.5 System Folder instead - but the boot device setting from 10.0 still tries to boot Mac OS X Server from CD (which doesn't appear to work, it runs the loader but fails to find a kernel I think).

From a bit of digging, I believe the HFS Standard wrapper over the HFS+ partition holds the C-key boot data. There are three hidden files located on this hidden sub-partition:

  • System, which is a standard Mac OS system suitcase file, with a few notable resources:
    • boot, which has the code that does the above reconfiguration (specifically entry 2), and I believe this is what the ROM looks for
    • OFpt, which contains NVRAM patches for each platform (also present in System Disk)
    • OFtb and OFtc, which have tables mapping each hardware ID to the necessary patch in OFpt
  • OSXBoot!, which is empty in both forks. Not sure what it's for - maybe it just indicates that this is an OS X disk (or it shadows the boot image)?
  • Finder, which is also empty and appears to be a placeholder to ensure the system definitely thinks this disk is bootable.

Also possibly relevant is the HFS boot block, which I'm leaving a link to docs for in case it's necessary.

As for Open Firmware loading, you're correct about it loading from the APM - I'm not sure exactly where it comes from, but I'm guessing that /packages/mac-files looks for the first partition with boot code set up, and loads the entire image into memory. This could be used with either the existing ELF or this PR's XCOFF file, provided the start + base addresses are correct in APM.

So after a lot of investigation, I believe this is the way to make a "truly bootable" CD for an Open Firmware payload:

  • Make a hybrid APM+ISO disc image.
  • Add in all of the required drivers under APM.
  • Add an HFS Standard partition under APM, with a proper boot block and startup file set up.
  • Add a system suitcase with similar contents to the OS X suitcase onto the HFS partition. The boot program will set up the boot-device parameter to point to the loader on the ISO filesystem.
  • Configure the ISO filesystem to start after the end of the APM area, or otherwise shadow the APM data.
  • Place the XCOFF image to boot in the ISO filesystem.

Alternatively, using an APM boot image:

  • Do the first four steps above.
  • Copy the XCOFF/ELF/whatever image to some place in the image.
  • Hack the APM to point to the correct sectors and load addresses for that image.

Now, I don't really think I want to put in the effort to make this work without copying Apple's files - it's a lot of hacking to be able to hold "C" instead of typing a command once. But this is some food for thought, and I might play around with the Apple files a bit on my own to see what's possible.

@Wack0
Copy link
Owner

Wack0 commented Jul 30, 2024

"without copying Apple's files" - I already bundle the OS9 IDE drivers, the only way for installing them at all is reformat or having them present for OS9 drive setup to be able to update them... if I could have avoided bundling them (for dualboots) I would have...

Regarding the open firmware nvram changes, that would make sense given OSX BootX comes up in 1024x768 under dingusppc, the same as when dropping to OF prompt, yet OF boot switches back to 640x480.

@Wack0
Copy link
Owner

Wack0 commented Oct 16, 2024

so I've been thinking about Old World support again. I also got a cheap wallstreet (PDQ) that's seen better days for testing on real hardware eventually.

I've decided that the "best" way to go about things would be a custom System file like what Apple did for OSX, except implementing a full stage1 bootloader in that System file instead of just modifying OF variables and rebooting.

With the boot partition as Apple_HFS, it would then show in startup disks, and ARC firmware could search the drive for bootable HFS partitions and show all of those in the boot list, and change the boot partition in NVRAM (or just set things up on disk for stage1 to do it) and reboot when attempting to boot those.

(I noticed that the MESH driver in open firmware on my wallstreet was broken for the SCSI device I'm currently testing with, INQUIRY would not complete until I powered off the device, but the toolbox ROM could use it fine. It works fine under open firmware on my lombard.)

NuBus systems (although I'm not planning to get one) could be supported in the same manner (with a different stage1 bootloader), which would allow for drive partitioning code in stage2 to be shared.

@MCJack123
Copy link
Author

I've also been thinking about restarting this project, and now I've got my 7600 back with me (didn't have access to it for a while). I've done a little bit of testing and research, but I haven't gotten to do anything significant as I lack a good way to boot HFS+ volumes on real hardware - I'd rather not burn my limited CD stack on tests that won't work, and it's hard to do anything meaningful with the internal hard drive, so I'll need to get a BlueSCSI to drop CD images through.

I've decided that the "best" way to go about things would be a custom System file like what Apple did for OSX, except implementing a full stage1 bootloader in that System file instead of just modifying OF variables and rebooting.

I'm not sure how well that would work. The boot code in the system file is 68K, so some trap would be needed to tell the system to run native PowerPC code - possibly the MixedModeDispatch trap, but I failed to find any info about it online. Furthermore, Open Firmware wouldn't be readily available, so we'd need to use other undocumented methods (or Gestalt?) to get the addresses of everything, meaning a complete rewrite (yay!). (Or could we use a static offset to find it? Sounds like trouble.) And of course, this would also require building with a compiler that has MPW and 68K and A-line traps and all that legacy stuff that's probably pretty hard to find nowadays. While it would be nice to use the Mac Toolbox to grab files and whatnot, it seems like a hell of a lot more work than just rebooting again and running the existing payload.


The following is some collected miscellany about my tests so far.

  • From my reasoning, the Old World boot process consists of:
    • Open Firmware initializes stuff and searches for a boot device.
    • The default boot device is /AAPL,ROM, so it boots the PowerPC segment in ROM.
    • The ROM then initializes the 68K emulator and runs the Macintosh Toolbox init code.
    • Then the Toolbox searches for a blessed startup volume (one with a boot block and System/Finder files - TODO: figure out how relevant the startup code in the boot block is, as references say that it's ignored in favor of whatever's in the suitcase)
    • Once found, the Toolbox loads the (68K) code segment in the first boot resource of the system suitcase.
    • Then Mac OS starts up using whatever magic it has in boot.
  • I used CodeWarrior Gold 10 to build a test system suitcase using its Code Resource output type. I had to make sure to check "Single segment" to build to a single boot resource. I also needed to add some extra code to initialize the A5 register for QuickDraw, and to define the qd global. However...
  • Booting this system suitcase from a floppy disk, after setting the right type codes and adding a boot block to the disk, resulted in a freeze on the Happy Mac. I probably definitely did something wrong, as I was also messing with some of the data from the OS X system suitcase, but I can't really debug it any further.
  • I then tried simply copying the OS X suitcase to the floppy, and that also failed. Perhaps it's because the first stage code is hardcoded to look on the CD and not a floppy? (The OS X suitcase has two boot entries, and from an uninformed glance at the disassembly, it appears the first one mounts the volume, gets the second boot resource from the System file, and executes it. I'm guessing this is because there's a <1000 byte limit on the boot block in HFS.)
  • I also took a peek into how OpenBIOS (QEMU's OF implementation) handles Mac booting. In its mac-parts package, the loader has a note that Apple Open Firmware looks for the first partition with Apple_Boot or Apple_HFS type which has boot code registered in the partition entry.
  • Next I messed around with building a theoretical boot ISO based on my first method above, except just with an HFS+ volume. I copied the driver partitions and partition map from a 10.0 CD and added a 10 MB HFS+ partition after. I used mkfs.hfsplus from hfsprogs on Linux to format it.
  • The underlying newfs_hfs program from Apple's diskdev_cmds project dropped support for HFS wrappers in version 491, so I had to get an older version to be able to generate the wrapper. Luckily, the entire contents of the resource fork of the System suitcase it generates (which is simply an HFS+ driver and chainloader) are stored in a separate file, so I could simply replace that data to put in the OS X loader.
  • For some reason, newfs_hfs artificially restricts the size of the resource fork to 64k, but the OS X loader is 71k. I'm not sure why this is - I couldn't find any limits it's breaking, and everything's sized and allocated dynamically - but I was able to recompile from source (using Ubuntu's build scripts) to override this limit.
  • To finish off the image, I copied my boot.xcoff file to the HFS+ partition, and adjusted the partition entry to point to the file on disk. The sector number is an offset from the start of the partition.
  • Emulators are constantly failing me in trying to test this image - dingusppc doesn't show any disks on both pm7500 and pmg3dt, which use SCSI and IDE respectively; QEMU (which is technically New World) hangs on trying to access the CD; and SheepShaver (which probably doesn't have enough low-level emulation of hardware) throws an illegal instruction when booting through the system suitcase.

Long story short, the Mac OS X method seems promising, but I'm gonna need a BlueSCSI to test any further.

@Wack0
Copy link
Owner

Wack0 commented Nov 9, 2024

The boot code in the system file is 68K, so some trap would be needed to tell the system to run native PowerPC code

The OSX one that sets up OF for booting OSX has a small 68k stub (260 bytes) that uses MixedModeDispatch to get into ppc mode after doing some stuff involving reading or trying to read Debugger and Disassembler files that I don't understand the purpose of, the MixedModeDispatch struct points to a powerpc pef directly after the 68k code.

this would also require building with a compiler that has MPW and 68K and A-line traps and all that legacy stuff that's probably pretty hard to find nowadays

Retro68 is a thing. I don't really care about the 68k side, using Apple's 260 byte stub for that should be good enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants