blog
作成日 : 2023/09/27
更新日 : 2023/09/27
更新日 : 2023/09/27
WSLのカーネルをdockerを利用して手軽にビルドする
概要
WSLのカーネルに追加したい機能 (例えば#9132 ) がある場合などにカーネルをビルドする必要がある。
カーネルのバージョンアップに追従し、 機能を追加していくためにも手軽にビルドするスクリプトの実装例を示す。
前提条件
- WSL上にdockerをインストール済み
- WSL上にgit clientをインストール済み
- WSL上にpython3をインストール済み
ファイル構成及び、呼び出す流れ
WSL上の作業ディレクトリ
.
|- Dockerfile
|- update.sh
|- config.sh
|- output.sh
|- wsl_kernel_default_latest_tag.py
|- main.sh
|- WSL2-Linux-Kernel/
|- .config
|- .config.bak
Windows上のディレクトリ
C:
|- wslkernel/
|- vmlinux
|- vmlinux.bak
|- Users/
|- {ユーザ名}/
|- .wslconfig
スクリプトを呼び出す流れ
![](https://www.ulvaniac.co.jp/wp-content/uploads/2023/09/overall_call_script.drawio-1024x667.png)
作業準備
WSL上の作業ディレクトリで、以下コマンドを実施する。
cat <<'EOS' > Dockerfile
FROM debian:stable-slim
WORKDIR /buildir
RUN : \
&& apt-get update \
&& apt-get install -y \
build-essential \
flex \
bison \
libssl-dev \
libelf-dev \
pkg-config \
libncurses-dev \
dwarves \
bc \
python3 \
&& apt-get -y clean \
&& rm -rf /var/lib/apt/lists/* \
&& :
EOS
cat <<'EOS' > update.sh
#!/bin/bash
set -euxo pipefail
docker pull debian:stable-slim
docker build --tag wsl-kernel-builder:latest .
cd WSL2-Linux-Kernel
lastest_tag=$(python3 ../wsl_kernel_default_latest_tag.py)
git checkout $lastest_tag
EOS
cat <<'EOS' > config.sh
#!/bin/bash
set -euxo pipefail
docker run --rm -it -v ".:/buildir" wsl-kernel-builder:latest \
bash -c 'cd WSL2-Linux-Kernel && cp -p --backup --suffix ".bak" Microsoft/config-wsl .config && make menuconfig'
EOS
cat <<'EOS' > output.sh
#!/bin/bash
set -euxo pipefail
docker run --rm -it -v ".:/buildir" wsl-kernel-builder:latest \
bash -c "cd WSL2-Linux-Kernel && make -j $(nproc)"
cd WSL2-Linux-Kernel
if [ ! -d "/mnt/c/wslkernel" ]; then
mkdir "/mnt/c/wslkernel"
fi
cp -p --backup --suffix ".bak" ./vmlinux /mnt/c/wslkernel/
EOS
cat <<'EOS' > wsl_kernel_default_latest_tag.py
import requests
import sys
repo_owner = "microsoft"
repo_name = "WSL2-Linux-Kernel"
repo_info_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}"
releases_url = f"https://api.github.com/repos/{repo_owner}/{repo_name}/releases"
headers = {
"Accept": "application/json" # JSON 形式のレスポンスを指定
}
try:
response = requests.get(repo_info_url, headers=headers)
response.raise_for_status()
default_branch = response.json()["default_branch"]
response = requests.get(releases_url, headers=headers)
response.raise_for_status()
releases = response.json()
for release in releases:
if release["target_commitish"] == default_branch:
print(release["tag_name"])
sys.exit(0)
except Exception as e:
print(e, file=sys.stderr)
sys.exit(1)
sys.exit(1)
EOS
cat <<'EOS' > main.sh
#!/bin/bash
set -euxo pipefail
# 最新のビルド環境にアップデート
bash update.sh
# `make menuconfig`でカーネルのビルドパラメータを設定
bash config.sh
# WSLの最新のカーネルをWindowsのディレクトリに出力
bash output.sh
EOS
# WSLカーネルのGitHubリポジトリをクローン
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
# カーネルを格納するディレクトリの作成
mkdir /mnt/c/wslkernel
カーネルのビルド
2回目以降は、本章のみ実行し、カーネルを更新する。 すぐにビルドしたカーネルを適用するときは、カーネルの適用のWSLの再起動も実施する。
bash main.sh
make menuconfig
によるカーネルのビルド時の設定が表示されるので、 やりたいことに合わせて設定する。
カーネルの適用
vim "$(wslpath "$(powershell.exe 'echo $env:USERPROFILE')" | tr -d "\r")/.wslconfig"
以下の内容を追加する。
wslconfig
[wsl2]
kernel=C:\\wslkernel\\vmlinux
# WSLの再起動
powershell.exe 'wsl --shutdown'
WSLを開くとビルドしたカーネルを適用した状態になる。
参考
WSLカーネルのGitHubリポジトリ