東京工業大学「システム開発プロジェクト応用第二」第一回前半 環境構築メモ
現在、東京工業大学から自作OSの講義動画が公開されている。
どうやらこの講義を担当している特任助教は『ゼロからのOS自作入門』の著者でもあるらしく同著を教科書として採用しているらしい。
『ゼロからのOS自作入門』は既に予約してあるが、せっかくなので暇を見て少しづつ講義動画の方も追ってみようと思います。
ただ、解説として必要な点は概ね講義中に網羅されているだろうし書籍に載っているであろう情報を書いてもしょうがないので記事には躓いた点をピックアップする形で進めていきます。
この記事で取り扱う範囲
講義ではブートローダーの作成ぐらいまでやっているようですが自分がやっているのは
・実行環境の構築
・イメージファイルの作成
くらいなので(大体動画50分くらい)そこだけ取り扱います。
BOOTX64.EFI(Hello, worldプログラム)の作成
EFIファイルってなに?とかそこら辺の話は『ゼロから作るOS自作入門』に書いてあるらしい。
後の方の講義で解説されるかもしれないのでここでは特に解説しません。
ファイルそのものは著者のリポジトリに置いてある。
ダウンロードしてしまうのが一番手っ取り早いと思う。
名前がhello.efiになっているのでBOOTX64.EFIに変更しておく。
名前を変更しないと『Hello, world!』と表示されるべき場所に『>>Start PXE over IPv4』と表示されてしまう。(何を意味しているのかは分からない)
恐らくファイルには命名規則があるのだと思う。
余談ですがバイナリエディタで手打ちするのは結構しんどいです。
イメージファイルの作成
イメージファイルそのものについてはここらへんを見れば十分だと思います。
https://wa3.i-3-i.info/word15853.html
リンク先を見るのが面倒な人用に誤解を恐れずにまとめると『ファイルをまとめたファイル』(ISOイメージファイルの場合はCD/DVD用)です。
『ファイルをまとめたファイル』という字面は一見すると奇妙ですが圧縮していないZIPファイルみたいなものだと捉えていれば今回の作業には困らないと思います。
また、今回作成したイメージファイルの拡張子は.imgとなっています。
これは歴史的にはフロッピー用みたいですが、現在は何にでも使えるイメージファイルという使われ方をするみたいです。(要調査)
実際に行う作業は講義動画にも出ていますが,下記の通りです。
このコマンドを実行することで
①disk.imgという200MBのイメージファイルを作成
②disk.imgの中に/EFI/BOOT/というディレクトリを作成
③BOOTX64.EFIを書き込む
という処理をしています。(①と②と③の境界は私が適当に決めました)
備忘録も兼ねて各コマンドが何をしているのかすごく簡単に解説します。
qemu-img create -f raw disk.img 200M
disk.imgという200MBのイメージファイルを作成している。
・オプションについて
-f format:フォーマットを指定するオプション。デフォルトでformatはrawなので無くても動く。
mkfs.fat -n 'MIKAN OS' -s 2 -f 2 -R 32 -F 32 disk.img
イメージファイルにファイルシステムを作成している。
イメージファイルは『ファイルをまとめたファイル』ですが、ファイルのまとめ方(ファイルシステム)にもいろいろ存在している。
ここで使用しているのはFAT32。
後の方にファイルシステムの講義があると思うので詳細はその時まで放置。
https://wa3.i-3-i.info/word17344.html
mkfs.fatで一つのコマンド。
/usr/sbinとかをみるとほかのファイルシステム用のコマンドも見つかる。
mkfsというコマンドも存在するが、どうやら他のファイルシステムを作成するコマンドを実行するコマンドっぽい?
多分mkfsでも作成できるんじゃないかと思う。
・オプションについて
-n:ボリューム(論理的な記憶領域)に11文字以下の名前を付けるオプション。デフォルトでは付けない。どこに名前が保存されるのかはわからなかった。
-s:1クラスタ(FATの記憶単位)を構成するセクタ(物理的な記憶単位)の数を指定するオプション。デフォルト動作はよくわからなかった。
-f:file allocation tableの作成個数を指定するオプション。デフォルトでは2。1だと多分不整合が起きたときにマズいんだろうと思う。
-R:Reserved sectors areaの設定らしいがよくわからなかった。デフォルトは32。ブートセクタは1らしい。
-F:FAT12、FAT16、FAT32からどれを使うのか指定するオプション。デフォルト動作はよくわからない。
mkdir -p mnt
マウントポイントを作成している。
Windowsだと外部記憶装置は(E:)とか勝手に名前を決めてくれるが、Linuxとかだと自分で名前を決めなきゃいけない(多分)。
・オプションについて
-p:『ディレクトリの中のディレクトリ』みたいなディレクトリを作る際に、存在しないディレクトリを全て作ってくれるオプション。ここでは必要ないはず。何か意図があるのかもしれない。
sudo mount -o loop disk.img mnt
さっき作成したmntディレクトリにdisk.imgをマウントしている
・オプションについて
-o:オプションを使用するというオプション(冗談みたいだがそう読める)。loopを指定するとループデバイスとして認識する。ざっくりいうと、本当は物理デバイスに書き込んでから読み書きするところをイメージファイルに直接読み書きできるようになる。
sudo mkdir -p mnt/EFI/BOOT
sudo cp BOOTX64.EFI mnt/EFI/BOOT/BOOTX64.EFI
sudo umount mnt
いわずもがな
実行環境の構築
この記事では
・VirtualBox on Windows
・QEMU on WSL2
・QEMU on Ubuntu Desktop 20.04.2.0 LTS
・実機(LB-J772X-SH2-KK)
で作成したイメージファイルを実行した。
個人的にオススメはQEMU on WSL2。
VirtualBox on Windows
適当にダウンロード
新規作成しようとするとタイプとバージョンを聞かれるので
タイプ:Other
バージョン:Other/Unknown(64-bit)
で動作した。他は雰囲気で作成。
あと設定→システムから拡張機能の『EFIを有効化(一部のOSのみ)』を有効化しておきます。
起動するとコントロールを奪われます。復帰は右CTRLです。
次に作成したimgファイルをUEFI BIOSが参照できる場所に配置します。
ただ、imgファイルを読み込もうとすると『ディスクイメージファイルを開けませんでした。』とか『VERR_NOT_SUPPORTED』などと言われてエラーになります。
そこで以下のコマンドでイメージファイルをiso形式(光学ドライブ)とvdi形式(VirtualBox用HDD)に変換しました。
・iso形式
$ mv disk.img disk.iso
・vdi形式
$ qemu-img convert -f raw -O vdi disk.img disk.vdi
基本的に作成したイメージファイルはどのストレージデバイスに載せても動きます。
ただ、USBだけはうまく認識してくれませんでした。(理由不明)
また、UEFI Internal Shellの優先順位が他のデバイスより高い場合は以下の様な画面が表示されました。
exitを実行するとUEFIの設定画面が開くので
Boot Maintenance Manager -> Boot Options -> Change Boot Order
から優先順位を変更すれば起動できました。
QEMU on WSL2
WSL2でQEMUを使うためにインストールしたものは以下の四つです。
・qemu-system-x86 (qemu-system-x86_64)
・ovmf (OVMF_CODE.fd, OVMF_VARS.fd)
OVMF_CODE.fdとOVMF_VARS.fdは/usr/share/OVMF/の中に存在する。
/usr/share/ovmf/というディレクトリもなぜか作られていた。
しかし中にはOVMF_CODE.fdもOVMF_VARS.fdもなかった。
代わりに何かの鍵(pem)が入っていた。
ただし、上記の四つをインストールしただけではX Window Systemが存在しないので
gtk initialization failed
というエラーを起こす。
WSL2でX Window Systemを使うためにはWindows側で設定が必要です。
基本的にここの通りにしたらうまくいきました。
ただ、Extra settingsはいじってあります。
libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast
と怒られます。(実行はしてくれます)
残りのパラメータを変えたときの挙動は結構不安定で、QEMUが認証エラーを返す時もあればQEMUは起動はするけど何も表示されないという時もありました。(スクショとれず)
Xserverが起動出来たらネットワークの設定をしてやるとHello, world!が表示されました。
QEMU on Ubuntu Desktop 20.04.2.0 LTS
基本的にWSL2と同じです。
X Window Systemがデフォルトで入ってるのでそこら辺の設定をしなくても動きます。
実機
実行できませんでした。
Secure Boot Violation
Invalid signature detected. Check Secure Boot Policy in Setup
というエラーが出ます。
なんとなく言ってることは分かりますが解決方法は分かりません。
おまけ
Ubuntu 20.04.2.0.LTSに/EFI/BOOT/BOOTX64.EFI相当のファイルが存在するか確認した。
どうやらUbuntu 20.04.2.0.LTSにはそもそも/EFIが存在しないらしい。
ただし/boot/efiというディレクトリがあり、その中には確かにEFI/Boot/bootx64.efiが存在していた。