Open5

Mac+dockerでMikanOSを作る

konskons

3章

3章のカーネルからピクセルを描くのところで縞々にならない。
このためブートローダのPrintデバッグ。
具体的にはカーネル呼び出しが成功しているのかが気になったので

EFI_STATUS tmp = root_dir->Open(
      root_dir, &kernel_file, L"\\kernel.elf",
      EFI_FILE_MODE_READ, 0);
  if (tmp != EFI_SUCCESS) {
    Print(L"failed\n");
  }else {
    Print(L"success\n");
  }

こんな感じのコードを書いた。
参考までにOpen関数はこんな感じになっている

/**
  Opens a new file relative to the source file's location.

  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file
                     handle to the source location. This would typically be an open
                     handle to a directory.
  @param  NewHandle  A pointer to the location to return the opened handle for the new
                     file.
  @param  FileName   The Null-terminated string of the name of the file to be opened.
                     The file name may contain the following path modifiers: "\", ".",
                     and "..".
  @param  OpenMode   The mode to open the file. The only valid combinations that the
                     file may be opened with are: Read, Read/Write, or Create/Read/Write.
  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
                     attribute bits for the newly created file.

  @retval EFI_SUCCESS          The file was opened.
  @retval EFI_NOT_FOUND        The specified file could not be found on the device.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
                               longer supported.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write
                               when the media is write-protected.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
  @retval EFI_VOLUME_FULL      The volume is full.

**/
typedef
EFI_STATUS
(EFIAPI *EFI_FILE_OPEN)(
  IN EFI_FILE_PROTOCOL        *This,
  OUT EFI_FILE_PROTOCOL       **NewHandle,
  IN CHAR16                   *FileName,
  IN UINT64                   OpenMode,
  IN UINT64                   Attributes
  );

やはり呼び出しに失敗していたのでなぜだろうかと考えていたら,run_qemu.shに引数を渡すのを忘れていた(run_qemu.shの呼び出しをショートカットにしたまま2章から変更しなかったのが原因)

ちなみにカーネルのロードに失敗した場合のosbook_day03aの表示が
https://zenn.dev/karaage0703/scraps/b2705131673377
この記事の結果と一緒だった気がするので,これもカーネルの読み込みができてない気がする。
dockerで一通りやったら私のmacで再現可能かやってみる。

konskons

(^- osbook_day04dで上と全く同じようなデバッグが可能なエラー処理が追加された...)

git tagで切り替えているので全員が同じコードを手にすることを考えると書籍に行番号があってもいいと思ったり

konskons

一連の流れ

  1. メモリマップの取得
  2. メモリマップの保存
  3. グラフィックの設定変数の取得
  4. カーネルファイルの取得
  5. カーネルファイルのメモリ確保,読み込み
  6. ブートサービスの停止
  7. カーネルの起動

個人的には関数ポインタで起動するのが面白いと感じた。
UefiMainの引数が気になる

konskons

4章

まずピクセルを描くにあたってUEFIでは4種類のフォーマットがあるが,今回は簡単な2種類のみ
この2種類はRGBかBGRかの違いしかないのでクラスを継承することで必要な関数を提供する。
(c++の仮装関数は初めてだがrustでいうトレイトだとわかった。)
ピクセル座標は4byteであることに注意。これは1byte分を予約領域として保持しているためである。

インスタンス生成でnewを普通に使うと怒られる。なぜならメモリ管理自体がOSの機能であるからである。
そのため配置newというのを使う。これと配列を組み合わせることによってインスタンス生成を行う。

カーネルを読み込む際にサイズ情報が必要だが,これは読み込まないとわからないというジレンマがある。このため一時領域に一度読み込んでから,サイズ情報を抜き出しメモリ上に実際に読み込むということを行う。

感想

なんだか追えているのか追えていないのかわからない。
仮想アドレスはOSが提供するからこのelfは物理アドレスに等しいと考えていいのか?