0
0

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自作入門 メモ #2

Posted at

前置き

本記事は「ゼロからのOS自作入門」のメモになります。
仕事上OSの知識があってもいいなと思って、取り組むことにしました。
各章に対し、1記事をOutputする予定です。
前の章はこちら
https://qiita.com/fuji3195/items/1495df96a164b23a9007

EDKとは

EDKⅡ:UEFI BIOS本体および、UEFI BIOS上で動くアプリケーションを開発するための開発キット
もともとIntelが実装したものをオープンソースにした。

Mikan OSを取得

git clone https://github.com/uchan-nos/mikanos.git
# EDKⅡのディレクトリににMikanOSのブートローダディレクトリをリンク
cd $HOME/edk2
ln -s $HOME/'workspace'/mikanos/MikanLoaderPkg ./
source edksetup.sh

workspaceにはgitでcloneしたワークスペースのパスを入れる。
Conf/target.txtが生成されるので、中身のうち以下の項目を書き換える。

設定項目 設定値
ACTIVE_PLATFORM MikanLoaderPkg/MikanLoaderPkg.dsc
TARGET DEBUG
TARGET_ARCH X64
TOOL_CHAIN_TAG CLANG38

buildでビルドすると、何かがビルドされる。

ハローワールド

通常のC/C++では,main()がスタートになるが、EDK2では、自由にスタート地点を決められる。
その際に、Loader.infにある、ENTRY_POINTを参照する。
buildを行おうとすると、そのままではうまくいかず、以下のエラーが出て失敗する。

/home/user/edk2/MikanLoaderPkg/MikanLoaderPkg.dsc(...): error 4000: Instance of library class [RegisterFilterLib] is not found
        in [/home/user/edk2/MdePkg/Library/BaseLib/BaseLib.inf] [X64]
        consumed by module [/home/user/edk2/MikanLoaderPkg/Loader.inf]

これは新しいEDKでエラーの原因が追加されたためらしい。
そこで, gitからcheckoutするとうまくいく。古いバージョンをインストールしているイメージ。

cd $HOME/edk2
git checkout 38c8be123aced4cc8ad5c7e0da9121a181b94251

メモリマップ

git checkoutで02bに変更する。
GetMemoryMap()について解説。

gs->GetMemoryMap(
    IN OUT UINTN *MemoryMapSize, // 入力:メモリマップ書き込み用のメモリ領域の大きさ。出力:実際のメモリマップの大きさ。
    IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, // メモリマップ書き込み用のメモリ領域の先頭ポインタ。後ほど紹介。
    OUT UINTN *MapKey, // メモリマップを識別するための値を書き込む変数。後で使う。
    OUT UINTN *DescriptorSize, // メモリマップの個々の行を表すメモリディスクリプタのバイト数を表す。UEFIの実装によっては構造体が拡張されていたりしてByte数が異なる可能性があるため。
    OUT UINT32 *DescriptorVersion // メモリディスクリプタの構造体のバージョン。
);

メモリ領域に書き込まれるデータの構造は、EFI_MEMORY_DESCRIPTOR構造体の配列になっている。
EFI_MEMORY_DESCRIPTOR配列は以下の構造

フィールド名 概要
Type UINT32 メモリ領域の種別
PhysicalStart EFI_PHYSICAL_ADDRESS メモリ領域の先頭の物理メモリアドレス
VirtualStart EFI_VIRTUAL_ADDRESS メモリ領域の先頭の仮想メモリアドレス
NumberOfPages UINT64 メモリ領域の大きさ(4KiBページ単位)
Attribute UINT64 メモリ領域が使える用途を示すbit集合

メモリマップはUefiMain()でファイル保存する。
指定されたプログラムを実行すると、下のような情報が手に入る。

Memory Mapはファイルへ保存する。
その際にSaveMemoryMap()で行う。
printはPrint(L"...", format)を使っている。ここは通常のprintf文とは異なる。
AsciiPrintでそれぞれの要素をAsciiで出力する。
出力する要素は,itr num, Descriptor Type, GetMemoryType, 物理Startアドレス, Page数, Attribute&0xFFFFFの順で並べている.

Buildすると,Loader.efiが作成される.
これを実行した後,mountし下にあるmemmapを除くと,Memory Mapの中身を確認できる.
ここら辺は指示通りに行えば問題ない.

ポインタに関しては基本なので省略.

感想

まだ何をやっているかわかっていない,という感じ.
EDK2を使っているのに,EDK2の全貌が見えない.
今後EDK2を理解できるようになるのか,それともそんなに使わないのかで,ここの理解度も変わってきそう.

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?