Install Mac on WSL2 => Prepare for IOs Editing

Homan Huang
8 min readOct 16, 2020

You will find WSL2 is quite a convenient tool to have Twin OSs editing in one machine. I don’t want to buy a second laptop, but I will buy a second screen to help my work between $260 to $350 on Amazon. 🤔Why do they have a huge difference in price? They share the 🙄same design and the 😵same screen size. Let’s begin:

— === Menu === —

💥1. Enable KVM Booster
_______🍖X Server — VcXsrv
_______🍭Kernel Source
_______📝Setup WSL2
_______🔧Fix Intel CPU Detection
💻2. Install macOS-Simple-KVM
_______🛢Image Size
_______🐭Mouse cursor
_______🍬CPU setting
_______🍰Memory
👁‍🗨3. MAC Installation: Catalina for Xcode-12
_______🗜 Format Partition
_______♌️OS Installation
_______🌼Fresh Setup
👌4. Shutdown and Re-Entry

💥1. Enable KVM Booster

< === Menu

Requirements

  • Intel Core i5 CPU or AMD with Hyper-V support
  • An X server for Windows, e.g. X410 or VcXsrv(Free)
  • Ram Requirement: >16GB; 32GB will be better.
  • Hardisk Requirement: >60GB basic; >80GB with Xcode-12

VcXsrv Setting

Multiple windows. Next
Start no client. Next

Input: -swcursor

Ubuntu → .bashrc

echo "Getting Host IP: "
MYIP=`cat /etc/resolv.conf | grep nameserver | awk '{print $2}' `
echo -e "${MYIP}\n ======== \n"
echo -e "\nDisplay:"
DISP_IP=$(/usr/bin/grep nameserver /etc/resolv.conf 2> /dev/null | /usr/bin/tr -s ' ' | /usr/bin/cut -d' ' -f2)
export DISPLAY=$DISP_IP:0.0
export | grep DISPLAY
Test Run

Export Audio to PulseAudio Server

Please check my past story for installing the PulseAudio server (section 6) on Windows.

> .bashrc:

echo -e "\nPulse Audio Serve:"
echo "${MYIP}"
export PULSE_SERVER="${MYIP}"
export | grep PULSE_SERVER

update

Open Ubuntu 20.04 shell:

$ sudo apt update && sudo apt -y upgrade
[sudo] password for XXX: ...
$ sudo apt -y install build-essential libncurses-dev bison flex libssl-dev libelf-dev cpu-checker qemu-kvm aria2
[sudo] password for XXX: ...

Kernal Source

Download the Kernel source from Microsoft.

$ cd
$ aria2c -x 10 https://github.com/microsoft/WSL2-Linux-Kernel/archive/4.19.104-microsoft-standard.tar.gz

Unzip

$ tar -xf WSL2-Linux-Kernel-4.19.104-microsoft-standard.tar.gz

Move to kernel source

$ cd WSL2-Linux-Kernel-4.19.104-microsoft-standard/

Let’s check your kernel version:

$ uname -r
4.19.104-microsoft-standard

Setup @ WSL2-Linux-Kernel-4.19.104-microsoft-standard

WSL 2 kernel configuration:

$ cp Microsoft/config-wsl .config

Install Menu:

$ make menuconfig

Move down to Virtualization:

Press M at KVM for Intel processors support.

Esc…Esc, Next, ==> Processor type and features.

==> Linux guest support

Enable KVM Guest support.

<Save> as .config and <Exit>.

Build the new kernel:

