WSL可以自己編譯新的Linux核心給自己用!
從官方文件來看,WSL2的Linux核心不能透過Linux裡面的套件管理器替換,而是要由WSL.exe載入。因此Linux核心更新時程是由WSL決定的,apt install無效。
這個WSL的Linux核心是可以替換的。
Microsoft開發的WSL雖然功能眾多,但仍不支援用DKMS方式載入外部核心模組(out-of-tree kernel modules)的功能,所有驅動模塊都是編譯在核心裡的。所以若核心需要支援某個功能,多半得重新編譯(recompile)核心了。
譬如,我想在WSL跑Waydroid容器,就需要用到memfd與Binder的核心選項。那麼只要取得Microsoft公開的WSL核心原始碼,將特定功能開啟,編譯核心,再將WSL使用的核心抽換掉就好啦。
甚至,如果想搶先體驗最新版主線Linux的核心功能,您也可以自行從kernel.org下載原始碼自行編譯,並給WSL裝上!
我們不需要在Windows設定cross compile來編譯Linux核心,直接在WSL裡面編譯就可以了。
本文以WSL預設的Ubuntu為例子,示範如何在WSL裡編譯核心,開啟自訂選項,再替換掉原本的WSL核心。
1. 編譯Linux核心前的準備 #
-
確保已安裝WSL2
-
登入WSL,這裡是預設的Ubuntu
wsl- 安裝編譯核心用的套件
sudo apt update
sudo apt install build-essential flex bison dwarves libssl-dev libelf-dev cpio qemu-utils- 取得核心原始碼。Microsoft的原始碼會公佈在Github儲存庫。下載之前需要先確認目前WSL使用的核心版本:
uname -a- 假設輸出
6.18.33,那麼就從Github下,切換到該核心分支
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git --depth=1
cd WSL2-Linux-Kernel
git checkout linux-msft-wsl-6.18.y2. 編輯核心功能 #
- 讀取WSL的核心設定檔,啟動menuconfig編輯核心選項
make menuconfig KCONFIG_CONFIG=Microsoft/config-wsl-
現在會看到一個灰色畫面,這個就是用來調整核心功能的界面。操作方式:使用鍵盤的箭頭上下移動,按Enter進入下一級選單,按空白鍵啟用/關閉該核心功能。

-
如果不知道要啟用的核心選項在哪,按
/,鍵入CONFIG的字串,按Enter,它就會告訴你該選項的位置。如下圖,CONFIG_IPV6_ROUTER_PREF要到Networking support下的The IPv6 protocol勾選啟用,使其變成[y]。
-
如果記不起來位置,可以選取終端機文字,按Ctrl+C複製到記事本對照看。如果不知道確切要開哪個核心選項,請搜尋「CONFIG_XXX + Gentoo Wiki」就會有很多資料。

-
編輯完核心功能後,用鍵盤左右鍵移動到
Save,按Enter,儲存設定檔。
-
接著開始編譯核心。
-j$(nproc)代表使用全部CPU執行緒編譯,大約要30分鐘。
make -j$(nproc) KCONFIG_CONFIG=Microsoft/config-wsl- 安裝核心模組
make INSTALL_MOD_PATH="$PWD/modules" modules_install-
編譯後的檔案是
bzImage,應位於/arch/x86/boot/資料夾。 -
建立含有核心模組的VHDX映像檔
sudo ./Microsoft/scripts/gen_modules_vhdx.sh "$PWD/modules" $(make -s kernelrelease) modules.vhdx- 將編譯的bzImage檔案複製到Windows的C槽
cp arch/x86/boot/bzImage /mnt/c/bzImage
cp modules.vhdx /mnt/c/modules.ANDROID.vhdx3. 給WSL裝上編譯好的核心 #
我們可以利用.wslconfig指定WSL啟動時要載入的核心,或者用GUI設定。
-
開啟檔案總管,點選檢視 → 顯示隱藏項目,到
C:\Users\使用者名稱,找到剛剛複製出來的兩個檔案。 -
放到任意資料夾。例如
C:\Users\使用者名稱\customwslkernel\ -
開啟Windows軟體列表的WSL Settings,在開發人員面板,核心選取bzImage,核心模組選取VHDX。

-
回到WSL終端機,退出WSL
exit- 將WSL強制關機
wsl --shutdown- 重新登入WSL。
wsl- 確認核心版本是否已經成功變更。核心編譯日期應該顯示為今天。
uname -v