Author Topic: Building a custom Mac OS ROM.  (Read 421 times)

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Building a custom Mac OS ROM.
« on: January 07, 2019, 05:52:00 AM »
I want to try my hand at building the Mac OS ROM, I used Elliot's repo:

https://github.com/elliotnunn/newworld-rom

Got a basic build going, however I'd like to use some of the patches used for the Mini.

ELN, do you have a repo for building the Rom we use for the Mini?

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #1 on: January 11, 2019, 05:54:38 AM »
Just uncomment this line in bootmake.py to get it booting:

Code: [Select]
# SET_PRIM_INFO = ['000000ff', '0000002c', '00030d40', '0001e705', '00001400', '00000000', '0000260d', '46000270'] # for mini

The CPU Plugin will still crash the machine when it tries to access the THRM registers. You can work around this with a NanoKernel patch in the aggressive-mini-power-mgt branch of my powermac-rom repo. This repo is pretty janky, so here is the 4 MB “rom” file from the tbxi that I released in April. As well as the NanoKernel patch to fix the CPU Plugin, it also features that fancy Happy Mac from MacTron.

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #2 on: January 11, 2019, 08:31:40 AM »
Just uncomment this line in bootmake.py to get it booting:

Code: [Select]
# SET_PRIM_INFO = ['000000ff', '0000002c', '00030d40', '0001e705', '00001400', '00000000', '0000260d', '46000270'] # for mini

The CPU Plugin will still crash the machine when it tries to access the THRM registers. You can work around this with a NanoKernel patch in the aggressive-mini-power-mgt branch of my powermac-rom repo. This repo is pretty janky, so here is the 4 MB “rom” file from the tbxi that I released in April. As well as the NanoKernel patch to fix the CPU Plugin, it also features that fancy Happy Mac from MacTron.



Building for the iBook G4 to see if I can enable sleep, don't really want to patch the prim-info as yet.

I'm having trouble building a :tbxi that is bootable, just halts at " DO-QUIESCE finished"?

Code: [Select]
make tbxi.hqx
rm -f tbxi # in case of stray resource fork
./scripts/bootmake.py tbxi trampoline.elf parcels
SetFile -t tbxi -c chrp tbxi || true # try to set finfo on macOS
# cd ../enablifier && ./enablify templates/mac-os-rom-9.6.1 "/Users/jam/Downloads/newworld-rom-master/tbxi" # Uncomment to use https://github.com/elliotnunn/enablifier (requires macOS)
rm -f rsrcfork && touch rsrcfork && cp tbxi/..namedfork/rsrc rsrcfork 2>/dev/null || true # try to preserve rsrc fork before binhexing
scripts/binhexmake.py --data=tbxi --rsrc=rsrcfork --type=tbxi --creator=chrp --name="Mac OS ROM" tbxi.hqx
rm -f rsrcfork
« Last Edit: January 11, 2019, 08:45:16 AM by darthnVader »

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #3 on: January 11, 2019, 03:27:12 PM »
In that case, have a look at the mini-pmu-fix branch. You’ll need to use git to clone the repository, then run git checkout mini-pmu-fix. You can also look at the commit history of that branch and revert any commits that you think are inappropriate for your iBook.

IIRC, the problem you describe indicates that the Trampoline is handing control to the NanoKernel successfully, and the error is occurring later on.

Just to be clear, has one of the mini ROMs previously started your iBook?

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #4 on: January 11, 2019, 06:16:10 PM »
In that case, have a look at the mini-pmu-fix branch. You’ll need to use git to clone the repository, then run git checkout mini-pmu-fix. You can also look at the commit history of that branch and revert any commits that you think are inappropriate for your iBook.

IIRC, the problem you describe indicates that the Trampoline is handing control to the NanoKernel successfully, and the error is occurring later on.

Just to be clear, has one of the mini ROMs previously started your iBook?

mini-pmu-fix branch builds and seems to boot, however if I comment out the PRIM_INFO it hangs on loading the Apple CPU Plugin, also if I try to replace the PRIM_INFO with the correct one for my iBook, it hangs on loading that.
« Last Edit: January 12, 2019, 12:25:58 PM by darthnVader »

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #5 on: January 14, 2019, 09:06:05 PM »
I’m not quite sure I follow. Where does this iBook normally hang, and what evidence do you have that points to an underlying cause?

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #6 on: January 15, 2019, 05:03:55 AM »
The iBook hangs when loading the Apple CPU Plugin, remove it and no boot hang.

