東京工業大学「システム開発プロジェクト応用第二」第一回前半 環境構築メモ

現在、東京工業大学から自作OSの講義動画が公開されている。

 

www.youtube.com

 

どうやらこの講義を担当している特任助教は『ゼロからのOS自作入門』の著者でもあるらしく同著を教科書として採用しているらしい。

 

www.amazon.co.jp

 

『ゼロからのOS自作入門』は既に予約してあるが、せっかくなので暇を見て少しづつ講義動画の方も追ってみようと思います。

ただ、解説として必要な点は概ね講義中に網羅されているだろうし書籍に載っているであろう情報を書いてもしょうがないので記事には躓いた点をピックアップする形で進めていきます。

 

この記事で取り扱う範囲

f:id:ymzkmtfm:20210305160038p:plain

目標とやること

講義ではブートローダーの作成ぐらいまでやっているようですが自分がやっているのは

・実行環境の構築

・イメージファイルの作成

くらいなので(大体動画50分くらい)そこだけ取り扱います。

 

BOOTX64.EFI(Hello, worldプログラム)の作成

EFIファイルってなに?とかそこら辺の話は『ゼロから作るOS自作入門』に書いてあるらしい。

後の方の講義で解説されるかもしれないのでここでは特に解説しません。

 

ファイルそのものは著者のリポジトリに置いてある。

 

github.com

 

ダウンロードしてしまうのが一番手っ取り早いと思う。

名前がhello.efiになっているのでBOOTX64.EFIに変更しておく。

名前を変更しないと『Hello, world!』と表示されるべき場所に『>>Start PXE over IPv4』と表示されてしまう。(何を意味しているのかは分からない)

恐らくファイルには命名規則があるのだと思う。

 

f:id:ymzkmtfm:20210305143850p:plain

hello.efiのまま実行した結果

 

余談ですがバイナリエディタで手打ちするのは結構しんどいです。

 

イメージファイルの作成

 

イメージファイルそのものについてはここらへんを見れば十分だと思います。

 

https://wa3.i-3-i.info/word15853.html

ja.wikipedia.org

 

リンク先を見るのが面倒な人用に誤解を恐れずにまとめると『ファイルをまとめたファイル』(ISOイメージファイルの場合はCD/DVD用)です。

『ファイルをまとめたファイル』という字面は一見すると奇妙ですが圧縮していないZIPファイルみたいなものだと捉えていれば今回の作業には困らないと思います。

また、今回作成したイメージファイルの拡張子は.imgとなっています。

これは歴史的にはフロッピー用みたいですが、現在は何にでも使えるイメージファイルという使われ方をするみたいです。(要調査)

 

ja.stackoverflow.com

 

実際に行う作業は講義動画にも出ていますが,下記の通りです。

f:id:ymzkmtfm:20210305171803p:plain

イメージファイルの作成

このコマンドを実行することで

①disk.imgという200MBのイメージファイルを作成

②disk.imgの中に/EFI/BOOT/というディレクトリを作成

③BOOTX64.EFIを書き込む

という処理をしています。(①と②と③の境界は私が適当に決めました)

備忘録も兼ねて各コマンドが何をしているのかすごく簡単に解説します。

 

qemu-img create -f raw disk.img 200M

access.redhat.com

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

ja.wikipedia.org

 

mkfs.fatで一つのコマンド。

/usr/sbinとかをみるとほかのファイルシステム用のコマンドも見つかる。

mkfsというコマンドも存在するが、どうやら他のファイルシステムを作成するコマンドを実行するコマンドっぽい?

多分mkfsでも作成できるんじゃないかと思う。

 

・オプションについて

-n:ボリューム(論理的な記憶領域)に11文字以下の名前を付けるオプション。デフォルトでは付けない。どこに名前が保存されるのかはわからなかった。

-s:1クラスタ(FATの記憶単位)を構成するセクタ(物理的な記憶単位)の数を指定するオプション。デフォルト動作はよくわからなかった。

-f:file allocation tableの作成個数を指定するオプション。デフォルトでは2。1だと多分不整合が起きたときにマズいんだろうと思う。

-R:Reserved sectors areaの設定らしいがよくわからなかった。デフォルトは32。ブートセクタは1らしい。

en.wikipedia.org

-F:FAT12FAT16FAT32からどれを使うのか指定するオプション。デフォルト動作はよくわからない。

 

mkdir -p mnt

マウントポイントを作成している。

