らんだむな記憶

blogというものを体験してみようか!的なー

みかん日記 (2)

もちろん、そのまま Main.c を写経して clang に通しても

$ clang -c Main.c 
Main.c:1:10: fatal error: 'Uefi.h' file not found
#include <Uefi.h>
         ^~~~~~~~
1 error generated.

となる。ansible によって $HOME/edk2 の下に EDK II が準備されているので、ここに移動して

ln -s $HOME/git_work/osbook/day02a/MikanLoaderPkg ./

みたいなことをする。そして、次に

$ source edksetup.sh
Using EDK2 in-source Basetools
WORKSPACE: /home/xxx/edk2
EDK_TOOLS_PATH: /home/xxx/edk2/BaseTools
CONF_PATH: /home/xxx/edk2/Conf
Copying $EDK_TOOLS_PATH/Conf/build_rule.template
     to /home/xxx/edk2/Conf/build_rule.txt
Copying $EDK_TOOLS_PATH/Conf/tools_def.template
     to /home/xxx/edk2/Conf/tools_def.txt
Copying $EDK_TOOLS_PATH/Conf/target.template
     to /home/xxx/edk2/Conf/target.txt

だが、「開発者コマンドプロンプト for VS 201X」のような気持ちになるな。
とりあえずこの呪文を唱えると $HOME/edk2/BaseTools/BinWrappers/PosixLike/build が見えるようになる。変な generic な名称のコマンドがグローバルに見えているのだろうかと最初不安になった・・・(本の脚注にひっそりと説明されている)。
そんなわけで build すると clang に謎のインクルードパスが渡った状態で色々コンパイルが走り、途中で nasm の文字を見ながらビルド行程が進む。

できあがった Loader.efi を使って

sh run_qemu.sh Loader.efi

などで UEFI ブートすると「Hello, Mikan World!」が出る。

Print 関数の定義は

find MdePkg/Include/ -name "*.h" | xargs grep -n Print

で簡単に見つかって、MdePkg/Include/Library/UefiLib.h の中で

UINTN
EFIAPI
Print (
  IN CONST CHAR16  *Format,
  ...
  );

のように定義されている。対応する実装は MdePkg/Library/UefiLib/UefiLibPrint.c のほうで

UINTN
EFIAPI
Print (
  IN CONST CHAR16  *Format,
  ...
  )
{
  VA_LIST Marker;
  UINTN   Return;

  VA_START (Marker, Format);

  Return = InternalPrint (Format, gST->ConOut, Marker);

  VA_END (Marker);

  return Return;
}

そして

UINTN
InternalPrint (
  IN  CONST CHAR16                     *Format,
  IN  EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL  *Console,
  IN  VA_LIST                          Marker
  )
{
  ...
  if (Console != NULL && Return > 0) {
    Status = Console->OutputString (Console, Buffer);
    if (EFI_ERROR (Status)) {
      Return = 0;
    }
  }

  ...

  return Return;

となっている。本の p.43 でやっている内容が可変引数の関数化されていることが分かる。これで第 2 章前半(〜p.55)は終わり。