Linux 的 KVM 上安装 Mac OS X Mavericks 虚拟机
现在我们很方便就能在 Mac 上通过 VirtualBox 安装 Mac OS X 虚拟机,如果没 Mac 的话也能很容易在 Linux/Windows 下通过 VirtualBox 体验 Mac,
甚至把 Mac OS X 直接装在 PC 上也是可能的。如果想在数据中心这种 KVM/Xen 虚拟环境里安装 Mac OS X 呢?通过 Apple Remote Desktop 连接 n 个 Mac 虚拟机,应该会比较好玩吧。
以下操作在 CentOS 6.5 上测试通过。更详细的资料请参考 Running Mac OS X as a QEMU/KVM Guest.
首先需要 Linux 3.x 以上的内核,CentOS 6.5 上默认是 2.6.x 内核,所以需要另装或升级内核,我们这里用 CentOS 官方 Xen 源(Xen4CentOS6)里面的最新 Linux 内核,
注意这里用的是源里的普通内核,不是要用 Xen 内核,你也可以用其他第三方源的内核或者自己下载内核编译。注意修改 grub.conf 文件的 default=0 部分确认系统启动后启动的是普通内核(不是启动 Xen 内核):
# yum install centos-release-xen # yum update # vi /etc/grub.conf ... default=0 ... # reboot
当前的主流 Linux 发行版自带的 kvm/qemu 都不支持 OS X 作为 guest 系统,所以我们需要自己编译 kvm, kvm-kmod, qemu 加上 OS X 的支持。下载 kvm 和 kvm-kmod 源代码后编译,编译会出错,解决办法见后面:
# yum install git # yum groupinstall 'Development Tools' # git clone git://git.kernel.org/pub/scm/virt/kvm/kvm.git # git clone git://git.kiszka.org/kvm-kmod.git # cd kvm-kmod # ./configure # make LINUX=../kvm clean sync all ... /root/kvm-kmod/x86/assigned-dev.c: In function ‘assigned_device_enable_host_msix’: /root/kvm-kmod/x86/assigned-dev.c:434:2: error: implicit declaration of function ‘pci_enable_msix_exact’ [-Werror=implicit-function-declaration] r = pci_enable_msix_exact(dev->dev, ^ cc1: some warnings being treated as errors make[3]: *** [/root/kvm-kmod/x86/assigned-dev.o] Error 1 make[2]: *** [/root/kvm-kmod/x86] Error 2 make[1]: *** [_module_/root/kvm-kmod] Error 2 make[1]: Leaving directory `/usr/src/kernels/3.10.34-11.el6.centos.alt.x86_64' make: *** [all] Error 2
修改 assigned-dev.c 这个文件的第434行,用 pci_enable_msix 函数替代 pci_enable_msix_exact,查看 git 修改记录和日志,貌似 pci_enable_msix_exact 是 Linus 上个月刚加上去的,我们这里还原,
还是用原先的 pci_enable_msix 就可以了。
# vi /root/kvm-kmod/x86/assigned-dev.c ... /*r = pci_enable_msix_exact(dev->dev, dev->host_msix_entries, dev->entries_nr);*/ r = pci_enable_msix(dev->dev, dev->host_msix_entries, dev->entries_nr); ...
修改代码后重新编译,注意这时候 make clean all 不要 sync,否则上面的修改会被重新覆盖:
# make LINUX=../kvm clean all
编译成功后,就可以加载 kvm-intel 内核了,使用 dmesg 确认内核加载成功:
# modprobe -r kvm_intel # cp ./x86/kvm*.ko /lib/modules/$(uname -r)/kernel/arch/x86/kvm/ # modprobe kvm_intel # dmesg | tail -n1 loaded kvm module (for-linus-40872-ga4e91d0)
kvm 部分告一段落,现在来编译 qemu:
# yum install zlib zlib-devel glib2-devel pixman-devel # cd # mkdir osx # git clone git://git.qemu.org/qemu.git # cd qemu # ./configure --prefix=/root/osx --target-list=x86_64-softmmu # make clean; make; make install
我们要安装 OS X 当然需要 OS X 的启动盘。到 App Store 里下载 Install OS X Mavericks.app 安装文件,然后在 Mac 上用下面的脚本生成一个可启动的 Mavericks ISO 文件,
我们将要用这个 Mavericks.iso 安装系统,所以我们还需要把这个 Mavericks.iso 拷贝到 KVM 服务器上 :
$ vi createiso.sh # Mount the installer image hdiutil attach /Applications/Install\ OS\ X\ Mavericks.app/Contents/SharedSupport/InstallESD.dmg -noverify -nobrowse -mountpoint /Volumes/install_app # Convert the boot image to a sparse bundle hdiutil convert /Volumes/install_app/BaseSystem.dmg -format UDSP -o /tmp/Mavericks # Increase the sparse bundle capacity to accommodate the packages hdiutil resize -size 8g /tmp/Mavericks.sparseimage # Mount the sparse bundle for package addition hdiutil attach /tmp/Mavericks.sparseimage -noverify -nobrowse -mountpoint /Volumes/install_build # Remove Package link and replace with actual files rm /Volumes/install_build/System/Installation/Packages cp -rp /Volumes/install_app/Packages /Volumes/install_build/System/Installation/ # Unmount the installer image hdiutil detach /Volumes/install_app # Unmount the sparse bundle hdiutil detach /Volumes/install_build # Resize the partition in the sparse bundle to remove any free space hdiutil resize -size `hdiutil resize -limits /tmp/Mavericks.sparseimage | tail -n 1 | awk '{ print $1 }'`b /tmp/Mavericks.sparseimage # Convert the sparse bundle to ISO/CD master hdiutil convert /tmp/Mavericks.sparseimage -format UDTO -o /tmp/Mavericks # Remove the sparse bundle rm /tmp/Mavericks.sparseimage # Rename the ISO and move it to the desktop mv /tmp/Mavericks.cdr ~/Desktop/Mavericks.iso $ sudo sh createiso.sh
在 Mac 上编译 smc_read.c 这个文件并运行得到 SMC,这个 SMC 序号我们会在后面用到:
$ vi smc_read.c /* * smc_read.c: Written for Mac OS X 10.5. Compile as follows: * * gcc -Wall -o smc_read smc_read.c -framework IOKit */ #include #include typedef struct { uint32_t key; uint8_t __d0[22]; uint32_t datasize; uint8_t __d1[10]; uint8_t cmd; uint32_t __d2; uint8_t data[32]; } AppleSMCBuffer_t; int main(void) { io_service_t service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleSMC")); if (!service) return -1; io_connect_t port = (io_connect_t)0; kern_return_t kr = IOServiceOpen(service, mach_task_self(), 0, &port); IOObjectRelease(service); if (kr != kIOReturnSuccess) return kr; AppleSMCBuffer_t inputStruct = { 'OSK0', {0}, 32, {0}, 5, }, outputStruct; size_t outputStructCnt = sizeof(outputStruct); kr = IOConnectCallStructMethod((mach_port_t)port, (uint32_t)2, (const void*)&inputStruct, sizeof(inputStruct), (void*)&outputStruct, &outputStructCnt); if (kr != kIOReturnSuccess) return kr; int i = 0; for (i = 0; i < 32; i++) printf("%c", outputStruct.data[i]); inputStruct.key = 'OSK1'; kr = IOConnectCallStructMethod((mach_port_t)port, (uint32_t)2, (const void*)&inputStruct, sizeof(inputStruct), (void*)&outputStruct, &outputStructCnt); if (kr == kIOReturnSuccess) for (i = 0; i < 32; i++) printf("%c", outputStruct.data[i]); printf("\n"); return IOServiceClose(port); } $ gcc -Wall -o smc_read smc_read.c -framework IOKit $ ./smc_read REPLACE-YOUR-KEY-HERE(c)AppleComputerInc
快搞定了,最后我们还需要一个硬盘文件来充当虚拟机的硬盘以及 chameleon_svn2360_boot 这个文件,Chameleon 是 Darwin/XNU 系统的启动器(boot loader),用来在非苹果硬件上启动 OS X:
# /root/osx/bin/qemu-img create -f qcow2 osx.img 20G # wget http://www.contrib.andrew.cmu.edu/~somlo/OSXKVM/chameleon_svn2360_boot
在 KVM 上启动安装这个我们准备已久的 OS X Mavericks 虚拟机吧,注意下面的 osk="REPLACE-YOUR-KEY-HERE(c)AppleComputerInc" 部分用上面的 SMC 序号替代:
# /root/osx/bin/qemu-system-x86_64 -enable-kvm -m 2048 -cpu core2duo \ -smp 2 \ -vga std \ -device ahci,id=ide \ -usbdevice keyboard -usbdevice mouse \ -device isa-applesmc,osk="REPLACE-YOUR-KEY-HERE(c)AppleComputerInc" \ -kernel /root/chameleon_svn2360_boot \ -smbios type=2 \ -device ide-drive,bus=ide.2,drive=MacHDD \ -drive id=MacHDD,if=none,cache=none,file=/root/osx.img \ -vnc 0.0.0.0:1 \ -device ide-drive,bus=ide.0,drive=MacDVD \ -drive id=MacDVD,if=none,snapshot=on,file=/root/Mavericks.iso -boot once=d
打开 VNC 客户端连接上面 KVM 服务器 IP 和端口 5901 就会看到安装界面了,先按回车开始安装,然后用菜单里的 Disk Utility 工具分区,退出 Disk Utility 就可以看到安装盘了,
点击安装盘后就可以看到 Install OS X 安装界面了:
安装完后会重启进入系统:
目录 返回
首页