HOWTO Create A Bootable USB Drive From An ISO Image For Apple PowerPCs In Linux

HOWTO Create A Bootable USB Drive From An ISO Image For Apple PowerPCs In Linux

Creating a bootable USB drive for the Apple PowerPCs is complicated due to the fact that they use Apple's HFS (Hierarchical File System) as its native file system. But with the help of some special tools available on PowerPC Linux, construction of bootable drives is possible. Here is how it's done.

Your Mileage May Vary

I have a PowerBook G4 running Xubuntu 10.04 and I will be using a 1 GB USB drive. This means that while the information is accurate for this hardware but you may have to adapt it to your circumstances.

I used the UNIX convention of the user prompt as '$ ' and the root prompt as '# '. The prompt that you see may differ from this so make adjustments for it.

I have expanded many of the directories in the commands. This is to make clear what they're are. A isolated period for the current directory is hard to spot, so I wrote it as the longer version. You may, of course, use the shortest version to save typing.

Create A Working Directory

The first step is to create a place to work. Open a terminal and create a directory to work in.

  $ mkdir ~/liveusb
  $ cd ~/liveusb

We going to need two mount points. In Linux, a mount point is simply a directory, so:

  $ mkdir ./iso
  $ mkdir ./usb

Open your browser and download the ISO image of Linux you want to use. My browser puts it in the Downloads directory. Move the ISO image to your working directory.

  $ mv ~/Downloads/xubuntu-10.04-desktop-powerpc.iso ~/liveusb

Working As root

To create the drive, it is necessary to work as root. Use sudo to start a shell as root.

  $ sudo -s
  [sudo] password for userid:
  #

Determining The Serial Drive Of The USB

When you plug a USB device into the computer, the Linux OS assigns it a serial device number and creates an entry for it in the /dev directory. These devices are given a file name in the form of /dev/sd? where the ? is a lowercase letter starting with a.

To determine which file is the USB drive, before you plug it in do:

  # ls /dev/sd?

This gives you a list of all the existing serial drives. Now plug it in and repeat the above command. The new one is the one for the USB drive. Write it down; you'll need it later.

Note: For the following examples, I'll be using /dev/sda. Change this to the device you discovered here.

If any window opened when you plugged in the drive, close them all. Also, if any partition was mounted, unmount it. You can tell if any are mounted with this command:

  # mount | column -t
  /dev/hda3  on  /                         type  ext4        (rw,errors=remount-ro)
  proc       on  /proc                     type  proc        (rw,noexec,nosuid,nodev)
  none       on  /sys                      type  sysfs       (rw,noexec,nosuid,nodev)
  none       on  /sys/fs/fuse/connections  type  fusectl     (rw)
  none       on  /sys/kernel/debug         type  debugfs     (rw)
  none       on  /sys/kernel/security      type  securityfs  (rw)
  none       on  /dev                      type  devtmpfs    (rw,mode=0755)
  none       on  /dev/pts                  type  devpts      (rw,noexec,nosuid,gid=5,mode=0620)
  none       on  /dev/shm                  type  tmpfs       (rw,nosuid,nodev)
  none       on  /var/run                  type  tmpfs       (rw,nosuid,mode=0755)
  none       on  /var/lock                 type  tmpfs       (rw,noexec,nosuid,nodev)
  none       on  /lib/init/rw              type  tmpfs       (rw,nosuid,mode=0755)
  /dev/hda6  on  /home                     type  ext4        (rw)
  /dev/hda5  on  /usr                      type  ext4        (rw)
  /dev/sda2  on  /media/disk               type  ext3        (rw,nosuid,nodev,uhelper=hal)

As you can see, the partition /dev/sda2, which is part of /dev/sda is mounted. To unmount it:

  # umount /dev/sda?

If it doesn't complain, it worked.

Partitioning The USB Drive

Warning: This step will destroy any data on the USB drive.

The drive must be partitioned in HFS. The utility mac-fdisk does this.

  # mac-fdisk /dev/sda
  /dev/sda
  Command (? for help):

The first step is to initialize a new map. Use the i command for this.

  Command (? for help): i
  map already exists
  do you want to reinit? [n/y]: y
  size of 'device' is 2015232 blocks:
  new size of 'device' is 2015232 blocks
  Command (? for help):

If a map already exists, which is likely, answer y to reinitialize it. When asked for it size, just press RETURN for the default which is the maximum size.

