Mac OS X is the only operating system in my iBook and I have no plans to change this in the near future (installing NetBSD was frustrating and I do not want Linux). However, I want to be able to do NetBSD development on it shall the need arise. And it has to be easy.

My idea was to have a disk image with NetBSD/i386 on it and to be able to mount it from OS X to manage its contents (e.g. to update its kernel or to install new userland). Therefore, installing on a Apple UFS file system was a must. NetBSD can read such file systems but unfortunately it cannot boot from them (as far as I know); hence the need for a little boot FAT partition (see below).

As a result I have got a NetBSD/i386 installation under Q, completely manageable from OS X. The overall setup renders a very nice development environment.

Let's see how (not exactly trivial):
  1. Get NetBSD sources on your OS X machine.
  2. Build a cross-compiler toolchain for i386, which basically means ./build.sh -m i386 tools. Doesn't build.sh rock?
  3. Prepare a custom i386 kernel configuration and build it. You can simply get GENERIC, but you must enable options APPLE_UFS as well as options FFS_EI (thanks to Rudi Ludwig for pointing the latter out). Do not disable file-system MSDOS.
  4. Create a new PC under Q and specify a new 512MB raw disk image (qcow will not work).
  5. Use the command line fdisk utility to partition the new image: create a 50MB FAT16 partition (type 6) and leave the rest for Apple UFS (type 168). You may have geometry problems here as fdisk will think that the disk is extremely large; for the 512MB disk we just created, use 1040 cylinders, 16 heads and 63 sectors per track (you can give this to fdisk as parameters).
  6. The disk created by Q is stored in ~/Documents/QEMU/pcname.qvm/Harddisk_1.raw; I will refer to it as disk.img for simplicity. Tell OS X to attach it: hdiutil attach -nomount disk.img.
  7. Format the new partitions. WARNING: OS X attaches this as disk1 for me; check the device name in your machine before proceeding and adjust it accordingly. Simply do: newfs_msdos /dev/disk1s1 and newfs /dev/disk1s2.
  8. Detach the image and reattach it, but this time let OS X mount the file systems within them: hdiutil detach disk1 ; hdiutil attach disk.img.
  9. Use the finder to rename the partitions to more representative names. E.g. NB-Boot and NB-Root.
Now it's time to install NetBSD under the new disk. We need to do this manually. Assume that all of the following commands are run from within /Volumes/NB-Root:
  1. Unpack the NetBSD sets by doing: for f in ~/NetBSD/i386/binary/sets/[bcegmt]*.tgz; do sudo tar xzpf $f; done.
  2. Create the device files in dev by executing the following: cd dev && sudo ./MAKEDEV -m ${TOOLDIR}/bin/nbmknod all. TOOLDIR points to the directory holding the cross tools you built before.
  3. Create a minimal etc/fstab. E.g.:
    /dev/wd0f / ffs rw 1 2
    /dev/wd0e /boot msdos ro,-l 0 0
  4. Create the boot directory. This clashes with the standard /boot file in a NetBSD system, but we will not have this one; feel free to use a different name.
  5. Edit etc/gettytab and add al=root to the default entry. This will automatically log into root's session, so we do not need to set a password for it.
  6. Edit rc.conf and set rc_configured=YES. Disable all the services you will not use for better boot up speed: cron=NO inetd=NO sendmail=NO virecover=NO wscons=YES. Do not forget to set the host name: hostname=devel.
  7. Edit wscons.conf and disable all extra screens.
  8. Create links that will point to the kernels: ln -s boot/netbsd boot and ln -s boot/netbsd.gdb. This is the reason why my boot partition is 50MB; the debugging kernels take a lot of space.
At last, we need to install the boot loader in the FAT partition. I've chosen GRUB so I needed a GRUB boot floppy (an image) at hand to finish the setup.
  1. Mount the GRUB image and copy its files to the boot partition. E.g.: cp -rf /Volumes/GRUB/boot /Volumes/NB-Boot. You need the fat_stage1_5 file for this to work.
  2. Create a minimal /Volumes/GRUB/boot/grub/menu.lst file for automatic booting:
    default 0
    timeout 5
    title NetBSD - Development kernel
    kernel (hd0,0)/netbsd root=wd0f
  3. Copy the kernel you built at the beginning to /Volumes/GRUB/netbsd.
  4. Detach all the disk images: hdiutil detach disk1 and hdiutil detach disk2.
  5. Configure your virtual PC in Q to boot from this GRUB floppy disk image and embed GRUB into your virtual hard disk: root (hd0,0) and setup (hd0).
  6. Change Q's configuration to boot straight from the hard disk image.
And at last... Boot NetBSD!

With this setup you can mount your development image with hdiutil attach disk.img, mess as you want with its contents, detach it and relaunch your Q session. Pretty neat :-)