WSL2で使うlinuxカーネルのリビルド

## WSL2でもddを使いたいっ！
WSL/WSL2にはSDカードのddイメージを作成したり書き込んだりするのに使う/dev/sd?とか、/dev/mmcblk?といったデバイスファイルが存在しません。
Cドライブに直接ファイルアクセスするだけなら/mnt/cを見に行けばよいという話があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/495209e3-da55-bddb-7870-b60034e3d450.png)
Powershell上で\\.\PHYSICALDRIVEm形式でドライブを特定できる場合は、wsl --mount <DiskPath>またはwsl --mount <DiskPath> --bareといったコマンドでWSL2環境にアタッチすることができるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/43b1431e-91a3-7e67-1303-3f0454c6f9eb.png)
ですが、リムーバブルディスクであるSDカードはUSB-SDアダプタなどを介してPCに接続してもアタッチ可能なリストには出現しません。(Windowsからはドライブとして認識していても、です)

となると、usbipd-winを用いてUSBデバイスをWSL2に接続する方法を取るしかありませんが、WSL2で動いているKernelにはUSB MassStorageドライバが入っていませんので(ストア配布のUbuntu20.04LTSしか確認していません)、lsusbコマンド等でUSBデバイスとして認識してもデバイスファイルが出現しません。これはKCONFIGを修正してカーネルをリビルトしてあげれば済む簡単な話ですから、早速取り組んでみます。

:::note warn
ここではusbipdの導入については触れません。他の解説記事を参照してください。
:::

### Kernelソースコードを取ってくる

~~~
~$ git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
Cloning into 'WSL2-Linux-Kernel'...
remote: Enumerating objects: 10441428, done.
…
~$ cd WSL2-Linux-Kernel/WSL2-Linux-Kernel/
~~~
お約束通りソースコードをGithubからcloneします。

### menuconfigの実行
~~~
~/WSL2-Linux-Kernel/WSL2-Linux-Kernel$ sudo cp ../Microsoft/config-wsl .config
[sudo] password for user:
~/WSL2-Linux-Kernel/WSL2-Linux-Kernel$ sudo make menuconfig
~~~
WSL2向けのKCONFIGは、cloneしたソースコード中のMicrosoft/config-wslにサンプルとして置いてありますので、これを.configにリネームしてコピーします。 
(ここでは.configファイルの所有者がrootになってしまっていたため手抜きでsudoしていますが)、make menuconfigを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/ba520b0c-dc3d-f9ce-aeaa-a65566c566a2.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/d71eee41-5ff2-c204-a473-c6d66fa00554.png)
[ ]USB Mass Storage supportとなっている行を選択しススペースキーを二回押すと\<*>表示になるかと。これでドライバが組み込まれます。

:::note warn
\<m\>だとカーネルモジュールが生成され、ドライバが含まれないkernelが生成されてしまいます。
WSLではlinuxカーネルに必要なドライバを全部取り込む流儀があるようで、面倒事を避けるためにカーネルモジュール指定は止めておきましょう。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/f1818beb-828e-b641-c7c8-9774eb580c93.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/fee1c073-83ca-902f-dbf7-2df85c6e7673.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/8e232a5e-841d-33e7-30f7-725eaf9c2bdb.png)
.configファイルに保存したら、Exitを数回選んでmenuconfigを終了します。

## カーネルのビルド
makeします。vmlinuxファイルが生成されるのを待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/5fd9fa85-9791-bfe8-e78e-15821eccb1ee.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/fc3ae6fa-9a59-2f94-35e3-33f26ac4ae2c.png)
いったんWindows側にvmlinuxをコピーします。ここではExplorerを用いてC:\にコピーしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/6c19942c-dbb8-154e-014d-bd88ec0aa351.png)

:::note info
カスタムカーネルを置き換える際にwslがvmlinuxファイルをロックしていることかあります。
予めWSL2をシャットダウンしてから作業しましょう。
~~~
C:\Windows\System32>wsl --shutdown

C:\Windows\System32>wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         2
  Ubuntu          Stopped         2

C:\Windows\System32>
~~~

上書きコピーで書き変わっていないといった悲劇を避けるため、上書きせず旧ファイルの削除を確認してからコピーするといった丁寧な作業を心がけると良いと思います。
:::

.wslconfigにkernel=フルパスの形式でvmlinuxの場所を指定します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/24d8a231-3aaf-53d3-ad5f-b855e49fe8c4.png)
WSLのファイルシステム内にvmlinuxを置くことはできないようです。

## WSLを再起動
従前と同じ操作でカスタムカーネルから起動します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/44900a1f-b6f5-8bf9-9206-fe6e7ea4e177.png)
usbipd wsl attach -b n-mm形式で、WSL2にUSBデバイスを接続します。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/f6e7a9cf-dc5d-fd18-d5fe-e25a4bc53ad5.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376652/c032f3dd-e5d3-9ba9-2132-03ac3d11c60d.png)

>Bus 002 Device 002: ID 8564:4000 Transcend Information, Inc. RDF8

ここではTransend製のSDカード(64GiB)が/dev/sdeとして認識されています。
~~~
~$ ls -ar /dev/sd*
/dev/sde2  /dev/sde1  /dev/sde  /dev/sdd  /dev/sdc  /dev/sdb  /dev/sda
~$ fdisk -l
…
Disk /dev/sde: 59.7 GiB, 64088965120 bytes, 125173760 sectors
Disk model: Transcend
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x4db3cb53

Device     Boot  Start     End Sectors  Size Id Type
/dev/sde1  *        32  204831  204800  100M  c W95 FAT32 (LBA)
/dev/sde2       204832 6602975 6398144  3.1G 83 Linux
~$
~~~
~~~
~$ sudo dd if=/dev/sde2 bs=1M status=progress | gzip -c > ddimg.gz
3273654272 bytes (3.3 GB, 3.0 GiB) copied, 254 s, 12.9 MB/s
3124+1 records in
3124+1 records out
3275849728 bytes (3.3 GB, 3.1 GiB) copied, 254.644 s, 12.9 MB/s
~$
~~~

以上です。