The odd thing is, if I don't modify mini-pmu-fix branch, it boots fine with the CPU Plugin, however the PRIM_INFO is all wrong.

Not sure what patching was done to rid of the thermal register, and enable Nap, but it seems that should work on any 7447a CPU?

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #7 on: January 15, 2019, 07:02:18 AM »
You’re right. The file that carries the THRM patch is the ‘rom’ file, which contains the NanoKernel. Try that one!

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #8 on: January 15, 2019, 06:44:51 PM »
Some reason it just doesn't work, the patched NK just hangs the machine when the Apple CPU Plugin loads.

Not real sure what is causing this, I was thinking it had something to do with the PRIM_INFO, but my iBook G3 uses the same PRIM_INFO and it boots and sleeps just fine with this rom.

I know this rom was made for the Mini, I just wanted to give it a go on the iBook G3 to try and eliminate the PRIM_INFO string.

Here is a snip of the bootmake.py I'm using:

Code: [Select]
# Set constants.

# The COMPATIBLE field at the top of the script
COMPATIBLE = [
    "PowerBook6,5",
    "PowerMac10,2",
]

# Changes to the Forth boot script, all off by default
DELETE_MODEL_CHECK = True
DELETE_CHECKSUM_CHECK = False
G4_FIX = True

# *After* OF has loaded this file, set the "model" property?
SET_MODEL_PROPERTY = ''
SET_MODEL_PROPERTY = 'PowerBook6,5' # Cube

# ...and the "compatible" property? (empty strings not counted)
SET_COMPATIBLE_PROPERTY = [x for x in [
    SET_MODEL_PROPERTY,
    "MacRISC",
    "MacRISC2",
    'Power Macintosh',
] if x]

SET_PRIM_INFO = None
SET_PRIM_INFO = ['000000ff', '00000060', '00003e80', '00017fb5', '0202d607', '00000000', '00011300', '46000220'] # for iBook G4
# SET_PRIM_INFO = ['000000ff', '0000002c', '00030d40', '0001e705', '00001400', '00000000', '0000260d', '46000270'] # for mini

Like I say, I can boot the iBook G4 just fine with the Apple CPU Plugin enabled, so long as I only use the PRIM_INFO you made for the Mini.

I'm not really sure why it's boot hanging with the correct PRIM_INFO?

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #9 on: January 15, 2019, 08:51:53 PM »
Well, you might have figured out exactly what PRIM_INFO *does* :D. We know about a few of the bits from the Darwin sources, but mostly we’re in the dark. Can you “bisect” the structure to figure out which bit is important?

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #10 on: January 16, 2019, 03:52:34 AM »
Here are my notes on prim-info.

Code: [Select]
iBook G4            000000ff 00000060 00003e80 00017fb5 0202d607 00000000 00011300 46000220
Power Mac G4 MDD    000000ff 0000002c 00030d40 0001e705 00003400 00000000 0000260d 46000270

                                               ^^^^^^^^ public PM features
                                                        ^^^^^^^^ private PM features
                                                                          ^^^^ batt count

FROM THE DARWIN SOURCES:

// PUBLIC power management features
// NOTE: this is a direct port from classic, some of these bits
//       are obsolete but are included for completeness
enum {
  kPMHasWakeupTimerMask        = (1<<0),  // 1=wake timer is supported
  kPMHasSharedModemPortMask    = (1<<1),  // Not used
  kPMHasProcessorCyclingMask   = (1<<2),  // 1=processor cycling supported
  kPMMustProcessorCycleMask    = (1<<3),  // Not used
  kPMHasReducedSpeedMask       = (1<<4),  // 1=supports reduced processor speed
  kPMDynamicSpeedChangeMask    = (1<<5),  // 1=supports changing processor speed on the fly
  kPMHasSCSIDiskModeMask       = (1<<6),  // 1=supports using machine as SCSI drive
  kPMCanGetBatteryTimeMask     = (1<<7),  // 1=battery time can be calculated
  kPMCanWakeupOnRingMask       = (1<<8),  // 1=machine can wake on modem ring
  kPMHasDimmingSupportMask     = (1<<9),  // 1=has monitor dimming support
  kPMHasStartupTimerMask       = (1<<10), // 1=can program startup timer
  kPMHasChargeNotificationMask = (1<<11), // 1=client can determine charger status/get notifications
  kPMHasDimSuspendSupportMask  = (1<<12), // 1=can dim diplay to DPMS ('off') state
  kPMHasWakeOnNetActivityMask  = (1<<13), // 1=supports waking upon receipt of net packet
  kPMHasWakeOnLidMask          = (1<<14), // 1=can wake upon lid/case opening
  kPMCanPowerOffPCIBusMask     = (1<<15), // 1=can remove power from PCI bus on sleep
  kPMHasDeepSleepMask          = (1<<16), // 1=supports deep (hibernation) sleep
  kPMHasSleepMask              = (1<<17), // 1=machine support low power sleep (ala powerbooks)
  kPMSupportsServerModeAPIMask = (1<<18), // 1=supports reboot on AC resume for unexpected power loss
  kPMHasUPSIntegrationMask     = (1<<19)  // 1=supports incorporating UPS devices into power source calcs
};

// PRIVATE power management features
// NOTE: this is a direct port from classic, some of these bits
//       are obsolete but are included for completeness.
enum {
  kPMHasExtdBattInfoMask       = (1<<0),  // Not used
  kPMHasBatteryIDMask          = (1<<1),  // Not used
  kPMCanSwitchPowerMask        = (1<<2),  // Not used
  kPMHasCelsiusCyclingMask     = (1<<3),  // Not used
  kPMHasBatteryPredictionMask  = (1<<4),  // Not used
  kPMHasPowerLevelsMask        = (1<<5),  // Not used
  kPMHasSleepCPUSpeedMask      = (1<<6),  // Not used
  kPMHasBtnIntHandlersMask     = (1<<7),  // 1=supports individual button interrupt handlers
  kPMHasSCSITermPowerMask      = (1<<8),  // 1=supports SCSI termination power switch
  kPMHasADBButtonHandlersMask  = (1<<9),  // 1=supports button handlers via ADB
  kPMHasICTControlMask         = (1<<10), // 1=supports ICT control
  kPMHasLegacyDesktopSleepMask = (1<<11), // 1=supports 'doze' style sleep
  kPMHasDeepIdleMask           = (1<<12), // 1=supports Idle2 in hardware
  kPMOpenLidPreventsSleepMask  = (1<<13), // 1=open case prevent machine from sleeping
  kPMClosedLidCausesSleepMask  = (1<<14), // 1=case closed (clamshell closed) causes sleep
  kPMHasFanControlMask         = (1<<15), // 1=machine has software-programmable fan/thermostat controls
  kPMHasThermalControlMask     = (1<<16), // 1=machine supports thermal monitoring
  kPMHasVStepSpeedChangeMask   = (1<<17), // 1=machine supports processor voltage/clock change
  kPMEnvironEventsPolledMask   = (1<<18)  // 1=machine doesn't generate pmu env ints, we must poll instead
};

// DEFAULT public and private features for machines whose device tree
// does NOT contain this information (pre-Core99).

// For Cuda-based Desktops

#define kStdDesktopPMFeatures   kPMHasWakeupTimerMask         |\
                                kPMHasProcessorCyclingMask    |\
                                kPMHasDimmingSupportMask      |\
                                kPMHasStartupTimerMask        |\
                                kPMSupportsServerModeAPIMask  |\
                                kPMHasUPSIntegrationMask

#define kStdDesktopPrivPMFeatures  kPMHasExtdBattInfoMask     |\
                                   kPMHasICTControlMask       |\
                                   kPMHasLegacyDesktopSleepMask

#define kStdDesktopNumBatteries 0

// For Wallstreet (PowerBook G3 Series 1998)

#define kWallstreetPMFeatures   kPMHasWakeupTimerMask         |\
                                kPMHasProcessorCyclingMask    |\
                                kPMHasReducedSpeedMask        |\
                                kPMDynamicSpeedChangeMask     |\
                                kPMHasSCSIDiskModeMask        |\
                                kPMCanGetBatteryTimeMask      |\
                                kPMHasDimmingSupportMask      |\
                                kPMHasChargeNotificationMask  |\
                                kPMHasDimSuspendSupportMask   |\
                                kPMHasSleepMask

