• Hello MLAers! We've re-enabled auto-approval for accounts. If you are still waiting on account approval, please check this thread for more information.

updated firmware for new world ppc32 macs that allows booting from usb from the boot picker

findandadd-block appears to be the same in 4.8.9f4 (Mac mini G4) and 5.2.7f1 (Quad G5).

I suppose we might need to look at the assembly code to make sure they compile the same.
Interesting. Just to confirm, this is specifically what's in my nvramrc:
Code:
\ Enable OS 9 boot selection (MacRISC, MacRISC2)
" /" select-dev
" PowerMac10,1" encode-string " MacRISC" encode-string encode+ " MacRISC2" encode-string encode+ " MacRISC3" encode-string encode+ " Power Macintosh" encode-string encode+ " compatible" property
unselect

dev /packages/bootpath-search
\ enable scan of USB devices
: mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
' findandadd-block 3ac + ' mypatch c + brpatch
\ enable scan of 3 USB LUNs (not useful since only the first LUN works)
\ 3 ' findandadd-block-usb 98 + code!
With the debugging vars set I don't see it looking through the USB bus at all, just the ATA disks.

If I manually boot from the USB drive, it does work, but I guess it's possible the disk is formatted in some way the USB probe doesn't detect? I kinda doubt that's it though, since I don't see any trace of it searching USB.

If I understand correctly, the patch is meant to add the 6th case back?
 
I futzed around for awhile and realized I wasn't understanding the Forth errors. It seems like the findandadd-block words aren't defined in this ROM and/or package?
Code:
0 > dev /packages/bootpath-search  ok
0 > : mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
findandadd-block-usb, unknown word, HERE= ff9ddddc
 ok
0 > ' findandadd-block 3ac + ' mypatch c + brpatch
findandadd-block, unknown word, HERE= ff9ddddc
 ok
Running words on /packages/bootpath-search seems to confirm. And see just fails accordingly.
 
If I understand correctly, the patch is meant to add the 6th case back?
Correct. We add it to the end of findandadd-block since there's no place to add it earlier (patching case and of and endof or any other flow control words is weird - avoid it). Actually, ; is kind of a flow control word. Perhaps it would have been better to just replace
Code:
            6
            -> local_4
with
Code:
            local_0
            findandadd-block-usb
