WSL2でもddを使いたいっ!
WSL/WSL2にはSDカードのddイメージを作成したり書き込んだりするのに使う/dev/sd?とか、/dev/mmcblk?といったデバイスファイルが存在しません。
Cドライブに直接ファイルアクセスするだけなら/mnt/cを見に行けばよいという話があります。
Powershell上で\.\PHYSICALDRIVEm形式でドライブを特定できる場合は、wsl --mount またはwsl --mount --bareといったコマンドでWSL2環境にアタッチすることができるようです。
ですが、リムーバブルディスクであるSDカードはUSB-SDアダプタなどを介してPCに接続してもアタッチ可能なリストには出現しません。(Windowsからはドライブとして認識していても、です)
となると、usbipd-winを用いてUSBデバイスをWSL2に接続する方法を取るしかありませんが、WSL2で動いているKernelにはUSB MassStorageドライバが入っていませんので(ストア配布のUbuntu20.04LTSしか確認していません)、lsusbコマンド等でUSBデバイスとして認識してもデバイスファイルが出現しません。これはKCONFIGを修正してカーネルをリビルトしてあげれば済む簡単な話ですから、早速取り組んでみます。
ここでは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を実行します。
[ ]USB Mass Storage supportとなっている行を選択しススペースキーを二回押すと<*>表示になるかと。これでドライバが組み込まれます。
<m>だとカーネルモジュールが生成され、ドライバが含まれないkernelが生成されてしまいます。
WSLではlinuxカーネルに必要なドライバを全部取り込む流儀があるようで、面倒事を避けるためにカーネルモジュール指定は止めておきましょう。
.configファイルに保存したら、Exitを数回選んでmenuconfigを終了します。
カーネルのビルド
makeします。vmlinuxファイルが生成されるのを待ちます。
いったんWindows側にvmlinuxをコピーします。ここではExplorerを用いてC:\にコピーしています。
カスタムカーネルを置き換える際に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の場所を指定します。
WSLのファイルシステム内にvmlinuxを置くことはできないようです。
WSLを再起動
従前と同じ操作でカスタムカーネルから起動します。
usbipd wsl attach -b n-mm形式で、WSL2にUSBデバイスを接続します。
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
~$
以上です。