Creating an OPENSTEP Boot CD

How OPENSTEP 4.2 boots in m68k hardware.

A NEXTSTEP/OPENSTEP CD cannot be made to boot in both sparc and m68k hardware.  With NEXTSTEP 3.3, there was one installation CD for m68k/i386 and another installation CD for sparc/hppa.  For sparc, the hardware expects the bootloader to start at offset 0x00000200 (512) of the CD.  For m68k, the hardware expects a disklabel at the very start of the CD, and the disklabel contains a pointer to the bootloader somewhere else in the CD.  A disklabel is 7240 bytes in size and cannot fit into the available first 512 bytes of a sparc-bootable CD.

With OPENSTEP 4.2, there was a single "User" installation CD for m68k/i386/sparc (I think they dropped support for the hppa platform at that time).  Given those three platforms, NeXT probably opted to make the CD bootable on sparc hardware.  The sparc magic number 01 03 01 07 is present at offset 0x00000200 of the CD.  Note that to boot from a CD, sparc workstations need SCSI CDROM drives that provide 512-byte sectors, instead of the more common 2048-byte sectors.  Older drives from Plextor, Yamaha, and Pioneer typically have a jumper that sets the sector size.  Trying to boot the CD from m68k hardware gives the following error:

  Bad version 0x80000000
  Bad cksum
  Bad version 0x0
  Bad cksum
  Bad label

An m68k/i386 installation diskette and an i386 driver diskette were provided in 3.5" 1.44MB format.  The installation diskette is used to bootstrap the installation into m68k hardware.  I could not find an m68k bootloader anywhere in the installation diskette, which leads me to think that the boot process probably traps into the m68k ROM, which then loads a copy of the disklabel from either offset 0x00002000 or offset 0x00003C00 of the CD.  From the disklabel, the m68k bootloader can be located in the CD and the boot process continues, loading the m68k kernel "sdmach".

How OPENSTEP 4.2 boots in i386 hardware.

An i386 ROM loads the i386 initial "B1" bootloader from the first 512 bytes of the diskette.  The initial bootloader loads the standard i386 bootloader from offset 0x00008000 of the diskette.  In the boot process, the i386 kernel "mach_kernel" is loaded, "sarld" is loaded, the user is prompted to insert the driver diskette, drivers are loaded (the driver for the IDE or SCSI CD drive needs to be loaded so the CD can be read), and installation copies files from the CD into the hard disk.

Creating an m68k-bootable "User" OPENSTEP CD.

Since m68k hardware looks for a disklabel at the start of the CD, we need only to copy the duplicate disklabel located at offset 0x00002000 or offset 0x00003C00 of the CD.  From a raw "ISO" image of the OPENSTEP 4.2 CD, the disklabel can be extracted with:

  dd bs=1 count=7680 if=OPENSTEP42CD.iso of=OPENSTEP42CD.lbl skip=8192

Overlay the extracted disklabel into the first part of the CD image:

  dd bs=1 count=7680 if=OPENSTEP42CD.lbl of=OPENSTEP42CD.iso

Several bytes in the disklabel need to be changed.  The structure of the disklabel is available at bootblock.h.  The first set that needs to be changed is the block number in the disklabel.  If the disklabel originally came from offset 0x00002000, then its block number is 4 (where a block is 2048 bytes).  The new disklabel at the start of the disk should be at block number 0.

The second set of bytes that need to be changed is the pointer to the boot blocks (bootloader).  There are two pointers in the disklabel.  The first points to an hppa bootloader (block 0x10), and the second points to an m68k bootloader (block 0x30).  The hppa bootloader surprised me because I thought hppa platform support has been dropped in OPENSTEP.  Also note that the sparc bootloader that started at offset 0x00000200 has been partially overlaid by the new disklabel, so the new CD image will not be sparc-bootable.  We change the boot block pointers in the disklabel to point only to the m68k boot blocks — first pointer is set to 0x30, second pointer is set to 0xFFFFFFFF.

The third set of bytes that need to be changed is the default kernel loaded by the bootloader.  From the original disklabel, the kernel name is "mach_kernel".  Although "mach_kernel" is present on the CD, it is a tri-fat binary.  The m68k bootloader cannot load the tri-fat binary, and instead needs to load the Mach-O binary "sdmach".  Although you can manually specify the kernel name on the ROM boot prompt, the disklabel is altered to use "sdmach" instead of "mach_kernel" as the default.

The last set of bytes that need to be changed is a checksum on the disklabel.  NS_CKSUM.C is a very short program that illustrates the checksum calculation.  It reads the bytes in the disklabel preceding the checksum itself, and outputs a 16-bit hexadecimal value to use as the new checksum.  With the updated OPENSTEP 4.2 CD disklabel, the checksum calculated is 0xCE22.

Creating an i386-bootable "User" OPENSTEP CD.

