はい、miku_JK_Jbです
今回は自作OSをセキュアブートに対応させたり、ブートローダーの機能を大幅に強化した作業を紹介していくよ。
また久しぶりの自作OS関連のブログ更新だな笑
まあ、開発に時間がめっちゃかかるからしょうがないか
まずはセキュアブートとは何なのかについて解説しようか
セキュアブートとはPCが起動する際に、UEFI環境で信頼されたソフトウェアのみの読み込みを許可し、システムを保護するための重要なセキュリティ機能の事だ
また、セキュアブートはUEFIの機能であり、従来のBIOSでは使えない
要するにホテルのルームキーみたいなものと言えば分かりやすいだろうか
自作OSをセキュアブートに対応させると何が良いのか?
セキュアブートに対応させることで、OSが起動する前の最も弱っチー🤓段階で、システム全体のセキュリティと信頼性を守ることができるようになる
主にマルウェアやの実行を阻止することができる
セキュアブートに対応させるために必要な物は?
- UEFIのファームウェア
- 鍵ファイル
- 署名付きのバイナリファイル
- SBAT情報
となっている
意外と少ないでしょ?
それじゃあ順番に解説していこうか
まずはUEFIのファームウェアから解説しよう
これはさっきも書いているが、セキュアブートはUEFIの機能なので、従来のBIOSでは使うことができない。そのためUEFIに対応するマザーボードなどが必要になってくる
次に鍵ファイルについて解説しよう
鍵ファイルはソフトウェアが信頼できる製作者によって作成される改ざんされていないことを証明する認証システムだ
また、鍵ファイルは主に2つで構成される
秘密鍵と公開鍵だ

秘密鍵は自作OSのブートローダーなどのバイナリファイルに製作者が「これは自分が作成したオリジナルのファイルです」と証明するための物だ
また、秘密鍵は絶対に外部に漏らしてはいけない物だ
万が一漏らしてしまうと、第三者が「正規品に見える不正なコード」を作れてしまう
要はぼんくらがパチモンを作っても騙せちゃうってことだな😁
公開鍵は秘密鍵を検証するための物だ
PCを起動するときに、UEFIがブートローダーに付与された秘密鍵を検証する必要があるこの検証をするために秘密鍵に対応する公開鍵がUEFIの「信頼しているデータベースに登録されるのだ
これらを行うことによってUEFIが署名を復号・チェックして、ブートローダーが本物であることを確認するのだ
次に署名付きのバイナリファイルについて解説しよう
これは起動させたいブートローダーなどのソフトウェア自身だ
こいつらはさっき解説した秘密鍵で署名されている必要がある
また、UEFIはこれらのバイナリファイルが読み込まれる際に署名を検証するのだ
最後にSBAT情報について解説しよう
これは既知の脆弱性に対処するために重要となるもので、ブートローダーのバージョン情報を示すメタデータだ。
また、古いブートローダーを無効化させるもので、セキュリティ問題が発見された時に、古いバージョンを「禁止リスト」に登録することで新しい署名鍵を発行しなくても、脆弱性のある古いバージョンでの起動を防ぐものだ
要するに古いバージョンの物を出禁にするってことだな😁
では自作OSをどうやってセキュアブートに対応させたかについて解説しよう
主に行った作業はこんな感じだ
- 鍵ファイルの作成
- SBATセクションの作成
- ブートローダーの署名
- ShimとMokManagerの導入
- 公開鍵の登録
これも意外と少ないでしょ?
これも順番に解説していこうか
まずは鍵ファイルの作成だ
これは秘密鍵と公開鍵を作成した
作成自体は簡単でWSLのコマンドを使用して作成した
ちなみに公開鍵は有効期限を設定する必要があるので15年間有効に設定した
秘密鍵には有効期限が無いが、流出したらすぐに失効する必要がある
次にSBATセクションの作成だ
これも作成自体は簡単でWSLのコマンドを使用して作成した
次にブートローダーの署名だ
これも同じく簡単でWSLのコマンドを使用して署名した
署名する際は秘密鍵と公開鍵、署名したブートローダーの出力先を設定して署名を行う
次にShimとMokManagerの導入だ
Shimはセキュアブートの環境で、自作や配布元が違うブートローダーを起動させるものだ。Ubuntuなども利用している
また、ShimはMicrosoftに署名されているので、セキュアブート有効環境では必ずと言ってもいいくらい起動する
MokManagerは鍵の登録を行う際に使用する。また、MokManagerはShimがロードされる過程で起動する
ただし、ShimとMokManagerは開発時の際に使用し、リリースする際はMicrosoft UEFI Third-Party CAに署名してもらうことにする
Microsoft UEFI Third-Party CAは一般の個人開発者でも受け付けしている
ちなみにMicrosoft UEFI Third-Party CAに署名してもらう際は、ブートローダーをMicrosoftが出している署名条件に満たす必要が出てくる
まあ、私は最初から視野に入れていたから今の状態でも条件を満たしているんだな😁
最後に公開鍵の登録だ
これはPCを起動させて、ShimがMokManagerを起動させる。
起動したMokManagerで公開鍵の登録を行う
ちなみに鍵ファイルを登録したら再起動する必要がある
登録している所は私のYouTubeの動画から見てくださーい
これが自作OSをセキュアブートに対応させるために行った作業だ!!
全体的に簡単な作業が多いというイメージだった
次は自作OSのブートローダーの機能を強化した作業について解説しよう
ブートローダーの機能を強化するために行ったはこんな感じだ
- ELFローダーで.text .data .bssセクションを物理メモリに展開させる処理の追加
- MSx64 ABIからSysV ABIに変換する処理の追加
- ブートローダーのシリアル出力の追加
- スタック領域の確保を行う処理の追加
- CR3に新しいPML4のロードの追加
- SysV ABIに合わせてカーネルを起動させる処理の追加
こんな感じで、かなり大幅にブートローダーの機能を向上させたね
それじゃあ順番に解説していこうか
まずはELFローダーで.text .data .bssセクションを物理メモリに展開させる処理の追加について解説していこう
これはELF形式のカーネルを解析して、実行に必要なセクションを正しい物理アドレスに配置するようにした
これを行うことにより、実際にカーネルが期待するメモリのレイアウト再現することができ、カーネルがデータなどに正しくアクセスすることができるようになる
また、.textセクションはカーネルが行う命令で、.dataセクションは初期値を持つグローバル変数や、静的変数が格納されたもので、.bssセクションは初期値を持たないグローバル変数や、静的変数が書くのされたもの
次はMSx64 ABIからSysV ABIに変換する処理の追加について解説しよう
これはUEFIは、MSx64 ABIで動いているが、自作OSのカーネルはSysV AVIを前提に書いているので、この差をなくすためにMSx64 ABIからSysV ABIに変換する処理だ
これを行うことにより、カーネルがUEFIに縛られずに移植性や拡張性が上がるのだ
次はブートローダーのシリアル出力の追加について解説しよう
これは元々実装してあったが、エラーが発生した際にしか表示されなかったが、
今回の変更によって、ブートローダーの処理がどこまで進んだかを分かるようにした
次はスタック領域の確保を行う処理の追加について解説しよう
これはカーネルの実行用の専用スタックを確保し、カーネルにジャンプする前にRSPを切り替える処理だ
RSPとは64bit環境のCPUで、スタックポインタとして機能する汎用型のレジスタの事だ。また、スタックはメモリ上に確保される特別なデータ構造だ
カーネル実行用のスタックを確保することにより、UEFI側のスタックを汚さずに済んで、カーネルが安定して動作し、カーネル側の関数の呼び出しや割り込み処理の基礎が整う
次はCR3に新しいPML4のロードの追加について解説しよう
これは自作のページテーブルをCPUに適用させて、仮想アドレス空間をカーネル用に切り替える処理だ
CR3とは主にIntel,AMDのCPUが持つコントロールレジスタの1つで、メモリ管理においてとても重要な役割を持っている。また、主にページングや仮想アドレス空間の切り替えを行う
PML4はx86_64で使用される、ページングの構造の最上位レベルのテーブルだ
レクサスで言うLSってとこだな😁
次はSysV ABIに合わせてカーネルを起動させる処理の追加について解説しよう
これは今まではただカーネルのアドレスにジャンプさせるだけで、カーネルを起動させていたが、今回からはSysV ABIの規約に従って引数をレジスタにセットし、カーネルを起動させるように変更した
これにより、カーネルが期待通りの初期引数を受け取り、初期化や描画処理などを自力で始めることができるようになる
これがブートローダーの機能を大幅に強化した作業だ!!
実際にブートローダーが動くとこんな感じになる

ちなみに赤・黄・水色・紫・オレンジ色の小さい四角が表示されているが、
これはブートローダーの処理ががどこまで進んだかを簡単に分かるようにしている
ちなみに画像ではカーネルは起動していない
理由は

_人人人人人人人人人人人人人人人_
> カーネルパニックを起こした <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄
ってことで次回カーネルパニックを直して画面を描画できるようになった乞うご期待
ということで以上miku_JK_Jbでした