$ make -j 8
... 5 minutes ...
Setup is 15964 bytes (padded to 16384 bytes).
System is 8849 kB
CRC cec81900
Kernel: arch/x86/boot/bzImage is ready (#1)
homanadmin@LAPTOP-THUV2CQ5:~/WSL2-Linux-Kernel-4.19.104-microsoft-standard$

Install modules

$ sudo make modules_install
INSTALL arch/x86/kvm/kvm-intel.ko
DEPMOD 4.19.104-microsoft-standard

Copy bzImage to under your name:

$ cp arch/x86/boot/bzImage /mnt/c/Users/YourName/bzImage

Create a WSL2 config:

$ nano /mnt/c/Users/Homan/.wslconfig

Paste:

[wsl2]
nestedVirtualization=true
kernel=c:\\Users\\Homan\\bzImage
debugConsole=true
pageReporting=true
kernelCommandLine=intel_iommu=on iommu=pt kvm.ignore_msrs=1 kvm-intel.nested=1 kvm-intel.ept=1 kvm-intel.emulate_invalid_guest_state=0 kvm-intel.enable_shadow_vmcs=1 kvm-intel.enable_apicv=1

Restart Ubuntu:

Close all Ubuntu shells. In PowerShell:

> wsl --list --verbose
NAME STATE VERSION
* Ubuntu-20.04 Running 2

It’s still running. Let’s shutdown.

> wsl --shutdown Ubuntu
> wsl --list --verbose
NAME STATE VERSION
* Ubuntu-20.04 Stopped 2

Open a new Ubuntu shell.

$ uname -ar

It’s a new kernel.

Fix Intel-CPU Pipes Detection: Install WinDBg Preview on Microsoft Store; run-wsl and script.js

Goto: https://gist.github.com/steffengy/62a0b5baa124830a4b0fe4334ccc2606

Copy the content of run-wsl.bat and script.js into C:\WINDOWS\system32.

> run-wsl.bat: I have added administrator requirement and Ubuntu calling.

REM Administrator Requirement
set "params=%*"
cd /d "%~dp0" && ( if exist "%temp%\getadmin.vbs" del "%temp%\getadmin.vbs" ) && fsutil dirty query %systemdrive% 1>nul 2>nul || ( echo Set UAC = CreateObject^("Shell.Application"^) : UAC.ShellExecute "cmd.exe", "/k cd ""%~sdp0"" && %~s0 %params%", "", "runas", 1 >> "%temp%\getadmin.vbs" && "%temp%\getadmin.vbs" && exit /B )
REM Ensure vmcompute.exe is running
wsl.exe -e true
REM Listen for and Intercept utility vm creation
start Windbgx.exe -pn vmcompute.exe -c "bp vmcompute!Marshal::JsonParser::JsonParser;g;.scriptrun %CD%\script.js;.scriptrun %CD%\script.js;.scriptrun %CD%\script.js;.detach;qq"
REM Ensure WSL Utility VM is not running (hopefully windb starts up fast enough...)
net stop LxssManager
net start LxssManager
echo "Press Enter if the debugger is running"
REM My batch file to start Ubuntu. 5s for Windbgx debugs
d:
cd\bin
timeout 5
REM Call Ubuntu and VcXsrv
startx

>startx.bat: You need to work on your own files.

@echo off
rem start X server
start /B cursor-config.xlaunch -ac
rem start pulse audio server
start "" /B "D:\bin\pulseaudio-1.1\bin\pulseaudio.exe"
rem run ubuntu
start /B explorer.exe shell:appsFolder\CanonicalGroupLimited.Ubuntu20.04onWindows_79rhkp1fndgsc!ubuntu2004

Configure kvm-intel:

$ sudo nano /etc/modprobe.d/kvm-nested.conf
[sudo] password for You:

Paste these lines:

options kvm-intel nested=1
options kvm-intel enable_shadow_vmcs=1
options kvm-intel enable_apicv=1
options kvm-intel ept=1

Save.

Check CPU-Info:

$ egrep -c "(svm|vmx)" /proc/cpuinfo
12

My laptop has 12 pipes at the CPU.

If you have 0, please close Ubuntu shell and WinDbg. Run my run-wsl.bat again.

Please continue if you have a number.

$ sudo modprobe kvm_intel
[sudo] password for You:

KVM Ability:

$ kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

Nested status:

$ cat /sys/module/kvm_intel/parameters/nested
Y

Edit .bashrc:

$ cd
$ nano .bashrc

add two lines at the end before you call GUI:

# KVM
sudo modprobe kvm_intel
sudo chmod 666 /dev/kvm
echo
echo "Your CPU Threads: "
egrep -c "(svm|vmx)" /proc/cpuinfo
echo

Done!

💻2. Install macOS-Simple-KVM

< === Menu

Install QEMU

$ sudo apt -y install qemu-kvm libvirt-daemon qemu-system qemu-utils python3 python3-pip bridge-utils virtinst libvirt-daemon-system virt-manager

MacOS-Simple-KVM: With MoJave(Xcode 11 compatilbe), Catalina(Xcode 12 compatible)

$ git clone https://github.com/foxlet/macOS-Simple-KVM.git$ cd macOS-Simple-KVM$ ./jumpstart.sh --catalina

Create a disk image:

$ qemu-img create -f qcow2 /%DEST%/MacOS.qcow2 100G

For example, I am using d:/wsl/ as my image destination.

$ qemu-img create -f qcow2 /mnt/d/wsl/MacOS.qcow2 50G

Add to basic.sh at macOS-Simple-KVM

>Ctrl+_: 300 ← Jump to 300th line

    -drive id=SystemDisk,if=none,file=/%DEST%/MacOS.qcow2 \
-device ide-hd,bus=sata.4,drive=SystemDisk \

basic.sh — Mouse to tablet:

    -usb -device usb-kbd -device usb-tablet \

basic.sh — CPU setting: -smp (sockets=1) x cores x threads

My CPU is Intel 8750H: 6 cores and 12 threads = 72 max, right?

    -smp 72 <== It doesn't work.

My best test is:

    -smp 4,cores=4

Show on Mac:

basic.sh — memory: 8G or 16G if you have 32G Ram

    -m 8G      or     -m 16G

basic.sh —Glitching Audio← Need to be fixed.

    -device ich9-intel-hda -device hda-output,audiodev=hda \
-audiodev pa,id=hda,server=`cat /etc/resolv.conf | grep nameserver | awk '{print $2}'` \

Now, turn on the Xserver,

and run. It may be hidden in the corner.

If you encounter this error:

Authorization required, but no authorization protocol specified

You need to shut down all opened Xservers and reopen a new one.

👁‍🗨3. MAC Installation: Catalina for Xcode-12

< === Menu

First screen:

Press enter.

Format partition:

Find preset QEMU image:

To use Xcode, please set QEMU image to 100G

Set name:

Erase.

Done.

OS Installation

Time Machine: Later, I run out of space after I download Xcode-12GM. 50GB is a terrible choice. Mac has a huge mouth. 24-hour after, I resized failure with 50GB, I have to reinstall the Mac with 100GB.

Press the red dot to go back to the macOS Utilities and install MacOS.

Install New OS:

Continue
Agree
Agree
Install

For about 1 hour… It’ll restart later.

40 more minutes? Windows 10 installation will be faster.

MacOS Fresh Setup

Welcome screen:

Continue

Keyboard:

Continue

Data and privacy:

Continue

Transfer:

Don’t and Continue

Apple ID:

Type in Your Apple ID

You can create your Apple ID on Apple iCloud.

icloud.com

Term and Condition

Agree
Agree

Account:

Fill in…Continue

iCloud Backup:

Continue

Look:

Continue

👌4. Shutdown and Re-Entry

< === Menu

Let’s shut down the Mac.

Shut Down

I wrote a bash shortcut: runmac

cd
cd macOS-Simple-KVM/
./basic.sh

Save it in your bin and chmod +x runmac

Anywhere in your terminal:

$ runmac

Login Screen:

Enjoy Your MAC on PC!

--

--

Homan Huang

Computer Science BS from SFSU. I studied and worked on Android system since 2017. If you are interesting in my past works, please go to my LinkedIn.