We don't need to do it in the case statement unless there's a possibility of a USB device to also be a "k2-sata" which is the only other item after usb and hub and usb-device that can change local_4.
We need to set local_4 if there is a possibility that a usb or hub or [icode"usb-device[/icode] device can also be one of the earlier devices (scsi, scsi-wide, wide, extended, spi, ide, ata, swim3, fdc, or sbp-2)

Since we are using local variables in the patch, we are using a brpatch to jump to after the local variables are setup in our patch instead of a blpatch to our patch. If we put the brpatch in the middle of findandadd-block-usb instead of the end then we need to add a brpatch at at the end of our patch to branch back to findandadd-block-usb (a blpatch would not need to do that).

A blpatch is a branch with link instruction (bl in PPC assembly). The least significant bit is 1 to indicate the link option.
Code:
0 > see blpatch 
: blpatch 
  over - 3fffffc and 48000001 or swap code! ; ok

A brpatch is a branch instruction (br in PPC assembly)
Code:
0 > see brpatch 
: brpatch 
  over - 3fffffc and 48000000 or swap code! ; ok

Interesting. Just to confirm, this is specifically what's in my nvramrc:
That looks correct. I would reduce line length to less than 80 characters if possible.

Have you tried applying the patch manually without using nvramrc?

You have not provided any info to prove that findandadd-block + 3ac is the correct offset for the patch or that mypatch + c is the correct destination for the patch.

If you do see findandadd-block then you should see at the end some garbage where the ; used to be.
Code:
0 > see findandadd-block
: findandadd-block 
...
    8 of 
      {0@} findandadd-block-scsi-extended 
      endof 
    endcase 
  endof 
{1} {0@} makefullpathalloc {2!} {1!} {1@} {2@} bpr-new {1@} {2@} 
ib-newphyspath true bpr-set-infobit {1@} {2@} {0@} bpr-set-node {1@} {2@} 
ib-netpath true bpr-set-infobit {1@} {2@} bi-t-net bi-t-loc lshift 
bpr-set-businfo {1@} {2@} freemem0 ;
STACK UNDERFLOW!
 ok

If you do xsee findandadd-block then you should see that the word at ' findandadd-block 3ac + has changed from a branch with negative offset 4beff444 to a branch with positive offset 480f4a58 (the offset is the least 26 bits of the branch instruction, i.e. instruction & 0x03fffffc.
Code:
0> xsee findandadd-block
...
ff947058: 4befffa9 (endcase) 
ff94705c: 480f4a58 <- positive offset means it's patched.

With the debugging vars set I don't see it looking through the USB bus at all, just the ATA disks.

If I manually boot from the USB drive, it does work, but I guess it's possible the disk is formatted in some way the USB probe doesn't detect? I kinda doubt that's it though, since I don't see any trace of it searching USB.
What command do you use to boot manually?

Check the contents of dev / ls and dump-device-tree and devalias

Do you see any USB disks? What are the properties?

Do you see a usb disk devalias?
Code:
ud                  /ht@0,f2000000/pci@8/usb@b/disk@2

If it's missing, then try adding it (encode it as a property in dev /alias
 
I futzed around for awhile and realized I wasn't understanding the Forth errors. It seems like the findandadd-block words aren't defined in this ROM and/or package?
Code:
0 > dev /packages/bootpath-search  ok
0 > : mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
findandadd-block-usb, unknown word, HERE= ff9ddddc
 ok
0 > ' findandadd-block 3ac + ' mypatch c + brpatch
findandadd-block, unknown word, HERE= ff9ddddc
 ok
Running words on /packages/bootpath-search seems to confirm. And see just fails accordingly.
Oh, findandadd-block-usb is defined with headers instead of external
You need to do this:
setenv fcode-debug? true
to see words that are defined with headers
Words that are defined with headerless have no names and are therefore not seen with words in any case.
 
I futzed around for awhile and realized I wasn't understanding the Forth errors. It seems like the findandadd-block words aren't defined in this ROM and/or package?
Does doing setenv fcode-debug? true and rebooting make the patch work?
 
Have you tried applying the patch manually without using nvramrc?
Yeah, that's when I realized it couldn't find the words.

Oh, findandadd-block-usb is defined with headers instead of external
You need to do this:
setenv fcode-debug? true
to see words that are defined with headers
Words that are defined with headerless have no names and are therefore not seen with words in any case.

Does doing setenv fcode-debug? true and rebooting make the patch work?
Yeah, I see where you're going with that and I had started to wonder the same thing myself...will test tomorrow if I have a chance.

If that at least applies the patch, I can tinker with the offset!
 
Yep! That made the difference. So debug needs to be enabled to expose the words to patch.

Let me hunt for the proper offset:

If I understand correctly, I'm looking to patch the statement just after the (endcase). findandadd-block starts at ff93b210 and the statement after is ff93b5bc. That's an offset of 3ac, so it matches.

After patching I've got:
Code:
ff93b5b8: 4bf0bf49 (endcase)
ff93b5bc: 480a2800

Tried it out, and it works! multi-boot picker now shows my USB drive.

However, the nvramrc still doesn't trigger it....curious. Time to fiddle some more!

EDIT: Nevermind, had a syntax error in my final nvramrc. Works fantastically!

Here's my little script if anyone wants it, it also enables a few other features:
- OS 9 drive firmware should be installable from Disk Utility
- OS 9 should be pickable in the OS X Startup Disk configuration
- USB drives should appear in the OF boot picker
- OS X should display it's version in the OF boot picker
Code:
#!/bin/bash
echo "Setting nvramrc to allow OS 9 boot picker and USB boot..."
sudo nvram nvramrc="\" /\" select-dev
\" PowerMac10,1\" encode-string \" model\" property
\" PowerMac10,1\" encode-string \" MacRISC\" encode-string encode+ \" MacRISC2\" encode-string encode+ \" MacRISC3\" encode-string encode+ \" Power Macintosh\" encode-string encode+ \" compatible\" property
unselect

dev /packages/bootpath-search
: mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
' findandadd-block 3ac + ' mypatch c + brpatch
"

sudo nvram "use-nvramrc?"=true

# fcode-debug is required for the USB patch to work
sudo nvram "fcode-debug?"=true

# Disable netboot for faster boot picker
sudo nvram "skip-netboot?"=true

# Display OS X versions in boot picker
sudo nvram aapl,debug-mbv=true

echo "Done."
I assume this works on at least the Mac mini G4 and aforementioned G5 system. Yeah my quoting is dumb, I got lazy.
 
Last edited:
For nvramrc, I would reduce the max line width to less than 80 characters and replace unix line feeds with classic Mac carriage returns like this:
Code:
sudo nvram nvramrc="$(tr '\n' '\r' << DONE
" /" select-dev
" PowerMac10,1" encode-string " model" property
" PowerMac10,1" encode-string
" MacRISC" encode-string encode+
" MacRISC2" encode-string encode+
" MacRISC3" encode-string encode+
" Power Macintosh" encode-string encode+
" compatible" property
unselect

dev /packages/bootpath-search
: mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
' findandadd-block 3ac + ' mypatch c + brpatch
DONE
)"