The i386 bootloader is located on the install diskette boot blocks.  This is a copy of the /usr/standalone/i386/boot binary located on the CD.  Additionally, the first 512 bytes of the diskette contains a copy of the /usr/standalone/i386/boot1f binary.  Unlike m68k hardware, i386 hardware does not bootstrap from the first few blocks of the CD.  Instead, i386 hardware makes use of the El Torito specification for bootstrapping from a CD.  The El Torito specification was developed by Phoenix and IBM.  With an El Torito CD, a bootstrap image is loaded by the BIOS.  The bootstrap image can be treated as a diskette in drive "A:".

One limitation in El Torito is that you can only bootstrap a single image.  Although it allows you to select from multiple bootstrap images on the CD, you only bootstrap one of the images ("B:" cannot be mapped to another image in the CD).  You also cannot "swap" images during the El Torito boot process, as required by the OPENSTEP i386 installation process where it asks that you eject the install diskette and insert the driver diskette.

With "mach_kernel" and "sarld", no additional drivers can fit in a 1.44MB install diskette.  The good thing in El Torito is that the bootstrap image can be the image of a 2.88MB diskette.  If we can combine the OPENSTEP install diskette and driver diskette into a single 2.88MB diskette, it can be used to boot from the CD.

There are several ways to create the 2.88MB diskette.  One way is to use an actual 2.88MB SCSI diskette drive and initialize a 2.88MB diskette appropriately, then copy the contents of both OPENSTEP diskettes into the new diskette.  Since I was currently working on a Windows box, I opted to use a virtual machine running OPENSTEP to set up the diskette image.

First, create a 2.88MB file (2,949,120 bytes).  You can use any available utility to create a file of that exact size.  The contents do not matter, since it will be re-initialized from within OPENSTEP.  I tried to mount the 2.88MB file as a virtual floppy drive in VirtualBox.  However, when treated as a floppy drive, the OPENSTEP i386 floppy driver refuses to initialize it as 2.88MB, citing that 1.44MB is the limit.  VirtualBox does not provide a BIOS configuration screen where you can change "A:" into a 2.88MB drive.  Virtual PC 2007 has the BIOS configuration screen, but as reported by others, OPENSTEP installation causes a processor exception in Virtual PC 2007.

The 2.88MB file is mounted as a virtual IDE disk in VirtualBox.  The VMware-format F288.vmdk file is used to describe the virtual disk F288.img as having 160 cylinders, 2 heads, and 18 sectors/track.  IDE sectors are 512 bytes in length, giving a total of 160*2*18*512 = 2.88MB.

Once assigned in VirtualBox running OPENSTEP, the 2.88MB disk is initialized as:

  /usr/etc/disk -i -b -B1 /usr/standalone/i386/boot1f /dev/rhd1a 

The new disk is mounted:

  mkdir /F288 
  mount /dev/hd1a /F288 