#define kWallstreetPrivPMFeatures  kPMHasExtdBattInfoMask      |\
                                   kPMHasBatteryIDMask         |\
                                   kPMCanSwitchPowerMask       |\
                                   kPMHasADBButtonHandlersMask |\
                                   kPMHasSCSITermPowerMask     |\
                                   kPMHasICTControlMask        |\
                                   kPMClosedLidCausesSleepMask |\
                                   kPMEnvironEventsPolledMask

#define kStdPowerBookPMFeatures      kWallstreetPMFeatures
#define kStdPowerBookPrivPMFeatures  kWallstreetPrivPMFeatures

#define kStdPowerBookNumBatteries 2

// For 101 (PowerBook G3 Series 1999)

#define k101PMFeatures          kPMHasWakeupTimerMask         |\
                                kPMHasProcessorCyclingMask    |\
                                kPMHasReducedSpeedMask        |\
                                kPMDynamicSpeedChangeMask     |\
                                kPMHasSCSIDiskModeMask        |\
                                kPMCanGetBatteryTimeMask      |\
                                kPMHasDimmingSupportMask      |\
                                kPMHasChargeNotificationMask  |\
                                kPMHasDimSuspendSupportMask   |\
                                kPMHasSleepMask               |\
                                kPMHasUPSIntegrationMask

#define k101PrivPMFeatures      kPMHasExtdBattInfoMask        |\
                                kPMHasBatteryIDMask           |\
                                kPMCanSwitchPowerMask         |\
                                kPMHasADBButtonHandlersMask   |\
                                kPMHasSCSITermPowerMask       |\
                                kPMHasICTControlMask          |\
                                kPMClosedLidCausesSleepMask   |\
                                kPMEnvironEventsPolledMask

#define IOPMNoErr       0   // normal return

                        // returned by powerStateWillChange and powerStateDidChange:
#define IOPMAckImplied      0   // acknowledgement of power state change is implied
#define IOPMWillAckLater    1   // acknowledgement of power state change will come later

                        // returned by requestDomainState
#define IOPMBadSpecification    4   // unrecognized specification parameter
#define IOPMNoSuchState     5   // no power state matches search specification

#define IOPMCannotRaisePower    6   // a device cannot change its power for some reason

                        // returned by changeStateTo
#define IOPMParameterError  7   // requested state doesn't exist
#define IOPMNotYetInitialized   8   // device not yet fully hooked into power management "graph"

The offending bits seem to be 0x202D607

We don't know what bits 0-2 do, but they are set, as well as bit 25?

Bits 9 and 10:

Code: [Select]
kPMHasADBButtonHandlersMask  = (1<<9),  // 1=supports button handlers via ADB
kPMHasICTControlMask         = (1<<10), // 1=supports ICT control

Bits 12, 14, and 15:

Code: [Select]
kPMHasDeepIdleMask           = (1<<12), // 1=supports Idle2 in hardware
  kPMOpenLidPreventsSleepMask  = (1<<13), // 1=open case prevent machine from sleeping
  kPMClosedLidCausesSleepMask  = (1<<14), // 1=case closed (clamshell closed) causes sleep
  kPMHasFanControlMask         = (1<<15), // 1=machine has software-programmable fan/thermostat

Then bit 17:

Code: [Select]
kPMHasVStepSpeedChangeMask   = (1<<17), // 1=machine supports processor voltage/clock change
Setting this to a known value for desktops( 0x1400 or 0x3400 ) works with our patched NK and the Apple CPU Plugin, whereas a few I tried unpicking bits just resulted in the same lockup I've been having.

Tho 0x02021607 resulted in an immediate shutdown when the Apple CPU Plugin loaded.


Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #11 on: January 16, 2019, 04:30:42 AM »
Code: [Select]
SET_PRIM_INFO = ['000000ff', '00000060', '00003e80', '00017fb5', '0200d607', '00000000', '00011300', '46000220'] # for iBook G4
Unticking bit 17 seems to be working, iBook knows it's a mobile unit and goes to sleep, but never wakes up.



Code: [Select]
kPMHasVStepSpeedChangeMask   = (1<<17), // 1=machine supports processor voltage/clock change
The 7447a does support clock change via changing the multiplier, but OS 9's power management software doesn't have any code to do that, so it's really a needless bit, at this point.

