This is blah of Tuomas Jormola. Blah is not a blog.

RSS Atom Add a new post titled:

Introduction

Here I document how I build a working Preboot.dmg for running Mac OS X 10.6 Snow Leopard on a HP xw4600 Workstation[1].

Not everything works out of the box, though. The onboard Broadcom NIC doesn’t work with drivers by Apple. It might be possible to make the vanilla AppleBCM5701Ethernet.kext driver work with the onboard NIC, but that would be quite messy and would probably break when updating the operating system. So I installed a card with RTL8111C chip instead. This ~10€ NIC is auto-detected and works great with Apple drivers. Also onboard audio doesn’t work by default, but I got it working with an alternative driver that is easy to install.

Detailed hardware configuration:

  • HP xw4600 Workstation, BIOS 1.21
  • Intel Core 2 Quad Q9450 processor
  • 4x 1GB Micron 1RX8 PC2-6400E-666-12-F0
  • Club 3D CGNX-GTS866 NVIDIA GeForce 8600 GTS graphics card
  • TP-LINK TG-3468 PCI-Express x1 NIC

Kernel extensions

Besides the mandatory kernel extensions I’m including the PS2 driver ApplePS2Controller.kext. It’s useful if no DSDT patches are applied and thus USB keyboard and mouse aren’t working. See more at Create preboot image for Chameleon bootloader.

DSDT patches

The following patches are needed in order to make USB and sleep work. More about DSDT patching at Create preboot image for Chameleon bootloader.

Enable device data insertion

The USB patch below requires the DTGP method, which is added by this patch.

--- dsdt.dsl.orig      2010-12-02 20:58:39.000000000 +0200
+++ dsdt.dsl       2010-12-02 21:02:16.000000000 +0200
@@ -7394,4 +7394,34 @@
             \OSFG ()
         }
     }
+    Method (DTGP, 5, NotSerialized)
+    {
+        If (LEqual (Arg0, Buffer (0x10)
+                {
+                    /* 0000 */    0xC6, 0xB7, 0xB5, 0xA0, 0x18, 0x13, 0x1C, 0x44, 
+                    /* 0008 */    0xB0, 0xC9, 0xFE, 0x69, 0x5E, 0xAF, 0x94, 0x9B
+                }))
+        {
+            If (LEqual (Arg1, One))
+            {
+                If (LEqual (Arg2, Zero))
+                {
+                    Store (Buffer (One)
+                        {
+                            0x03
+                        }, Arg4)
+                    Return (One)
+                }
+                If (LEqual (Arg2, One))
+                {
+                    Return (One)
+                }
+            }
+        }
+        Store (Buffer (One)
+            {
+                0x00
+            }, Arg4)
+        Return (Zero)
+    }
 }

Download patch

IRQ conflicts

By default USB doesn’t work because HPET device is using IRQs that conflict with USB[2]. This patch fixes the issue by removing IRQs from PIC, RTC, and TIME devices and defines IRQs for the HPET device.

--- dsdt.dsl.orig      2010-12-02 20:58:39.000000000 +0200
+++ dsdt.dsl       2010-12-02 21:09:25.000000000 +0200
@@ -2625,8 +2625,6 @@
                     0x00,               // Alignment
                     0x20,               // Length
                     )
-                IRQNoFlags ()
-                    {2}
             })
         }
     }
@@ -2643,8 +2641,6 @@
                     0x00,               // Alignment
                     0x04,               // Length
                     )
-                IRQNoFlags ()
-                    {0}
             })
         }
     }
@@ -2691,8 +2687,6 @@
                     0x00,               // Alignment
                     0x02,               // Length
                     )
-                IRQNoFlags ()
-                    {8}
             })
         }
     }