And files copied from the install diskette and driver diskettes:

  cp -r /4.2mach_Install/* /F288 
  cp -r /4.2mach_Drivers/* /F288 

Not all the drivers will fit, so some of them should not be copied.  I opted to not copy most of the SCSI drivers, since I will be installing from an IDE/ATAPI CD drive.  The /F288/private/Drivers/i386/System.config/Instance0.table is edited so "Prompt For Driver Disk" is "No".  We now have a 2.88MB "F288.img" file that can be used as the El Torito bootstrap image.

How do we combine the OPENSTEP 4.2 CD, and the 2.88MB bootstrap image into a single El Torito ISO9660 CD?  The OPENSTEP 4.2 CD is not in ISO9660 format.  It is in a variant of the 4.3BSD UFS format.  What’s great in this format is that the UFS filesystem is in a "relative" location in the CD.  In bootblock.h, the disklabel specifies the size (in blocks) of the "front porch" that precedes the actual UFS filesystem.  The "front porch" contains disk housekeeping information and precedes the UFS filesystem.  The raw UFS filesystem can be extracted from the CD image with:

  dd bs=2048 if=OPENSTEP42CD.iso of=OPENSTEP42CD.ufs skip=80

Having "F288.img" and "OPENSTEP42CD.ufs", we fire up our disk-burning application to create an El Toriro CD image.  The ISO9660 filesystem contains only the single OPENSTEP42CD.ufs file.  With the CD image created, we can find that the UFS filesystem got stored starting at offset 0x00360000.

We need to put the same block 0 disklabel into the CD image, but several bytes need to be changed.  The first set of bytes that need to be changed is the size of the "front porch".  Since the UFS filesystem has been moved to offset 0x00360000, the "front porch" value should be 0x06C0 (1728 blocks).  The other set of bytes that need to be changed is the checksum on the disklabel.  With this updated disklabel, the checksum calculated is 0xD492.

The disklabel is again overlayed into the start of the CD image:

  dd bs=1 count=7680 if=OPENSTEP42CD.Block00.ElTorito.lbl of=Disc.iso

Creating an m68k-bootable and i386-bootable OPENSTEP CD.

Extending the concepts further, we can create a CD that is bootable in both m68k and i386 hardware.  The ISO9660 volume descriptors start at offset 0x00008000 (block 16).  32KB is not enough to fit a disk label and an m68k bootloader.  The /usr/standalone/boot.cdrom file is 49812 bytes in size.

For this El Torito CD image, the ISO9660 file system contains the two files boot.cdrom and OPENSTEP42CD.ufs, along with the 2.88MB bootstrap image.  A few changes are in order for the disklabel.  The UFS file system now starts at offset 0x0036C800 of the CD, so the "front porch" value should be 0x06D9 (1753 blocks).  The boot.cdrom image starts at offset 0x0036C000 of the CD.  The first boot block pointer should be 0x06C0, and the second boot block pointer is left as 0xFFFFFFFF.  The new checksum of the disklabel is 0xDB3B.

The disklabel is again overlayed into the start of the CD image:

  dd bs=1 count=7680 if=OPENSTEP42CD.Block00.ElTorito.m68k.lbl of=Disc.iso

With those changes to Disc.iso, the image can be burned to a CD which is bootable in both m68k platforms (as long as you have the latest ROM that allows booting from the CD) and i386 platforms.

Miscellaneous files for download.
This entry was posted in Retrocomputing. Bookmark the permalink.

11 Responses to Creating an OPENSTEP Boot CD

  1. NeXThead says:

    Wow! Great, just great post! Believe it or not I was just banging my head about why the OpenSTEP CDROM/ISO wasn’t bootable (directly, without floppy) on Turbo stations, while the NeXTSTEP was, even without the latest ROM (works w/ 3.0(v68)). So I poked around and chopped and glued with dd (and I also hit the 8192 offset), but no luck. I was also surprised when I saw the SPARC label (I hadn’t tried booting this on a SPARCstation) but didn’t think it would be bootable only on SPARC. Anyhow, you went much further and explain it all so well and in perfect detail (love the historical tidbits too). Good job and thanks for keeping NeXTSTEP/OpenSTEP alive!

  2. t3RRa says:

    Could you state how and with which tool you used to create an El-torito ISO image?
    Was just a ISO9660 data CD with ufs file and el-torito booting with the floppy image?
    or was it something like multi-tracks that people used to make a bootable BeOS CD?
    What changes did you make disklabel file?
    I am asking those questions because I think I could not make ufs file resides at 0x360000.

    Thank you in advance.

  3. t3RRa says:

    OK. I think I have made the image correctly. I have created iso with mkisofs as follows:

    mkisofs -b F288.img -V OPENSTEP_4.2J -hide F288.img -J -R -o test.iso Temp

    Then for me the “front porch” value was 0x5C1 instead of 0x06C0 and the checksum was 0xD393 instead of 0xD492. I have replaced those values in .lbl file located at 0×70 and 0x22E respectively in big-endian. Now it seems it boots up and mounts the ufs partition correctly. (But could not install because I was getting ATA command errors repeatedly and so it would not proceed. oh my.. I will try to test on virtualbox or on a real machine to see if it really works. So far I can see all those files and folders on CD and can run some unix commands when I boots up in single-mode)

  4. pitz says:

    That’s good stuff you’re doing there. Since you’ve been able to boot in single-user mode, then your UFS file system source should be correct. I used a regular Windows-based CD authoring application that has the capability to include an El-Torito diskette image; there wasn’t a need for multi-track capabilities.
    The ATA errors could probably be just an incorrect ATA driver selected during the installation phase.
    Let me know how it goes — I’ll be glad to help out if the authored CD still does not install.

  5. Calvin says:

    VMWare has a BIOS that allows setting drives to 2.88 MB, but I haven’t tested it.

  6. antonio says:

    I tried Your steps to build a startdisk for i386, but the last step to overlay the built ISO don’t really work (on linux). dd creates/overwrite the built ISO and it is only 7,5kB large (??)

    What I’m doing wrong?

    I tried the example from user t3RRa, too. But installation stops at boot(-installer).

    • pitz says:

      @antonio On most Unix/Linux systems, you may need to pass the command-line parameter conv=notrunc to the dd command in order to overlay parts of a file without truncating the output file.

  7. Abrahan says:

    Your disk image includes the vesa video driver??

  8. pitz says:

    @Abrahan No, it doesn’t. The VESA video driver can subsequently be installed from the OPENSTEP PATCH4 CD or ISO image.

  9. Stuart Duncan says:

    Hi there, I think I’m missing something. How exactly do I find the offset of the UFS start and the checksum. I scanned the header file referenced but maybe it’s just over my head.

    • pitz says:

      The UFS file system blocks are just right after the front porch. In this CD, the front porch is 80 blocks * 2048 bytes/block, so the UFS blocks start at byte offset 163840 from the beginning of the CD image.
      The checksum is just the running sum of each 16-bit big-endian value of the disklabel structure (of length 560), excluding the checksum itself.

Leave a Reply

Your email address will not be published. Required fields are marked *