1クール続けるブログ

とりあえず1クール続けるソフトウェアエンジニアの備忘録

WSL1でみかん本を進める上で躓いたところ

背景・モチベーション

低レイヤを理解したいというのは、ソフトウェアエンジニアをやっていると、どうしても沸き起こってしまう感情なのではと思ったりします。
自分は工学部出身ですが、コンピュータサイエンスを専門とした学科ではなかったので電子回路とかを除くとC言語くらいしか情報系の授業は受けておらず、OSの仕組みとかは全然知りません。
7月末に退職し8月から新しい会社で働くことになるのですが、有給だったりで約1ヶ月間のお休みができたので、この機会に、DMMセールのときに購入し積んでいたみかん本をやるぞと思い立ちました。

WSL1を使うに至った経緯

2015年に買ってずっと眠らせていたSurface3を引っ張り出し、Windowsのバージョンを最新化してWSL2をセットアップしようとしました。
指定された手順を行っていきましたが、特にエラーなど起こることなく完了しました。ubuntuを起動しようとしたときに、 Installation failed with error 0x80070003 or error 0x80370102 というエラーメッセージが出力され起動に失敗しました。

ドキュメントを確認したところ、下記のように記載がありました

  • Please make sure that virtualization is enabled inside of your computer's BIOS
  • WSL2 requires that your CPU supports the Second Level Address Translation (SLAT) feature, which was introduced in Intel Nehalem processors (Intel Core 1st Generation) and AMD Opteron.

「これからBIOSを学ぶってときにBIOSをいじるんか…」と思いつつ、ここを見ながらBIOSの画面に飛んだ。が、Virtualizationの項目は特にない。調べたところSurfaceでは元々Virtualizationは有効になっているらしい。
「タスクマネージャ」の「パフォーマンス」タブの「仮想化」の欄を見たら、ちゃんと有効になっていた。

ではHyper-Vの要件を満たしていない…?と思い確認してみる。powershellSysteminfo.exeを実行してみた。Hyper-Vの要件を満たしているかは一番最後に出てきますが、全てが「はい」になっていることが確認できた。

WSLのGitHubのIssueRedditを見つつ色々やりましたが駄目でした。Hyper-VはWSL2利用時には明示的に入れなくても良いと書いてありましたが、Windowsのイベントログには「Hyper-Vがインストールされていないため、仮想マシンの作成に失敗しました」と出力されていたので、Hyper-Vもインストールしましたが同じエラーが出てしまい八方塞がりになってしまいました。

もうこれはWSL1で動かすしかないと諦めて、WSL1で進めていくことにしました。

WSL1で躓いたところ

USBに書き込んでそこから起動させる方式ではなく、QEMUで起動させる方式を自分は取りました

ディスクイメージをマウント出来ない

BOOTX64.EFIのファイルを作成し、ディスクイメージに書き込むために mnt ディレクトリを作成しマウントさせようとしましたが下記のようにエラーとなりました。

$ sudo mount -o loop disk.img mnt
mount: ./mnt: mount failed: Operation not permitted.

こればWSL1と2でシステムコールファイルシステムの扱い方が違うからなのかな(参考)と思いつつ調べていたところ、GithubのIssueとして既にどなたかが挙げてくださっていました。とてもありがたい…。

github.com

mtoolsを利用することで、wsl1でもディスクイメージにファイルの書き込みが出来るようです。Issueの中ではubuntuに元々入っているということでしたが、自分が動かしているWSL1のUbuntu 20.04には入っていなかったので apt 経由でインストールしました。
下記のような手順でディスクイメージにファイルをコピーすることができました!

$ sudo apt install mtools
$ mmd -i disk.img ::/EFI
$ mmd -i disk.img ::/EFI/BOOT
$ mcopy -i disk.img BOOTX64.EFI ::/EFI/BOOT/BOOTX64.EFI

$HOME/osbook/devenv/make_image.sh の中身のマウント部分の処理も上記のように変更しておくと、後々もいい感じです。

仮想マシンで生成されたファイルの中身が見れない

P61のメモリマップを出力した後にファイルを確認するときの手段についてです。上に関連した話になっています。
run_qemu.shを動かしたディレクトリにdisk.imgが作成されていますが、マウントして観ることはできないのでmtoolsを利用します。

# ファイルの存在確認
mdir -i disk.img ::/ 

# ファイルをコピーして確認する
mcopy -i disk.img ::/memmap ./memmap
less memmap

番外編: QEMUが動かない

これはWSL1であること由来ではありません。なんらかの理由でansibleの実行で一部上手くいかないと起こる事象のようです。
qemu-system-x86_64 を実行すると、Unable to init server: Could not connect: Connection refusedというエラーメッセージが出力されてしまいました。XLaunchが起動していることは確認済の状態です。

下記のように作業すると解決しました(参考
DISPLAY という環境変数はXサーバが利用するもののようです(参考
xhostはXサーバへの接続許可リストに追加するコマンドっぽいのですが、Xサーバの仕組み周りを自分が理解していないのでよく分からないまま利用している状態です。普段使いはWindowsではないので、あまり深追いはしないつもりです。

$ sudo apt install x11-xserver-utils
$ export DISPLAY=:0
$ xhost +

やっとこさ進める状態になったので、ちょっとずつ進めていこう