Now, take a look at the map; use the p command for this. You'll be using this command to get the first block of the remaining partitions. They're listing under the column called base.

  Command (? for help): p
  /dev/sda
          #                    type name                length   base    ( size )  system
  /dev/sda1     Apple_partition_map Apple                   63 @ 1       ( 31.5k)  Partition map
  /dev/sda2              Apple_Free Extra              2015168 @ 64      (984.0M)  Free space

  Block size=512, Number of Blocks=2015232
  DeviceType=0x0, DeviceId=0x0

  Command (? for help):

Now create the bootstrap partition with the b command. Use the base of the /dev/sda2 as its first block.

  Command (? for help): b
  First block: 64
  Command (? for help): p
  /dev/sda
          #                    type name                length   base    ( size )  system
  /dev/sda1     Apple_partition_map Apple                   63 @ 1       ( 31.5k)  Partition map
  /dev/sda2         Apple_Bootstrap bootstrap             1600 @ 64      (800.0k)  NewWorld bootblock
  /dev/sda3              Apple_Free Extra              2013568 @ 1664    (983.2M)  Free space

  Block size=512, Number of Blocks=2015232
  DeviceType=0x0, DeviceId=0x0

  Command (? for help):

The remainder of the drive will be used to hold the files from the ISO image. We will create a Linux partition for that. Use to c command to do this. Copy & paste the base and length for the first block and length. I used the name "xubuntu" for the partition but you can use any you like, or leave it blank.

  Command (? for help): c
  First block: 1664
  Length (in blocks, kB (k), MB (M) or GB (G)): 2013568
  Name of partition: xubuntu
  Command (? for help): p
  /dev/sda
          #                    type name                length   base    ( size )  system
  /dev/sda1     Apple_partition_map Apple                   63 @ 1       ( 31.5k)  Partition map
  /dev/sda2         Apple_Bootstrap bootstrap             1600 @ 64      (800.0k)  NewWorld bootblock
  /dev/sda3         Apple_UNIX_SVR2 xubuntu            2013568 @ 1664    (983.2M)  Linux native

  Block size=512, Number of Blocks=2015232
  DeviceType=0x0, DeviceId=0x0

  Command (? for help):

Now write the map to the drive with the w command. Answer y to the question.

  Command (? for help): w
  IMPORTANT: You are about to write a changed partition map to disk. 
  For any partition you changed the start or size of, writing out 
  the map causes all data on that partition to be LOST FOREVER. 
  Make sure you have a backup of any data on such partitions you 
  want to keep before answering 'yes' to the question below!

  Write partition map? [n/y]: y
  The partition map has been saved successfully!

  Syncing disks.

  Partition map written to disk. If any partitions on this disk 
  were still in use by the system (see messages above), you will need 
  to reboot in order to utilize the new partition map.

  Command (? for help):

Finally, quit with q.

  Command (? for help): q
  #

Note: Your system might automatically mount the partitions. If it does, unmount them.

  # umount /dev/sda?

Listing The Partitions

You can list the partition on the device at anytime with the -l option of mac-fdisk. This will come in handy when mounting the partitions.

  # mac-fdisk -l /dev/sda
  /dev/sda
          #                    type name                length   base    ( size )  system
  /dev/sda1     Apple_partition_map Apple                   63 @ 1       ( 31.5k)  Partition map
  /dev/sda2         Apple_Bootstrap bootstrap             1600 @ 64      (800.0k)  NewWorld bootblock
  /dev/sda3         Apple_UNIX_SVR2 xubuntu            2013568 @ 1664    (983.2M)  Linux native

  Block size=512, Number of Blocks=2015232
  DeviceType=0x0, DeviceId=0x0

Creating A File System

A file system has to be created on the partition. I choose to make it ext2 since this does not require the access time to be updated every time a file is read.

  # mkfs -v -t ext2 -L 'xubuntu-10.04' /dev/sda3

The -v is for verbose output. Since this takes some time, this tells you what is happening. The -L option allows you to name the file system. Leave it out if you don't want to.

Loading The ISO Files

Note: This could take a long, long time, like 20-30 minutes. Also, the computer is doing a lot of I/O, so it may not be very responsive to anything you do, like move the mouse. My advice: go for coffee.

Mount the USB drive.

  # mount /dev/sda3 ./usb

Mount the ISO file as a file system.

  # mount -t iso9660 -o ro,loop=/dev/loop0 ./xubuntu-10.04-desktop-powerpc.iso ./iso

Now, load the ISO files to the device.

  # (cd ./iso ; tar cBpf - .) | (cd ./usb ; tar xvBpf -)

This command is complicated but can be broken down. This parenthesis groups the commands. The pipe, '|' tells it to pipe the stdout of the first group to the stdin of the second.