@@ -7348,6 +7342,10 @@
             Name (_UID, 0x01)
             Name (CRES, ResourceTemplate ()
             {
+                IRQNoFlags ()
+                    {0}
+                IRQNoFlags ()
+                    {8}
                 Memory32Fixed (ReadWrite,
                     0x00000000,         // Address Base
                     0x00000000,         // Address Length

Download patch

USB

This patch fixes USB controller so that sleep works[3].

--- dsdt.dsl.orig      2010-12-03 00:17:14.000000000 +0200
+++ dsdt.dsl       2010-12-03 00:19:10.000000000 +0200
@@ -1797,6 +1797,24 @@
                 {
                     Return (0x03)
                 }
+                Method (_DSM, 4, NotSerialized)
+                {
+                    Store (Package (0x02)
+                        {
+                            "device-id", 
+                            Buffer (0x04)
+                            {
+                                0x34, 0x3A, 0x00, 0x00
+                            },
+                            "AAPL,clock-id",
+                            Buffer (0x01)
+                            {
+                                0x0A
+                            }
+                        }, Local0)
+                    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
+                    Return (Local0)
+                }
             }
             Device (USB2)
             {
@@ -1822,6 +1840,24 @@
                 {
                     Return (0x03)
                 }
+                Method (_DSM, 4, NotSerialized)
+                {
+                    Store (Package (0x02)
+                        {
+                            "device-id", 
+                            Buffer (0x04)
+                            {
+                                0x35, 0x3A, 0x00, 0x00
+                            },
+                            "AAPL,clock-id",
+                            Buffer (0x01)
+                            {
+                                0x0A
+                            }
+                        }, Local0)
+                    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
+                    Return (Local0)
+                }
             }
             Device (USB3)
             {
@@ -1847,6 +1883,24 @@
                 {
                     Return (0x03)
                 }
+                Method (_DSM, 4, NotSerialized)
+                {
+                    Store (Package (0x02)
+                        {
+                            "device-id", 
+                            Buffer (0x04)
+                            {
+                                0x36, 0x3A, 0x00, 0x00
+                            },
+                            "AAPL,clock-id",
+                            Buffer (0x01)
+                            {
+                                0x0A
+                            }
+                        }, Local0)
+                    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
+                    Return (Local0)
+                }
             }
             Device (USB4)
             {
@@ -1872,6 +1926,24 @@
                 {
                     Return (0x03)
                 }
+                Method (_DSM, 4, NotSerialized)
+                {
+                    Store (Package (0x02)
+                        {
+                            "device-id", 
+                            Buffer (0x04)
+                            {
+                                0x37, 0x3A, 0x00, 0x00
+                            },
+                            "AAPL,clock-id",
+                            Buffer (0x01)
+                            {
+                                0x0A
+                            }
+                        }, Local0)
+                    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
+                    Return (Local0)
+                }
             }
             Device (USB5)
             {
@@ -1897,6 +1969,24 @@
                 {
                     Return (0x03)
                 }
+                Method (_DSM, 4, NotSerialized)
+                {
+                    Store (Package (0x02)
+                        {
+                            "device-id", 
+                            Buffer (0x04)
+                            {
+                                0x38, 0x3A, 0x00, 0x00
+                            },
+                            "AAPL,clock-id",
+                            Buffer (0x01)
+                            {
+                                0x0A
+                            }
+                        }, Local0)
+                    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
+                    Return (Local0)
+                }
             }
             Device (USB6)
             {
@@ -1922,6 +2012,24 @@
                 {
                     Return (0x03)
                 }
+                Method (_DSM, 4, NotSerialized)
+                {
+                    Store (Package (0x02)
+                        {
+                            "device-id", 
+                            Buffer (0x04)
+                            {
+                                0x39, 0x3A, 0x00, 0x00
+                            },
+                            "AAPL,clock-id",
+                            Buffer (0x01)
+                            {
+                                0x0A
+                            }
+                        }, Local0)
+                    DTGP (Arg0, Arg1, Arg2, Arg3, RefOf (Local0))
+                    Return (Local0)
+                }
             }
             Device (EUS1)
             {

Download patch

Audio

I used VoodooHDA[4] driver to get the onboard audio work. Installer package VoodooHDA-2.7.2.pkg.zip was used.

SMBIOS

I use the following smbios.plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>SMserial</key>
    <string>WRKDA2FSDMN</string>
    <key>SMbiosvendor</key>
    <string>HP</string>
    <key>SMbiosversion</key>
    <string>1.21 Rev. a</string>
    <key>SMbiosdate</key>
    <string>02/19/2010</string>
    <key>SMmanufacturer</key>
    <string>HP</string>
    <key>SMproductname</key>
    <string>xw4600</string>
    <key>SMmemtype</key>
    <string>19</string>
    <key>SMmemspeed</key>
    <string>800</string>
    <key>SMmemmanufacter</key>
    <string>Micron</string>
    <key>SMmempart_1</key>
    <string>1RX8 PC2-6400E-666-12-F0</string>
    <key>SMmempart_2</key>
    <string>1RX8 PC2-6400E-666-12-F0</string>
    <key>SMmempart_3</key>
    <string>1RX8 PC2-6400E-666-12-F0</string>
    <key>SMmempart_4</key>
    <string>1RX8 PC2-6400E-666-12-F0</string>
</dict>
</plist>

Boot configuration

This is the com.apple.Boot.plist for the machine.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Kernel</key>
    <string>mach_kernel</string>
    <key>Kernel Flags</key>
    <string></string>
    <key>GraphicsEnabler</key>
    <string>Yes</string>
    <key>Legacy Logo</key>
    <string>Yes</string>
    <key>Quiet Boot</key>
    <string>Yes</string>
    <key>GUI</key>
    <string>No</string>
    <key>Scan Single Drive</key>
    <string>Yes</string>
</dict>
</plist>

References

Posted 2010-12-03T01:06:45 EET Tags:

This page serves as the reference list of software that I may want to install on a clean system running Mac OS X.

Networking

Media

Other applications and utilities

Posted 2010-05-20T15:45:19 EEST Tags:

Introduction

This posting documents how I configured triple boot environment of Ubuntu 9.10 karmic, Mac OS X 10.6 and Windows 7 on one of my machines. All operating systems are installed on a single physical disk. Grub 2[1] boot loader installed by Ubuntu will be used as the primary boot loader. Grub will be then used to boot Chameleon[2] boot loader which boots Mac OS X. Grub boots Ubuntu’s Linux kernel directly and Windows by chain-loading the Windows boot loader from the Windows partition.

Partitioning the disk

Partitioning the disk causes headache and requires some tweaking as we have to install both GUID Partition Table[3] and Master Boot Record Partition Table[4] on the same disk. Mac OS X only supports system disks with GPT. But Windows doesn’t support booting from a disk with GPT[5]. Ubuntu is happy to boot from disks paritioned using both GPT and MBR. Thus we have to create hybrid GPT/MBR boot record[6].

We’re going to do the initial partitioning of the system disk from within Mac OS X installer environment using diskutil(8)[7] tool. Follow the instructions in the posting Create Mac OS X 10.6 Snow Leopard USB installation media for Hackintosh and create bootable Mac OS X installer USB media that works with your system. Of course if your system boots with the retail Mac OS X DVD, you can use that too.

Next we have to decide the partition table layout. When installing Grub 2 on a disk with GPT, it’s recommended to have BIOS Boot Partition[8],[9]. With the hybrid partition table in place, you’re limited to only 4 partitions that are available to Windows. And two of these partitions are reserved (EFI Partition and BIOS Boot Partition) so you only have 2 primary partitions to configure at your will. Also it’ll be difficult to work with the partitioning after we’ve finished with the installations and gotten everything to work so it’s better to do good initial planning.

Ubuntu 9.10 karmic and later install Grub 2 that is capable of handling LVM. Since we’re going to install Ubuntu on logical volume(s), there’s not need for a separate partition for /boot file system. That’s great!

I partitioned my 600GB disk as follows:

  • Partition 1: 200MB HFS+ volume labeled EFI. This is created automatically when partitioning the disk with diskutil(8)[7]. Chameleon boot loader code and support files are also installed on this volume. This way there’s no need to do any customization to the Mac OS X volume described below.
  • Partition 2: 2MB volume for the BIOS Boot Partition. Used by Grub.
  • Partition 3: 150GB NTFS volume for Windows.
  • Partition 4: 50GB Physical volume for volume group managed by LVM. The volume group will house the Ubuntu installation.
  • Partition 5: 100GB Mac OS X system volume labeled Hackintosh HD for the operating system, applications and user home directories.
  • Partition 6: ~300GB HFS+ volume labeled Video for video archive and scratch space used during editing of home videos.

To partition the disk boot Mac OS X installer and launch Terminal.app from the Utilities menu. First identify the system disk.

    -bash-3.2# diskutil list

In my system the system disk is /dev/disk7. Then I partitioned the disk using the following command.

    -bash-3.2# diskutil partitionDisk /dev/disk7 GPT \
        "MS-DOS FAT32" %noformat% 2M \
        "MS-DOS FAT32" %noformat% 150G \
        "MS-DOS FAT32" %noformat% 50G \
        "Journaled HFS+" "Hackintosh HD" 100G \
        "Journaled HFS+" Video 0b

As noted above, this will create total of six partitions. In addition to the five partitions listed above, the 200MB EFI partition is automatically created by diskutil(8)[7] as the first partition of the disk. I marked the Windows, Linux and BIOS boot partitions temporarily as FAT32 so that the space gets allocated for these partitions. The Windows partition will be formatted as NTFS when installing Windows 7, the Linux partition will be added to the volume group when installing Ubuntu and Grub installer will use the BIOS boot partition.

Installing Chameleon boot loader

The empty, just partitioned hard disk is not bootable and won’t be even after installing Mac OS X in the next step. But we can copy Chameleon boot loader and its configuration from the Mac OS X USB installer to the system disk. See my guide for more details about Chameleon. These steps assume that the Mac OS X installer was created like documented in that posting. While still in the Mac OS X installer with Terminal.app running, execute the following commands.

  1. Create HFS+ file system on the EFI volume and mount it.

    -bash-3.2# newfs_hfs -v EFI /dev/disk7s1
    -bash-3.2# mkdir /Volumes/EFI
    -bash-3.2# mount_hfs /dev/disk7s1 /Volumes/EFI
    
    
  2. Mark the EFI file system so that fseventsd doesn’t keep any logs there.

    -bash-3.2# mkdir /Volumes/EFI/.fseventsd
    -bash-3.2# touch /Volumes/EFI/.fseventsd/no_log
    -bash-3.2# chmod -R g-rwx,o-rwx /Volumes/EFI/.fseventsd
    -bash-3.2# chown -R root:admin /Volumes/EFI/.fseventsd
    
    
  3. Copy the Chameleon boot loader binaries to the root of the EFI volume. You really need the boot file, which is the last stage of Chameleon boot system and contains bulk of the Chameleon code, but it’s a good idea to have the images of the first stages at hand, too.

    -bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot /Volumes/EFI
    -bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot0 /Volumes/EFI
    -bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot1h /Volumes/EFI
    
    
  4. Copy Chameleon support file directory Extra to the EFI volume.

    -bash-3.2# ditto /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/Extra /Volumes/EFI/Extra
    
    
  5. Unmount the EFI volume.

    -bash-3.2# umount /dev/disk7s1
    -bash-3.2# rmdir /Volumes/EFI
    
    
  6. Eject the system disk so that you can write to the block device file in the next step.

    -bash-3.2# diskutil eject /dev/disk7
    
    
  7. Now you can copy the Chameleon initial boot code from the installer file system to the Master Boot Record at the beginning of the system disk.

    -bash-3.2# dd if=/Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot0 of=/dev/disk7 bs=440 count=1
    
    
  8. Then copy the Chameleon 2nd stage boot code from the installer file system to the beginning of the EFI partition.

    -bash-3.2# dd if=/Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/boot1h of=/dev/disk7s1
    
    
  9. Bootloader installation is now ready. Mount the Mac OS X volume so you can install Mac OS X onto it.

    -bash-3.2# diskutil mount /dev/disk7s5
    
    
  10. Finally, quit Terminal.app.

Installing Mac OS X 10.6 Snow Leopard

Go ahead and install Mac OS X normally on the Mac OS X volume (Hackintosh HD). After the installation is finished, the machine should boot to Mac OS X as we installed the Chameleon boot loader to the Master Boot Record and support files to the EFI partition in the previous steps. It’s a good idea to create backups of the Master Boot Record of the system disk at this stage so you can revert back if needed. You can use e.g. dd(1)[10] in Mac OS X installer shell.

    -bash-3.2# dd if=/dev/disk7 of=/Volumes/BackupVolume/mbr-backup bs=512 count=1

Installing Windows 7

When the system disk was partitioned above with diskutil(8)[7], it also created the hybrid GUID/MBR partition table. You can now boot Windows 7 installer and format the partition dedicated to Windows as NTFS. Proceed to install Windows on this partition. After Windows is installed, the machine now boots Windows as the Windows installer replaced Chameleon boot code in the Master Boot Record with its own boot code. No need to worry, we’ll get Mac OS X back after installing Ubuntu and configuring Grub.

Installing Ubuntu 9.10 karmic

Use Ubuntu alternate installer[11]. Boot the installer and proceed to the disk partitioning step. Choose manual partitioning and create a volume group to the partition dedicated to Ubuntu, create required volumes and install Ubuntu there. When the installer prompts for boot loader device installation, don’t answer yet but switch to the console (Alt-F2). We need to activate the BIOS Boot Partition first. In the following setup /dev/sda is the physical system disk.

  1. Mount the special file systems at the target file system.

    ~ # mount -o bind /dev /target/dev
    ~ # mount -o bind /sys /target/sys
    ~ # mount -o bind /proc /target/proc
    
    
  2. Enable BIOS Boot Partition using parted(1)[12].

    ~ # chroot /target parted /dev/sda set 2 bios_grub on
    
    
  3. Unmount the special file systems at the target file system.

    ~ # umount /target/dev
    ~ # umount /target/sys
    ~ # umount /target/proc
    
    

Now switch back to the installer virtual console (Alt-F1) and input the system disk block device name /dev/sda and finish with Ubuntu installation.

Restoring hybrid partition table

After installing Ubuntu, you should be able to boot it using Grub. However, Ubuntu installer and parted(1) have destroyed the hybrid GPT/MBR partition table. But we can fix that using the gptsync(1) tool which is part of the rEFIt[13]. gptsync package is available for Ubuntu[14], but unfortunately the version in karmic is too old to support BIOS Boot Partitions[15]. This has been fixed in the version 0.13-4 of the package. Until there’s a working version of gptsync package in Ubuntu, you can use the package from Debian[16]. When you have a version of gptsync(1) installed which supports BIOS Boot Partitions, go ahead and re-create the hybrid partition table.

    ~$ sudo gptsync /dev/sda

Updating Grub boot menu

Ubuntu installer should detect the Windows 7 installation and create a Grub menu entry for it. It’ll also detect the Mac OS X installation and create menu entry for that, too. However, that is no good to us since it uses Grub’s native Mach kernel loading facilities[17] but we want to use Chameleon to boot Mac OS X.

So let’s create a custom menu entry that will boot Chameleon. Save the following script as /etc/grub.d/99_local_chameleon and set it executable.

#!/bin/sh

cat <<END_OF_MENU_ENTRY
menuentry "Mac OS X via Chameleon" {
        insmod hfsplus
        set root=(hd0,1)
        multiboot /boot
}
END_OF_MENU_ENTRY

Download script

    ~$ sudo chmod 755 /etc/grub.d/99_local_chameleon

And update the Grub configuration.

    ~$ sudo update-grub

Now you should have Grub menu from which you can choose whether to boot Ubuntu, Mac OS X or Windows.

Fixing Windows

Unfortunately, partition changes related to Ubuntu installation breaks Windows on my machine. When trying to boot Windows, I get Windows Boot Manager error screen with status 0xc00000e. To fix this, boot to Windows Recovery Environment and start Command Prompt. With Windows 7 retail DVD in hand, boot it, choose your language and locale settings and choose Repair your computer. If the Recovery Environment asks Do you want to apply repairs and restart your computer, choose No. Choose Use recovery tools that can help fix problems starting Windows and then clck Command Prompt. In the Command Prompt find the drive that contains the Windows installation. Most likely it’s C:. Run the following commands to repair Windows Boot Catalog.

    bcdedit /set {default} device partition=c:
    bcdedit /set {default} osdevice partition=c:
    bcdedit /set {bootmgr} device partition=c:

It should now be possible to boot Windows from the Grub boot menu.

References

Posted 2010-04-19T21:52:10 EEST Tags:

Introduction

Here I document the steps that are needed to create a Windows 7 installation media that contains all retail editions of both 32-bit and 64-bit versions of the operating system. You’ll need original retail DVD media of both versions. It doesn’t matter which edition your’re using, since all Windows 7 DVDs contain the same installation image[1]. You also need a Windows 7 installation with about 10GB of free disk space.

This posting borrows a lot from this article[2]. Thanks and greetings to the author. Also Microsoft’s Windows 7 Technical Library Roadmap[3] has something to say about the topic[4],[5].

Windows Automated Installation Kit

  1. Download and install WAIK for Windows 7[6].

  2. Start Deployment Tools Command Prompt as Administrator. All subsequent commands are typed in the command prompt.

Extracting the original 32-bit media

  1. Create the following directory structure holding the installation image remastering data on a disk that can be used as scratch space. I’m using d:\aio as the base directory.

    md d:\aio
    md d:\aio\build
    md d:\aio\temp
    
    
  2. We use the 32-bit edition as basis for the image due to the reasons described in detail in the article referenced above[2]. Insert Windows 7 32-bit installation DVD into the drive. I’m using g:\ as the DVD drive letter in this listing.

  3. Copy the content of the DVD to d:\aio\build

    xcopy /e g:\ d:\aio\build
    
    
  4. Delete the ei.cfg file in order to unlock all editions[7].

    del d:\aio\build\sources\ei.cfg
    
    
  5. Eject Windows 7 32-bit installation media from the DVD drive

Integrate 64-bit install

  1. Insert Windows 7 64-bit installation media to the DVD drive

  2. Copy the install.wim file that holds the installation image to d:\aio\temp

    copy g:\sources\install.wim d:\aio\temp
    
    
  3. Now we can use ImageX[8] tool to integrate 64-bit editions from the 64-bit installation image with the 32-bit installation image.

    imagex /export d:\aio\temp\install.wim "Windows 7 HOMEBASIC" d:\aio\build\sources\install.wim "Windows 7 HOMEBASIC 64-bit"
    imagex /export d:\aio\temp\install.wim "Windows 7 HOMEPREMIUM" d:\aio\build\sources\install.wim "Windows 7 HOMEPREMIUM 64-bit"
    imagex /export d:\aio\temp\install.wim "Windows 7 PROFESSIONAL" d:\aio\build\sources\install.wim "Windows 7 PROFESSIONAL 64-bit"
    imagex /export d:\aio\temp\install.wim "Windows 7 ULTIMATE" d:\aio\build\sources\install.wim "Windows 7 ULTIMATE 64-bit"
    
    

Remaster ISO image of the installation media

  1. Finally, you can remaster the installation ISO image using Oscdimg[9].

    oscdimg -u2 -bd:\aio\build\boot\etfsboot.com -lGRMCULFRER_EN_DVD -t7/14/2009,12:26:40 d:\aio\build d:\aio\Windows_7_Retail_AIO.iso
    
    
  2. Now you have the final ISO image of the Windows 7 AIO installation media in the file d:\aio\Windows_7_Retail_AIO.iso. You could burn it to a DVD or create bootable USB installation stick[10],[11] or what ever.

References

Posted 2010-04-19T21:51:47 EEST Tags:

Introduction

In this posting I’m creating Windows 7 pre-installation (Windows PE) and rescue images that can be PXE booted for both 64-bit and 32-bit systems. As source I’m using Windows 7 Ultimate retail images. You need a machine running Windows 7 to build the images using Windows Automated Installation Kit. This machine is named “Technician Computer” in the documentation[1]. The resulting bootable images are stored on a Linux server that has a DHCP server and TFTP server configured to serve PXE clients. ISC DHCP Server 3.1.2 and tftpd-hpa 0.49 are used. On the server TFTP root is /var/lib/tftpboot and we want to make Windows stuff available via TFTP under the path /i386/windows/. DHCP server is passing the following DHCP option to PXE clients:

    filename "/i386/pxelinux.0";

This PXELinux kernel comes from syslinux 3.63.

Other people have been writing about this stuff, too[2],[3],[4].

Windows Automated Installation Kit

  1. Download and install WAIK for Windows 7[5] on the Technician Computer.

  2. Start Deployment Tools Command Prompt as Administrator. All subsequent commands are typed in the command prompt.

Create Windows PE images

The following steps show you all the commands that are required to create and configure PXE bootable Windows PE 64-bit and 32-bit images.

  1. Insert your Windows 7 Ultimate 64-bit DVD to your DVD drive, mount an ISO image of the retail DVD or otherwise have the content of the retail DVD available under some directory. In this guide we’ll use DVD as the source and the content of the media is available under g:\.

  2. Create Windows PE 64-bit working directory

    copype.cmd amd64 c:\winpe_x64
    
    
  3. The plain Windows PE image created by WAIK for Windows 7 above doesn’t contain The Windows Recovery Environment[6]. However, we can use the Windows RE image on the DVD[7] as basis for our custom image. This way we get the recovery features and tools. So let’s mount the install image from the DVD and copy Windows RE image as our base image.

    md c:\winpe_x64\os_install
    imagex /mount g:\sources\install.wim 1 c:\winpe_x64\os_install
    copy c:\winpe_x64\os_install\windows\system32\recovery\winre.wim c:\winpe_x64\winpe.wim
    imagex /unmount c:\winpe_x64\os_install
    rd c:\winpe_x64\os_install
    
    
  4. You can now eject the DVD

  5. Mount the Windows PE 64-bit image

    imagex /mountrw c:\winpe_x64\winpe.wim 1 c:\winpe_x64\mount
    
    
  6. You can install 3rd party drivers to the Windows PE environment[8] if you need. I’m going to install some VMWare drivers here[9]. VMware drivers were copied from a host running under VMWare with VMWare Tools installed. Drivers are available at c:\Program Files\VMWare\VMWare Tools\Drivers\ and were copied to c:\winpe_x64\drivers\vmware.

    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\audio\vmaudio.inf
    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\mouse\vmmouse.inf
    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\pvscsi\pvscsi.inf
    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers\vmware\vmxnet3\vmxnet3ndis6.inf
    
    
  7. Alternatively, you could add all the drivers under c:\winpe_x64\drivers\ in one go like this.

    dism /image:c:\winpe_x64\mount /add-driver:c:\winpe_x64\drivers /recurse
    
    
  8. You can see what drivers have been installed with the command

    dism /image:c:\winpe_x64\mount /get-drivers
    
    
  9. If you wish, you might set internationaliztion and localization options in the Windows PE environment[10]. In this example Finnish settings are used for standards and formats, keyboard layout and timezone while all other settings are set to American English by default.

    dism /image:c:\winpe_x64\mount /set-allintl:en-us
    dism /image:c:\winpe_x64\mount /set-userlocale:fi-fi
    dism /image:c:\winpe_x64\mount /set-inputlocale:fi-fi
    dism /image:c:\winpe_x64\mount /set-timezone:"FLE Standard Time"
    
    
  10. You may verify internationalization and localization settings by running the following command.

    dism /image:c:\winpe_x64\mount /get-intl
    
    
  11. If you don’t want to start the Windows Recovery Environment by default, edit c:\winpe_x64\mount\windows\system32\winpeshl.ini and replace the program that is launched by the Windows PE shell[11]. I use the following winpeshl.ini to initialize some stuff using wpeinit.exe[12] and the launch the command prompt. When your image is ready and you can boot it, you can launch The Windows Recovery Environment by running %SYSTEMDRIVE%\sources\recovery\recenv.exe from the command prompt after booting Windows PE.

    [LaunchApps]
    %SYSTEMROOT%\System32\wpeinit.exe
    %SYSTEMROOT%\System32\cmd.exe
    
    
  12. Install ImageX[13] tool from Windows AIK installation to the Windows PE environment. This allows you to work with the Windows Imaging File Format WIM[14] images within the Windows PE environment. You could use ImageX to install Windows 7 locally on a system supporting PXE booting using an installation image stored on a network share[15], for instance.

    copy "c:\Program Files\Windows AIK\Tools\amd64\imagex.exe" c:\winpe_x64\mount\Windows\system32
    
    
  13. Install any 3rd party applications and scripts you may want. Just copy the stuff somewhere under the image mount point, e.g. self-contained executables could go to c:\winpe_x64\mount\Windows\system32. Some examples include

    • Explorer++[16]
      • File manager
    • PE Network Configurator[17]
      • Allows you to configure networking in Windows PE
  14. Copy all files (but the directories containing localization data are not needed) from c:\winpe_x64\mount\Windows\Boot\PXE\ to /var/lib/tftpboot/i386/windows on the TFTP server.

  15. Unmount Windows PE 64-bit image

    imagex /unmount /commit c:\winpe_x64\mount
    
    
  16. Create Windows PE 32-bit environment. Windows 7 Ultimate 32-bit installation media must be available at g:\ so insert the DVD or mount the image first. I’ve included bulk of the commands here in one go, see the steps above for explanation.

    copype.cmd x86 c:\winpe_x86
    md c:\winpe_x86\os_install
    imagex /mount g:\sources\install.wim 1 c:\winpe_x86\os_install
    copy c:\winpe_x86\os_install\windows\system32\recovery\winre.wim c:\winpe_x86\winpe.wim
    imagex /unmount c:\winpe_x86\os_install
    rd c:\winpe_x86\os_install
    imagex /mountrw c:\winpe_x86\winpe.wim 1 c:\winpe_x86\mount
    dism /image:c:\winpe_x86\mount /add-driver:c:\winpe_x86\drivers /recurse
    dism /image:c:\winpe_x86\mount /set-allintl:en-us
    dism /image:c:\winpe_x86\mount /set-userlocale:fi-fi
    dism /image:c:\winpe_x86\mount /set-inputlocale:fi-fi
    dism /image:c:\winpe_x86\mount /set-timezone:"FLE Standard Time"
    copy "c:\Program Files\Windows AIK\Tools\x86\imagex.exe" c:\winpe_x86\mount\Windows\system32
    
    
  17. Install any 3rd party software or customizations (the winpeshl.ini customization shown above, for instance) for the Windows PE 32-bit environment in c:\winpe_x86\mount.

  18. Unmount Windows PE 32-bit image

    imagex /unmount /commit c:\winpe_x86\mount
    
    
  19. Your Windows PE images c:\winpe_x64\winpe.wim and c:\winpe_x86\winpe.wim are now ready for booting! Besides booting over PXE[18], you could create a bootable USB stick using these same images[19], for instance.

Boot configuration

  1. Create boot configuration data[20],[21] using the bcdedit tool[22].

    bcdedit /createstore c:\bcd-pxeboot
    
    
  2. Create ramdisk options in the boot configuration data

    bcdedit /store c:\bcd-pxeboot /create {ramdiskoptions}
    bcdedit /store c:\bcd-pxeboot /set {ramdiskoptions} ramdisksdidevice boot
    bcdedit /store c:\bcd-pxeboot /set {ramdiskoptions} ramdisksdipath \i386\windows\boot.sdi
    
    
  3. Create OS Loader settings for the Windows PE 64-bit image in the boot configuration data.

    bcdedit /store c:\bcd-pxeboot /create /application osloader /d "Windows PE 64-bit"
    
    
  4. Previous command will output a GUID for Windows PE 64-bit. In this guide we’ll use fa76e260-385f-11df-8c80-00241d86f38c, adjust to match yours.

    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} systemroot \Windows
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} detecthal Yes
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} winpe Yes
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} osdevice ramdisk=[boot]\i386\windows\boot_x64.wim,{ramdiskoptions}
    bcdedit /store c:\bcd-pxeboot /set {fa76e260-385f-11df-8c80-00241d86f38c} device ramdisk=[boot]\i386\windows\boot_x64.wim,{ramdiskoptions}
    
    
  5. Create OS Loader settings for the Windows PE 32-bit image in the boot configuration data.

    bcdedit /store c:\bcd-pxeboot /create /application osloader /d "Windows PE 32-bit"
    
    
  6. Previous command will output a GUID for Windows PE 32-bit. In this guide we’ll use 28318ca0-3860-11df-8c80-00241d86f38c, adjust to match yours.

    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} systemroot \Windows
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} detecthal Yes
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} winpe Yes
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} osdevice ramdisk=[boot]\i386\windows\boot_x86.wim,{ramdiskoptions}
    bcdedit /store c:\bcd-pxeboot /set {28318ca0-3860-11df-8c80-00241d86f38c} device ramdisk=[boot]\i386\windows\boot_x86.wim,{ramdiskoptions}
    
    
  7. Create Boot Manager settings in the boot configuration data. Boot Windows PE 64-bit by default.

    bcdedit /store c:\bcd-pxeboot /create {bootmgr}
    bcdedit /store c:\bcd-pxeboot /set {bootmgr} timeout 10
    bcdedit /store c:\bcd-pxeboot /displayorder {fa76e260-385f-11df-8c80-00241d86f38c} {28318ca0-3860-11df-8c80-00241d86f38c}
    bcdedit /store c:\bcd-pxeboot /default {fa76e260-385f-11df-8c80-00241d86f38c}
    
    