If you know the fcode number for a word, then you don't need to have fcode-debug? set to true. But I don't see any reason not to have fcode-debug? true.

Instead of ' findandadd-block, you could use 1d5f get-token drop but first verify that they both give the same address. Note how later Macs support fcode numbers with more than 12 bits. Different versions of Open Firmware will have different fcode numbers for the same word. The fcode number is at an offset before the execution token address that is returned by ' or ['] or get-token. The offset increases with the length of the name (if the word has a name).

There's an xt>hdr word to convert an execution token address to a compiled fcode word header address.

A compiled fcode word header has these fields:
Code:
\ header address is 4 byte aligned
0 >h.link \ offset to the next word in the dictionary
4 >h.flags \ flags
5 >h.ctype \ code type
6 >h.token \ fcode number
8 >h.count \ length of name
9 >h.name \ name

The flags are these:
Code:
h#80 constant fdefd \ word is finished compiling/defined
\ fdefd with 4 byte alignment marks header offset +4 because of the following:
\ >h.ctype and >h.token don't have 4 byte alignment. >h.count can't be ≥ 0x80. >h.name can't include ASCII ≥ 0x80.
h#40 constant fimm \ immediate
h#20 constant fnohdr \ headerless
h#10 constant falias \ alias
8 constant finstance \ instance ; indexed by my-self
4 constant fvisible \ external
2 constant finvisible \ headerless
1 constant fvectored \ vectored ; similar to instance but not sure how they work ; indexed by my-vector

The code types are these:
Code:
0x0b7 b(:) \ compiled forth words
0x0b8 b(value)
0x0b9 b(variable)
0x0ba b(constant)
0x0bb b(create)
0x0bc b(defer)
0x0bd b(buffer:)
0x0be b(field)
0x0bf b(code) \ for precompiled words or words that include assembly and can't be converted back to Forth with the see command
 
After fighting with my mini this week I realized I introduced a bug into my script above. A corrected version:
Code:
#!/bin/bash
echo "Setting nvramrc to allow OS 9 boot picker and USB boot..."
sudo nvram nvramrc="\" /\" select-dev
\" PowerMac10,1\" encode-string \" model\" property
\" PowerMac10,1\" encode-string
\" MacRISC\" encode-string encode+
\" MacRISC2\" encode-string encode+
\" MacRISC3\" encode-string encode+
\" Power Macintosh\" encode-string encode+
\" compatible\" property
unselect

dev /packages/bootpath-search
: mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
' findandadd-block 3ac + ' mypatch c + brpatch
device-end
"

sudo nvram "use-nvramrc?"=true

# fcode-debug is required for the USB patch to work
sudo nvram "fcode-debug?"=true

# Disable netboot for faster boot picker
sudo nvram "skip-netboot?"=true

# Display OS X versions in boot picker
sudo nvram aapl,debug-mbv=true

echo "Done."
This prevents a memory exception when you don't boot directly into multi-boot. This still doesn't use proper line endings, I fixed that by hand on my system but I haven't bothered to fix the script. YMMV.
 
After fighting with my mini this week I realized I introduced a bug into my script above. A corrected version:
Code:
#!/bin/bash
echo "Setting nvramrc to allow OS 9 boot picker and USB boot..."
sudo nvram nvramrc="\" /\" select-dev
\" PowerMac10,1\" encode-string \" model\" property
\" PowerMac10,1\" encode-string
\" MacRISC\" encode-string encode+
\" MacRISC2\" encode-string encode+
\" MacRISC3\" encode-string encode+
\" Power Macintosh\" encode-string encode+
\" compatible\" property
unselect

dev /packages/bootpath-search
: mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
' findandadd-block 3ac + ' mypatch c + brpatch
device-end
"

sudo nvram "use-nvramrc?"=true

# fcode-debug is required for the USB patch to work
sudo nvram "fcode-debug?"=true

# Disable netboot for faster boot picker
sudo nvram "skip-netboot?"=true

# Display OS X versions in boot picker
sudo nvram aapl,debug-mbv=true

echo "Done."
This prevents a memory exception when you don't boot directly into multi-boot. This still doesn't use proper line endings, I fixed that by hand on my system but I haven't bothered to fix the script. YMMV.
Wow... this is just what I've been looking for! This'll let me switch into System 7.5 on my G4 Mini without the huge delay... AND let me boot it from a USB stick!
 
Wow... this is just what I've been looking for! This'll let me switch into System 7.5 on my G4 Mini without the huge delay... AND let me boot it from a USB stick!
Yeah, it makes everything surprisingly clean and tidy. Repeating from above since it was sandwiched in the middle of a long block; with these nvram changes:

- OS 9 drive firmware should be installable from Disk Utility
- OS 9 should be pickable in the OS X Startup Disk configuration
- USB drives should appear in the OF boot picker
- OS X should display it's version in the OF boot picker

This seems to apply to any classic version, as it also works for me all the way back to 7.5. Unsurprising, since boot selection is based on the New World ROM, and we're using the OS 9 copy. Ultimately the compatible property just needs to match what's in the ROM. Theoretically you could modify the ROM instead, but this is more universal (and makes Disk Utility work).

Joe did all the heavy work for the USB patch so most of the credit to him.
 
After fighting with my mini this week I realized I introduced a bug into my script above. A corrected version:
Some minor changes:
  • Translate LF to CR so the script is more easily editable in Open Firmware.
  • Use a heredoc for multi-line nvram variables like nvramrc to make the script easier to read.
  • unselect isn't a word until Open Firmware 3.1.0 (the first New World Mac Open Firmware?) which is ok for this code but for consistency, I would just use device-end (like is done later in the script). device-end is defined in the Open Firmware spec but unselect is not.
  • For consistency, use dev instead of select-dev (like is done later in the script). The nvramrc script is interpreted Forth code so it can use words like dev that take arguments from the command line instead of the stack. Also, dev is shorter and select-dev is an obsolete Open Firmware word.

Code:
sudo nvram nvramrc="$(tr '\n' '\r' << DONE
dev /
" PowerMac10,1" encode-string " model" property
" PowerMac10,1" encode-string
" MacRISC" encode-string encode+
" MacRISC2" encode-string encode+
" MacRISC3" encode-string encode+
" Power Macintosh" encode-string encode+
" compatible" property
device-end

dev /packages/bootpath-search
: mypatch { ; loc0 loc1 loc2 loc3 loc4 } loc4 6 = if loc0 findandadd-block-usb then ;
' findandadd-block 3ac + ' mypatch c + brpatch
device-end
DONE
)"