The first command of the first group changes the directory to the ISO image. It then runs the Tape ARchiver (tar) in the directory. The c option means to create a new archive. The B option means to read full records; this makes it go as fast as it can. The p option preserves permissions. The f option means the name of the archive follows. This this case, it's a minus sign, which means it will sent its archive to stdout, which becomes the stdin of the second group. And finally, the period means start in the current working directory, which is ./iso.

The first command of the second group changes the directory to ./usb, our USB drive. Then another tar takes over. The x option means to extract the files from the archive in stdin. The v option means verbose: list the files as they are extracted. The rest of the options are as above but the minus sign means to read the archive from stdin.

The computer may be ready for more commands before all the bytes are written. This is because the low-level writes are buffered. It may be a while until it responds to your next command.

Now, get a copy of the bootloader, yaboot, and its configuration file.

  # cp ./iso/install/yaboot ./iso/install/yaboot.conf ~/liveusb
  # chmod +w yaboot.conf
  # umount ./iso
  # umount ./usb

The chmod command makes the configuration file writable.

Formatting The Bootstrap Partition

The bootstrap partition must be formatted before it can be used. Use the hformat utility for this.

  # hformat -l LiveUSB /dev/sda2

The -l option allows you to give a label to the volume. Leave it out if you want it unnamed.

Loading The Bootstrap Partition

The bootloader for Linux devices on the PowerPC is yaboot. It has to be loaded into the bootstrap partition and its attributes set. To do these, the volume must be mounted. Here is the sequence of commands to do this; all of them are special utilities for dealing with HFS.

  # hmount /dev/sda2
  # hcopy -r yaboot :
  # hattrib -c UNIX -t tbxi :yaboot
  # hattrib -b :
  # humount

The hmount command mounts the partition so the other commands can work with it. The hcopy command copies the yaboot program to the USB drive. Its -r option means copy raw; no conversion takes place. The colon is the HFS root directory. HFS uses colons where Linux uses slashes. The first hattrib commands sets the attributes of the yaboot program. The tbxi code is a special code used by Apple to signify that the program is the bootloader program. There should be only one of these on a device. The second hattrib commands blesses the root directory. I'm not sure what this means but it is required for the device to boot. Finally, the humount dismounts the partition.

Configuring The Bootstrap

The yaboot bootloader is configured by the yaboot.conf file. It has two parts: a header and a list of images. The image section behinds with the first image= option. Open the yaboot.conf file in your favourite text editor and find the image section. Delete everything before it. (OK, you can keep the comments.) In their place, insert this:

  root=/dev/ram
  partition=3
  message=/install/boot.msg
  default=live

The root option tells where the root directory will be mounted, in this case, RAM. The partition option says that all the images are in the third partition of the device. The message is the message yaboot will display at the start of the boot process. More on this later.

Save the changes and exit the editor.

Now, load the yaboot.conf file with the following.

  # mount /dev/sda2 ./usb
  # cp ./yaboot.conf ./usb
  # umount ./usb

Changing The Boot Message (Optional)

First, mount the partition.

  # mount /dev/sda3 ./usb

Create a local copy and change it.

  # cp ./usb/install/boot.msg ~/liveusb
  # chmod +w ./boot.msg

Open it in your favourite text editor and change it to what you like. Save it and exit the editor. Now, load it on the device.

  # cp ./boot.msg ./usb/install
  # umount ./usb

All Done

The USB drive is now ready for use. The last thing to do is exit the sudo shell.

  # exit
  $

Creating A Bootable USB Drive From A X86 Machine In Linux

You will need two things to create a LiveUSB drive from a Linux/Intel machine.

The first is mac-fdisk. I don't not know if a binary for this exists but you can download the source and compile it. One downlaod site is the mac-fdisk source at Debian.

The other item you will need is hfsutils. This is available as a binary and can be downloaded using your package manager.


Original Author

Shawn H Corey <SHCOREY at cpan.org>

Contributing Authors

(Insert your name here if you modified this documentation. Do not remove this comment.)


Acknowledgements

Thanks to Skeeve42 at Ubuntu forums for his pointers.

Thanks to OSXbook.com for their insights on Open Firmware works.

Thanks to homey at LinuxQuestions.org for the mount ISO command.

Thanks to Sergio Hernandez for pointing out the hfsutils to me.


Copyright & Licences

Copyright 2010 by Shawn H Corey. All rights reserved.

Document Licence

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with the Invariant Sections being Original Author, Copyright & Licences, and Document Licence.

Comments