Copy files to the boot server

Note the casing of the target file names stored on the Linux server! It’s important to get these right, otherwise booting the client won’t work.

  1. Copy c:\winpe_x64\winpe.wim to the TFTP server as the file /var/lib/tftpboot/i386/windows/boot_x64.wim

  2. Copy c:\winpe_x86\winpe.wim to the TFTP server as the file /var/lib/tftpboot/i386/windows/boot_x86.wim

  3. Copy file c:\Program Files\Windows AIK\Tools\PETools\amd64\boot\boot.sdi to /var/lib/tftpboot/i386/windows on the TFTP server.

  4. Copy directory c:\Program Files\Windows AIK\Tools\PETools\amd64\boot\fonts as /var/lib/tftpboot/i386/windows/Fonts on the TFTP server.

  5. Copy the boot configuration data c:\bcd-pxeboot to the TFTP server as the file /var/lib/tftproot/i386/windows/BCD.

  6. Ensure that all files that were copied earlier from the mounted Windows PE 64-bit environment c:\winpe_x64\mount\Windows\Boot\PXE\ to /var/lib/tftpboot/i386/windows have lower case file names on the TFTP server.

Configure the boot server

  1. In order to configure PXELinux, Linux TFTP server and Windows PE network boot to work together, some tuning is required. On the server you must serve the Windows PXE boot kernel with suffix .0 or it won’t work[3]. Let’s create a symlink for that.

    ~: # ln -s pxeboot.n12 /var/lib/tftpboot/i386/windows/pxeboot.0
    
    
  2. Adjust your PXE configuration file (/var/lib/tftpboot/i386/pxelinux.cfg/default in my case) to boot /i386/windows/pxeboot.0 we just created. You could use e.g. the following PXE menu entry in /var/lib/tftpboot/i386/pxelinux.cfg/default:

    menu title Boot Menu
    ...
    label winpe
      menu label ^Windows PE
      kernel windows/pxeboot.0
    
    
  3. Configure TFTP server remapping. The Windows PE network boot system uses hard coded paths for some of the files it retrieves over TFTP. Those paths don’t match our setup here by default. It also uses backslashes instead of slashes to separate directories. This doesn’t work with TFTP server on Linux Fortunately, tftpd-hpa supports file remapping using an external configuration file[23]. Save the following text somewhere (/etc/tftpd-remap.conf for example) and adjust TFTP server startup so that this file is loaded with the tftpd -m command line option.

    # Map DOS style path separators to Unix path separators
    gr \\ /
    # Locate bootmgr.exe
    r ^bootmgr\.exe /i386/windows/bootmgr.exe
    # Map /Boot to /i386/windows
    r ^/Boot /i386/windows
    
    