sudo nvram "use-nvramrc?"=true

# fcode-debug is required for the USB patch to work
sudo nvram "fcode-debug?"=true

# Disable netboot for faster boot picker
sudo nvram "skip-netboot?"=true

# Display OS X versions in boot picker
sudo nvram aapl,debug-mbv=true

echo "Done."
 
Hmm; could this be rolled into a ROM using ELN's patcher? It's easy enough to use as-is if you're already booted into OS X, but that would make things a bit simpler for those already living in OS 9 or earlier.
 
Hmm; could this be rolled into a ROM using ELN's patcher? It's easy enough to use as-is if you're already booted into OS X, but that would make things a bit simpler for those already living in OS 9 or earlier.
Which of @elliotnunn 's tools works with New World Boot ROMs (1 MiB flash chips)?

I have scripts to dump parts of New World Mac firmware updaters and ROMs. Some changes would be needed to allow modification and rebuilding the ROM or firmware updater.

  • Need a PPC assembler for the PPC assembly parts. Does Retro68 have a suitable PPC assembler?
  • Might need some changes to my DumpMacRom.sh script and corresponding detok command if any bugs are discovered in the output produced by those (for example, anything that can't be reversed by toke back to the equivalent fcode that the output of DumpMacRom.sh is created from).
  • Need a tool to split the Forth produced by DumpMacRom.sh into separate Forth files that toke can handle.
  • Need some additions to the toke command to handle some of the Forth code produced by DumpMacRom.sh.
  • Need a tool to stitch the assembly and fcode images together.
 
Which of @elliotnunn 's tools works with New World Boot ROMs (1 MiB flash chips)?

I have scripts to dump parts of New World Mac firmware updaters and ROMs. Some changes would be needed to allow modification and rebuilding the ROM or firmware updater.

  • Need a PPC assembler for the PPC assembly parts. Does Retro68 have a suitable PPC assembler?
  • Might need some changes to my DumpMacRom.sh script and corresponding detok command if any bugs are discovered in the output produced by those (for example, anything that can't be reversed by toke back to the equivalent fcode that the output of DumpMacRom.sh is created from).
  • Need a tool to split the Forth produced by DumpMacRom.sh into separate Forth files that toke can handle.
  • Need some additions to the toke command to handle some of the Forth code produced by DumpMacRom.sh.
  • Need a tool to stitch the assembly and fcode images together.
I wasn't thinking boot roms, just in the TBXI. After all, that loads into OF and can load objects, so seems like the logical place to insert structures like this, since it'll be self-contained in a file people can put in their System Folder.
https://github.com/elliotnunn/tbxi to explode the file, insert the additional instructions, then reassemble. But you'd be more knowledgeable than I on whether that "insert" bit is overly hand-wavy and we've got size restrictions etc. to deal with.
 
I wasn't thinking boot roms, just in the TBXI. After all, that loads into OF and can load objects, so seems like the logical place to insert structures like this, since it'll be self-contained in a file people can put in their System Folder.
https://github.com/elliotnunn/tbxi to explode the file, insert the additional instructions, then reassemble. But you'd be more knowledgeable than I on whether that "insert" bit is overly hand-wavy and we've got size restrictions etc. to deal with.
Oh right. The tbxi of the New World Mac OS ROM file does Open Firmware stuff before Mac OS boots.

tbxi dump extracts a boot script which I guess you can edit. Then tbxi build should take the edited boot script, fix up the offsets and checksum and include it in the new ROM. I haven't tried it before.

However, the USB boot patch part of the nvramrc script is not appropriate for the tbxi boot script because tbxi happens after a boot device is selected.
 
Back
Top