So we have the same sleep state we have with the Mini, the iBook appears to sleep, but never wakes up?
« Last Edit: January 16, 2019, 04:42:35 AM by darthnVader »

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #12 on: January 16, 2019, 05:03:37 AM »
I suspect that the system is never really entering sleep, best guess is the USB2 or AE PCI cards are preventing sleep.

I seem to recall some USB2 PCI cards preventing sleep in tower Macs under OS 9.

If someone can figure the proper pci-probe-mask bits, we can tell the system not to probe for the ehci pci device at startup.

It's pci/@1b,2, but I'm not sure what bit in the probe-mask that is?
« Last Edit: January 16, 2019, 05:24:54 AM by darthnVader »

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #13 on: January 16, 2019, 04:03:06 PM »
I think sleep is going to be more involved than fixing PCI devices.

Code: [Select]
// Power Management support functions and data structures:
// These come (almost) unchanged from the MacOS9 Power
// Manager plug-in (p99powerplugin.c)

Seemingly there exists somewhere, maybe someone has some of the Classic Mac OS dev cd's, the p99powerplugin.c and p99powerplugin.h.

If we had these files, maybe Elliot could hack us together some sleep support for Apple KeyLargo 2?

Am I correct in assuming that all G4 Mac's with USB2 are K2 based, and there never was a K2 based Mac that had native OS 9 boot?

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #14 on: January 16, 2019, 08:46:59 PM »
Probably a tall order, and remember I’m still pretty poor at wanging hardware. Maybe you could dump all the strings in that binary, and see from there which sources probably went in?

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #15 on: January 16, 2019, 08:48:14 PM »
Meanwhile, I strongly suggest this: with a vanilla build that is just enough to get the iBook booting, see which prim info bit might be controlling the CPU plugin crash. Fun fun!

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #16 on: January 16, 2019, 10:32:45 PM »
Vader, you got me thinking again about what can be found in the Darwin sources. Check this gem out:

https://opensource.apple.com/source/xnu/xnu-201/osfmk/ppc/POWERMAC/mp/MPPlugIn.h.auto.html

It is a header describing much of the behaviour of a Mac OS 9 CPU Plugin!

Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #17 on: January 17, 2019, 05:09:00 AM »
Vader, you got me thinking again about what can be found in the Darwin sources. Check this gem out:

https://opensource.apple.com/source/xnu/xnu-201/osfmk/ppc/POWERMAC/mp/MPPlugIn.h.auto.html

It is a header describing much of the behaviour of a Mac OS 9 CPU Plugin!

We'll add that to the collection:

https://opensource.apple.com/source/AppleKeyLargo/AppleKeyLargo-170.0.0/KeyLargo.h.auto.html

https://opensource.apple.com/source/AppleKeyLargo/AppleKeyLargo-150.0.3/AppleK2.h.auto.html

https://opensource.apple.com/source/AppleKeyLargo/AppleKeyLargo-140.0.19/AppleK2.cpp.auto.html

I think the KeyLargo.h has some interesting bits as far as sleep of Intrepid.


Offline darthnVader

  • Gold Member
  • *****
  • Posts: 431
  • New Member
Re: Building a custom Mac OS ROM.
« Reply #18 on: January 17, 2019, 07:42:06 AM »
One odd thing I will note, is for the iBook G4 with the 1.33Ghz G4, it appears to be running at 50% cpu speed under OS 9.

Offline Daniel

  • Silver Member
  • ****
  • Posts: 202
  • Programmer, Hacker, Thinker
Re: Building a custom Mac OS ROM.
« Reply #19 on: January 17, 2019, 06:38:11 PM »
Vader, you got me thinking again about what can be found in the Darwin sources. Check this gem out:

https://opensource.apple.com/source/xnu/xnu-201/osfmk/ppc/POWERMAC/mp/MPPlugIn.h.auto.html

It is a header describing much of the behaviour of a Mac OS 9 CPU Plugin!
The Plugin code in that directory also looks interesting. What Mac do you think it is for?

Offline ELN

  • Silver Member
  • ****
  • Posts: 249
  • new to the forums
Re: Building a custom Mac OS ROM.
« Reply #20 on: January 18, 2019, 04:54:39 AM »
Looks like Tanzania. Any match with a known cpup binary?