References

Posted 2010-04-19T21:51:17 EEST Tags:

Introduction

In this posting I document the steps needed to create an installer disk image from Mac OS X 10.6 Snow Leopard retail DVD in a generic way. While the process is well documented by others[1], I’ll do it here once more with a twist. The whole thing is created in shell using only command-line tools. The resulting disk image can be written onto a USB storage media and then used to install the operating system to a generic PC that is supported by the retail version of Mac OS X. You’ll need a working Mac OS X 10.6 installation running on a genuine Mac or Hackintosh with root shell access. For sake of simplicity, we use an image of the Mac OS X 10.6 Snow Leopard DVD (called ~/Desktop/Hackintosh/Mac_OS_X_10.6_Snow_Leopard.dmg in this guide) so you must create it from your physical DVD beforehand[2].

Preparing the installer image

  1. Create a disk image file for the installation media. 6500 megabytes will hold the installation partition. The disk image will be initialized with MBR partition scheme and one partition is created onto it. Soon we’ll wipe out this partition, though.

    ~: $ hdiutil create -size 6500m -layout MBRSPUD -fs HFS+ \
            ~/Desktop/Hackintosh/Mac_OS_X_10.6_Snow_Leopard_Hackintosh_Install_Disk.dmg
    
    
  2. Attach the Mac OS X 10.6 Snow Leopard retail DVD image.

    ~: $ hdiutil attach -nomount -noverify ~/Desktop/Hackintosh/Mac_OS_X_10.6_Snow_Leopard.dmg
    
    
  3. The command will print the device name for the disk. Write that down. In the guide we’re using /dev/disk1.

  4. Attach the newly created empty disk image.

    ~: $ hdiutil attach -nomount -noverify \
            ~/Desktop/Hackintosh/Mac_OS_X_10.6_Snow_Leopard_Hackintosh_Install_Disk.dmg
    
    
  5. Write down also the device name for the installer disk. In the guide we’re using /dev/disk2.

  6. Now we use dd(1) command to clone the 3rd partition from the retail DVD that holds the Mac OS X installer and write it to the 1st partition of the installer disk. Be sure to adjust the device names according to your system as you can potentially destroy your installation big time if you screw up here. This might take quite a lot of time to complete.

    ~: $ dd bs=1m if=/dev/disk1s3 of=/dev/disk2s1
    
    
  7. Then mount the installer disk. The installer file system should be available at /Volumes/Mac OS X Install DVD.

    ~: $ diskutil mount /dev/disk2s1
    
    
  8. Fix the installer mountpoint so that file can be owned by root.

    ~: $ sudo diskutil enableOwnership /dev/disk2s1
    
    
  9. Rename the installer file system. After that the installer file system is available at /Volumes/Hackintosh Snow Leopard Install Disk.

    ~: $ diskutil rename /dev/disk2s1 "Hackintosh Snow Leopard Install Disk"
    
    
  10. Mark the file system so that fseventsd doesn’t keep any logs there.

    ~: $ sudo rm -rf /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/.fseventsd
    ~: $ sudo install -o root -g admin -m 700 -d /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/.fseventsd
    ~: $ sudo touch /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/.fseventsd/no_log
    ~: $ sudo chmod 400 /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/.fseventsd/no_log
    ~: $ sudo chown root:admin /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/.fseventsd/no_log
    
    