Windowsだと外部記憶装置は(E:)とか勝手に名前を決めてくれるが、Linuxとかだと自分で名前を決めなきゃいけない(多分)。

 

・オプションについて

-p:『ディレクトリの中のディレクトリ』みたいなディレクトリを作る際に、存在しないディレクトリを全て作ってくれるオプション。ここでは必要ないはず。何か意図があるのかもしれない。

 

sudo mount -o loop disk.img mnt

さっき作成したmntディレクトリにdisk.imgをマウントしている

 

・オプションについて

-o:オプションを使用するというオプション(冗談みたいだがそう読める)。loopを指定するとループデバイスとして認識する。ざっくりいうと、本当は物理デバイスに書き込んでから読み書きするところをイメージファイルに直接読み書きできるようになる。

xtech.nikkei.com

 

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

適当にダウンロード

www.virtualbox.org

新規作成しようとするとタイプとバージョンを聞かれるので

タイプ:Other

バージョン:Other/Unknown(64-bit)

で動作した。他は雰囲気で作成。

あと設定→システムから拡張機能の『EFIを有効化(一部のOSのみ)』を有効化しておきます。

起動するとコントロールを奪われます。復帰は右CTRLです。

 

次に作成したimgファイルをUEFI BIOSが参照できる場所に配置します。

ただ、imgファイルを読み込もうとすると『ディスクイメージファイルを開けませんでした。』とか『VERR_NOT_SUPPORTED』などと言われてエラーになります。

f:id:ymzkmtfm:20210306042509p:plain

イメージファイルの読み込みエラー

そこで以下のコマンドでイメージファイルをiso形式(光学ドライブ)とvdi形式(VirtualBox用HDD)に変換しました。

 

・iso形式

$ mv disk.img disk.iso

 

・vdi形式

$ qemu-img convert -f raw -O vdi disk.img disk.vdi

 

docs.openstack.org

 

基本的に作成したイメージファイルはどのストレージデバイスに載せても動きます。

ただ、USBだけはうまく認識してくれませんでした。(理由不明)

 

また、UEFI Internal Shellの優先順位が他のデバイスより高い場合は以下の様な画面が表示されました。

f:id:ymzkmtfm:20210306043703p:plain

UEFI Internal Shell

exitを実行するとUEFIの設定画面が開くので

Boot Maintenance Manager -> Boot Options -> Change Boot Order

から優先順位を変更すれば起動できました。

f:id:ymzkmtfm:20210306044957p:plain

Virtual BoxでHello, world!

 

QEMU on WSL2

 WSL2でQEMUを使うためにインストールしたものは以下の四つです。

qemu-utils (qemu-img)

qemu-system-x86 (qemu-system-x86_64)

qemu (QEMU本体)

・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

というエラーを起こす。

 

f:id:ymzkmtfm:20210306053508p:plain

X Window Systemを使えない場合のエラー

 

WSL2でX Window Systemを使うためにはWindows側で設定が必要です。

基本的にここの通りにしたらうまくいきました。

 

qiita.com

 

ただ、Extra settingsはいじってあります。 

f:id:ymzkmtfm:20210306144309p:plain

Extra settings

Native openglにチェックを入れるとQEMU

libGL error: No matching fbConfigs or visuals found
libGL error: failed to load driver: swrast

と怒られます。(実行はしてくれます)

f:id:ymzkmtfm:20210306144607p:plain

Native opengl にチェックを入れた場合のエラー

 

残りのパラメータを変えたときの挙動は結構不安定で、QEMUが認証エラーを返す時もあればQEMUは起動はするけど何も表示されないという時もありました。(スクショとれず)

Xserverが起動出来たらネットワークの設定をしてやるとHello, world!が表示されました。

f:id:ymzkmtfm:20210306150015p:plain

ネットワークの設定

f:id:ymzkmtfm:20210306150034p:plain

QEMUで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

というエラーが出ます。

なんとなく言ってることは分かりますが解決方法は分かりません。

f:id:ymzkmtfm:20210306051635j:plain

Secure Boot Violation

おまけ

Ubuntu 20.04.2.0.LTSに/EFI/BOOT/BOOTX64.EFI相当のファイルが存在するか確認した。

どうやらUbuntu 20.04.2.0.LTSにはそもそも/EFIが存在しないらしい。

ただし/boot/efiというディレクトリがあり、その中には確かにEFI/Boot/bootx64.efiが存在していた。

f:id:ymzkmtfm:20210306053338p:plain

/boot/efi/EFI/Boot/bootx64.efi