背景・モチベーション
低レイヤを理解したいというのは、ソフトウェアエンジニアをやっていると、どうしても沸き起こってしまう感情なのではと思ったりします。
自分は工学部出身ですが、コンピュータサイエンスを専門とした学科ではなかったので電子回路とかを除くとC言語くらいしか情報系の授業は受けておらず、OSの仕組みとかは全然知りません。
7月末に退職し8月から新しい会社で働くことになるのですが、有給だったりで約1ヶ月間のお休みができたので、この機会に、DMMセールのときに購入し積んでいたみかん本をやるぞと思い立ちました。
WSL1を使うに至った経緯
2015年に買ってずっと眠らせていたSurface3を引っ張り出し、Windowsのバージョンを最新化してWSL2をセットアップしようとしました。
指定された手順を行っていきましたが、特にエラーなど起こることなく完了しました。ubuntuを起動しようとしたときに、 Installation failed with error 0x80070003 or error 0x80370102
というエラーメッセージが出力され起動に失敗しました。
ドキュメントを確認したところ、下記のように記載がありました
「これからBIOSを学ぶってときにBIOSをいじるんか…」と思いつつ、ここを見ながらBIOSの画面に飛んだ。が、Virtualizationの項目は特にない。調べたところSurfaceでは元々Virtualizationは有効になっているらしい。
「タスクマネージャ」の「パフォーマンス」タブの「仮想化」の欄を見たら、ちゃんと有効になっていた。
ではHyper-Vの要件を満たしていない…?と思い確認してみる。powershellで Systeminfo.exe
を実行してみた。Hyper-Vの要件を満たしているかは一番最後に出てきますが、全てが「はい」になっていることが確認できた。
WSLのGitHubのIssueやRedditを見つつ色々やりましたが駄目でした。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として既にどなたかが挙げてくださっていました。とてもありがたい…。
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 +
やっとこさ進める状態になったので、ちょっとずつ進めていこう