Install Chameleon boot loader

  1. The installer won’t boot on a generic PC without a special boot loader which loads the Mac OS X kernel in an environment that emulates real Mac. See more about Chameleon in the posting Create preboot image for Chameleon bootloader. Download Chameleon 2.0-RC4[3] boot loader and extract Chameleon-2.0-RC4-r684-bin.tar.gz somewhere, e.g. ~/Desktop/Hackintosh thus creating directory ~/Desktop/Hackintosh/Chameleon-2.0-RC4-r684-bin.

  2. First, unmount the installer disk so that we can write directly to the block device.

    ~: $ diskutil unmount /dev/disk2s1
    
    
  3. Next few steps are also documented in the file doc/README under Chameleon directory. We’ll install the initial boot code to the master boot record of the installer disk.

    ~: $ sudo dd if=~/Desktop/Hackintosh/Chameleon-2.0-RC4-r684-bin/i386/boot0 of=/dev/disk2 bs=440 count=1
    
    
  4. And then let’s install the 2nd stage boot code at the beginning of the 1st partition of the installer disk.

    ~: $ sudo dd if=~/Desktop/Hackintosh/Chameleon-2.0-RC4-r684-bin/i386/boot1h of=/dev/disk2s1
    
    
  5. Mount the installer disk again. The installer file system should be available at /Volumes/Hackintosh Snow Leopard Install Disk.

    ~: $ diskutil mount /dev/disk2s1
    
    
  6. Fix the installer mountpoint so that file can be owned by root.

    ~: $ sudo diskutil enableOwnership /dev/disk2s1
    
    
  7. And then copy the final stage of Chameleon boot code to the installer file system. We’re now done with the boot loader core installation.

    ~: $ sudo install -o root -g wheel -m 644 ~/Desktop/Hackintosh/Chameleon-2.0-RC4-r684-bin/i386/boot \
            /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk
    
    
  8. While not needed for Chameleon to operate, copy also the initial and 2nd stage boot code images to the installer file system. You may need these if you have to recover Chameleon installation.

    ~: $ sudo install -o root -g wheel -m 644 ~/Desktop/Hackintosh/Chameleon-2.0-RC4-r684-bin/i386/boot0 \
            /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk
    ~: $ sudo install -o root -g wheel -m 644 ~/Desktop/Hackintosh/Chameleon-2.0-RC4-r684-bin/i386/boot1h \
            /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk
    
    

