1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

高校生の間に自作OSの開発はどこまで進んだのか?

1
Posted at

はい、miku_JK_Jbです。

今回は高校生の間に自作OSの開発はどこまで進んだのかについて話していくよ

現状はこんな感じに動作する
20260322_143613470_iOS.jpg

前回のブログやYouTubeで紹介したように、起動した後にライブラリの改変を一切していないFreeTypeが起動して、多言語で「こんにちは 世界」が描画されるようになっているよ。また、高校生の間にxHCIのUSBドライバを自作した

今の自作OSの処理の流れはこんな感じ
まずはブートローダーの処理の流れから

ブートローダーが起動

Simple File Systemを開いて起動ドライブのルートを取得

起動ドライブの BlockIo を取得

FAT32 を読んで自作OSのRootの位置を特定

起動ボリュームの内容をスナップショット(1GB, 512MB, 386MB, 256MBと段階的にフォールバック)

GOP を取得して、画面情報 FrameBufferConfig を作成

必要なら BltOnly ではない描画可能モードへ切り替え

自作OSのカーネルを読み込む

ELF を解析して、high-half カーネルセグメントを物理メモリ上に展開

カーネルのエントリポイント、配置先物理アドレス、仮想ベースアドレス、サイズを確定

handoff バッファを作成

handoff バッファにUEFIメモリマップ, BootVolume, UefiMemoryMap, BootFileTable

プリロードの設定ファイルを読み込んで、必要な共有ライブラリなどを読み込んで、BootFileTableに登録

新しいページテーブルを作成

物理メモリの identity map と high-half direct map を作る

カーネル本体、フレームバッファ、handoff 領域もそのページテーブルにマップ

カーネル用の一時スタックを確保

ExitBootServices を実行して UEFI のブートサービスを終了

CR3 を新しいページテーブルへ切り替える

handoff の high-half アドレスを引数にして、カーネルエントリへジャンプ

カーネル側が handoff を読んで初期化開始

これがブートローダーの処理の流れだ

次はカーネルの処理の流れを紹介する

ブートローダーから handoff を受け取ってカーネルメインが開始

シリアル初期化

handoff のアドレスを検証

HandoffHeader を読み取り、マジック番号とバージョンを検証

handoff から以下の情報を復元(UEFIメモリマップ, FrameBufferConfig,  BootVolume,  UefiMemoryMap, BootFileTable)

ブートローダーが作ったページテーブル情報を引き継ぐ

BootVolume.snapshot の領域を identity map + linear map する

IDT を再初期化

FPU / SSE / XCR0 を初期化

システムコールテーブルを初期化

自作の動的リンカーの IRELATIVE 再配置を確定

syscall 機構を初期化

glibc / FreeType 用の TLS 領域を確保して FS ベースを設定

VFS(仮想ファイルシステム) を初期化

PCI を初期化

VFS のディスクルートを自作OSのRootに設定

BootVolume を使ってディスクバックド VFS を接続

フレームバッファを初期化

自作の動的リンカーを初期化

ブートローダーから渡された BootFileTable を自作の動的リンカーに登録

システムライブラリをロード

ユーザー空間や必要な共有ライブラリが使えるか確認

ユーザー空間のグラフィックを初期化

GUI が使える場合はデスクトップ環境を初期化

設定されているデスクトップUIのモードを呼ぶ

デスクトップUIの描画

多言語デモの実行

これがカーネルの処理の流れだ

ブートローダーは高校1~高3まで
ブートローダーはセキュアブートに対応している。

カーネルも高1~高3まで開発してここまで出来た。
とはいってもカーネルの開発は主に高3だったけどね
xHCIのUSBドライバは合間に作ってた感じだね
通信制の高校だったので、かなり時間には余裕があった

特にブートローダーと動的リンカーの作成で気が狂いそうになった。

ブートローダーでは、スナップショットを取得してカーネル側で1次キャッシュ(L1)として使用するのだが、EFIのメモリやスタック不足による start_image() Out of Resourcesに悩まされた。今では1GB, 512MB, 386MB, 256MBに段階的にフォールバックするようにしている。
また、ブートローダーの機能を盛り込み過ぎてもstart_image() Out of Resourcesが出てしまうので、どこを消そうか、どこを残そうかの取捨選択で迷った。

動的リンカーでは、FreeTypeはLinux上で動く前提で作られているので、mallocもerrnoも当然あるものとして呼んでくる。なので自作OSに自前で実装したが、動かせるまでが大変だった。さらにglibcが使っているIFUNCという仕組みがあり、CPUの環境に応じて最適な実装を実行時に切り替える機能があるのだが、これをカーネル環境でそのまま呼ぶとクラッシュするので、安全な実装に差し替える処理を実装したり、FreeTypeだけじゃなく、FreeTypeの依存ライブラリlibz, libpng, brotli, harfbuzzをロード順を間違えただけでもクラッシュする。などといった。Linux互換の壁を非常に感じた。

今後は自作OSに高校の間に作成したxHCIのUSBドライバをぶち込んで、マウスやキーボードに対応したり、Linuxアプリなどを動かせるようにしていきたい。
あとはインターネットに接続できるようにしたりとかね

これが高校生の間に自作OSの開発がどこまで進んだのかについて解説するブログでした
と言うことで以上miku_JK_Jbでした

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?