『ゼロからの自作OS入門』を読む
gBS ってなんだ?
global 変数のブートサービスのことっぽい
2章:EDK2 とメモリマップ
言い換えればどの関数を最初に呼び出すかを設定できる
Conf/Target.txt の設定
ここで指定する設定ファイルはパソコンはこういう部品で作られてるよ、とかが設定してあるファイル
より具体的にはプラットフォームなどを指定できるテキストファイル
プロセッサタイプ、チップセット、メモリ構成、周辺機器など
TARGET に指定するのは DEBUG
これはリリースとかだとまた変わる
TARGET_ARCH に指定するのは X64
32 bit とか arm とかだとまた変わるのかな?
64 bit の amd だと全部 X64 だと思う
TOOL_CHAIN_TAG に指定するのは CLANG38
コンパイラ、リンカー、その他のビルドツールを選択する場所
メモリマップをファイルに書き出すまでの流れ
そのメモリマップをファイルに書き出す
なぜファイルに書き出すかというと、現代のメモリは揮発性メモリであり、メモリ上にデータを置いておくと消えちゃうから メモリマップにはメモリ上の各領域のメタデータが入ってる
どこからどこまでの領域がなんのためのメモリとして割り当てられているか
3 章:画面表示の練習とブートローダ
コンパイルとリンク
カーネルの実行ファイル kernel.elf を生成してる
カーネルが読み込まれるまでの流れでいうと下記の順
UEFI -> Main.c 呼び出し -> カーネル呼び出し
ブートローダからピクセルを描く
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; // ここで画面真っ白にしてる }
カーネルからピクセルを描く
今度はカーネルで受け取ってグラデーションでぬりつぶしてる
Main.c からカーネル(main.cpp)に frame_buffer_base と frame_buffer_size を渡すようにしてる
処理の流れ
frame_buffer_base をポインタに変換する
frabe_buffer の先頭アドレスから frame_buffer の最後までをグラデーションで塗りつぶす
先頭アドレスと frame_buffer_size を受け取っているので、どこまでが frame_buffer の領域かはわかる
エラー処理
無限ループは普通に書くと cpu を無限に食いつぶしてしまうので hlt して止めましょうってだけ
hlt 命令だと割り込みがあるまで cpu をスリープさせることができる
4 章:ピクセル描画と make 入門
4.2 ピクセルを自在に描く
4.3 C++で書き直す
配置 new とは
引数に指定したメモリ領域上にインスタンスを生成する方法
OS にメモリ管理機能が存在しなくても好きな大きさのメモリ領域を確保できる
4.5 ローダを改良する
readelf -l コマンドで elf ファイルのプログラムヘッダを確認できる ロードの手順
カーネルファイルを一時領域に読み込む
一時領域に読み込んだカーネルファイルのプログラムヘッダを読み込み最終目的地の番地の範囲を取得
一時領域から最終目的地へ LOAD セグメントをコピー
一時領域を削除
MikanLoaderPkg/Main.c と kernel/main.cpp の関係でかなり混乱した
まず役割を確認する
OS を読み込む前に読み込まれる
edk2 でビルドされt efi ファイルになる
実際の 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 章:文字表示とコンソールクラス