『ゼロからの自作OS入門』を読む
gBS ってなんだ?
global 変数のブートサービスのことっぽい
みかん本: アドレスとポインタ
2章:EDK2 とメモリマップ
EDK2 とはUEFIの開発キット
Loader.inf でエントリーポイントが設定できる
言い換えればどの関数を最初に呼び出すかを設定できる
Conf/Target.txt の設定
ACTIVE_PLATFORM に指定するのは MikanLoaderPkg/MikanLoaderPkg.dsc
ここで指定する設定ファイルはパソコンはこういう部品で作られてるよ、とかが設定してあるファイル
より具体的にはプラットフォームなどを指定できるテキストファイル
プロセッサタイプ、チップセット、メモリ構成、周辺機器など
TARGET に指定するのは DEBUG
これはリリースとかだとまた変わる
TARGET_ARCH に指定するのは X64
32 bit とか arm とかだとまた変わるのかな?
64 bit の amd だと全部 X64 だと思う
TOOL_CHAIN_TAG に指定するのは CLANG38
コンパイラ、リンカー、その他のビルドツールを選択する場所
GitHub - uchan-nos/mikanos at osbook_day02b
メモリマップ
メモリマップをファイルに書き出すまでの流れ
UEFI からメモリマップを受け取る
そのメモリマップをファイルに書き出す
なぜファイルに書き出すかというと、現代のメモリは揮発性メモリであり、メモリ上にデータを置いておくと消えちゃうから
メモリマップにはメモリ上の各領域のメタデータが入ってる
どこからどこまでの領域がなんのためのメモリとして割り当てられているか
3 章:画面表示の練習とブートローダ
GitHub - uchan-nos/mikanos at osbook_day03a
コンパイルとリンク
カーネルの実行ファイル kernel.elf を生成してる
カーネルが読み込まれるまでの流れでいうと下記の順
UEFI -> Main.c 呼び出し -> カーネル呼び出し
ブートローダからピクセルを描く
GitHub - uchan-nos/mikanos at osbook_day03b
Graphics Output Protocol = GOP
UEFI の GOP で描画に必要な情報が得らる
得られる情報
フレームバッファの先頭アドレス
フレームバッファの表示領域の幅と高さ
フレームバッファの非表示領域を含めた幅
余分な幅が存在する場合がある
ピクセルのデータ形式
GOP で画面に情報書き込んでる処理はこれ
code:c
EFI_GRAPHICS_OUTPUT_PROTOCOL* gop;
OpenGOP(image_handle, &gop);
Print(L"Resolution: %ux%u, Pixel Format: %s, %u pixels/line\n",
gop->Mode->Info->HorizontalResolution,
gop->Mode->Info->VerticalResolution,
GetPixelFormatUnicode(gop->Mode->Info->PixelFormat),
gop->Mode->Info->PixelsPerScanLine);
Print(L"Frame Buffer: 0x%0lx - 0x%0lx, Size: %lu bytes\n",
gop->Mode->FrameBufferBase,
gop->Mode->FrameBufferBase + gop->Mode->FrameBufferSize,
gop->Mode->FrameBufferSize);
UINT8* frame_buffer = (UINT8*)gop->Mode->FrameBufferBase;
for (UINTN i = 0; i < gop->Mode->FrameBufferSize; ++i) {
frame_bufferi = 255; // ここで画面真っ白にしてる
}
カーネルからピクセルを描く
GitHub - uchan-nos/mikanos at osbook_day03c
今度はカーネルで受け取ってグラデーションでぬりつぶしてる
mikanos/kernel/main.cpp at osbook_day03c · uchan-nos/mikanos · GitHub
Main.c からカーネル(main.cpp)に frame_buffer_base と frame_buffer_size を渡すようにしてる
処理の流れ
frame_buffer_base をポインタに変換する
frabe_buffer の先頭アドレスから frame_buffer の最後までをグラデーションで塗りつぶす
先頭アドレスと frame_buffer_size を受け取っているので、どこまでが frame_buffer の領域かはわかる
エラー処理
GitHub - uchan-nos/mikanos at osbook_day03d
無限ループは普通に書くと cpu を無限に食いつぶしてしまうので hlt して止めましょうってだけ
hlt 命令だと割り込みがあるまで cpu をスリープさせることができる
4 章:ピクセル描画と make 入門
4.2 ピクセルを自在に描く
GitHub - uchan-nos/mikanos at osbook_day04b
UEFI の規格ではピクセルデータ形式は 4 種類存在する
4.3 C++で書き直す
GitHub - uchan-nos/mikanos at osbook_day04c
配置 new とは
引数に指定したメモリ領域上にインスタンスを生成する方法
OS にメモリ管理機能が存在しなくても好きな大きさのメモリ領域を確保できる
GitHub - uchan-nos/mikanos at osbook_day04d
4.5 ローダを改良する
readelf -l コマンドで elf ファイルのプログラムヘッダを確認できる
ロードの手順
カーネルファイルを一時領域に読み込む
一時領域に読み込んだカーネルファイルのプログラムヘッダを読み込み最終目的地の番地の範囲を取得
一時領域から最終目的地へ LOAD セグメントをコピー
一時領域を削除
MikanLoaderPkg/Main.c と kernel/main.cpp の関係でかなり混乱した
まず役割を確認する
MikanLoaderPkg/Main.c はブートローダー
OS を読み込む前に読み込まれる
edk2 でビルドされt efi ファイルになる
kernel/main.cpp はカーネル
実際の OS の処理が書かれてあるプログラム
描画処理とか
clang でビルドされて elf ファイルになる
ブートローダがカーネルを読み込む
MikanLoaderPkg/Main.c が kernel/main.cpp を読み込む
main.cpp でどの関数をはじめに発火するかは edk2 で指定されてる
言い換えると、エントリーポイントは edk2 で指定
MikanOS でのファイルだと下記のような読み込みになる
edk2/Build/MikanLoaderX64/DEBUG_CLANG38/X64//Loader.efi -- 読み込む -> mikanos/kernel/kernel.elf
5 章:文字表示とコンソールクラス