Preboot image

Create preboot image for Chameleon that suits your system. I’ve written about this in the posting called Create preboot image for Chameleon bootloader. In the following steps it is expected that the preboot image is saved as the file ~/Desktop/Hackintosh/Preboot.dmg.

  1. Chameleon expects to find the preboot image under the directory Extra in the root of the installer file system. So let’s create that.

    ~: $ sudo install -o root -g wheel -m 755 -d /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/Extra
    
    
  2. Install the preboot image onto the installer file system

    ~: $ sudo install -o root -g wheel -m 644 ~/Desktop/Hackintosh/Preboot.dmg \
            /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/Extra
    
    

Boot configuration

Optionally, you can customize many boot properties such as boot console graphics mode or enabled hardware by creating the file Extra/com.apple.Boot.plist under the Chameleon boot disk. You could start by copying the file /Library/Preferences/SystemConfiguration/com.apple.Boot.plist from an existing Mac OS X Snow Leopard installation and then use it as template. Chameleon binary download[3] contains the file doc/BootHelp.txt which lists the supported com.apple.Boot.plist settings. Also these postings[4],[5] contain some useful info about com.apple.Boot.plist file.

If you want that the installer is booted automatically without displaying Chameleon GUI, use the following kind of boot configuration and save it as /Volumes/Hackintosh Snow Leopard Install Disk/Extra/com.apple.Boot.plist. Of course you may also add any local modifications, such as enabling of some hardware, if needed.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Kernel</key>
    <string>mach_kernel</string>
    <key>Kernel Flags</key>
    <string></string>
    <key>Legacy Logo</key>
    <string>Yes</string>
    <key>Quiet Boot</key>
    <string>Yes</string>
    <key>GUI</key>
    <string>No</string>
    <key>Scan Single Drive</key>
    <string>Yes</string>
</dict>
</plist>

Finalizing the installer

  1. Cleanup installer file system

    ~: $ sudo rm -rf /Volumes/Hackintosh\ Snow\ Leopard\ Install\ Disk/.Trashes
    
    
  2. Image is now ready! You can now eject the retail DVD and the installer disk images.

    ~: $ diskutil eject /dev/disk1
    ~: $ diskutil eject /dev/disk2
    
    

The installer image ~/Desktop/Hackintosh/Mac_OS_X_10.6_Snow_Leopard_Hackintosh_Install_Disk.dmg is now ready to be written onto a USB storage media.

References

Posted 2010-04-19T21:50:49 EEST Tags: