ゼロからのOS自作入門 読みメモ 2章 その4

メインメモリ

  • UEFIのメモリマップにおける1ページの大きさは4KiB
  • 現実でのメモリマップはメモリ領域が隣接とならず歯抜けがあり得る
  • メモリマップの取得の写経
EFI_STATUS GetMemoryMap(struct MemoryMap* map) {
  if (map->buffer == NULL)
    return EFI_BUFFER_TOO_SMALL;
  }
  
  map->map_size = map->buffer_size;
  return gBS->GetMemoryMap(
      &map->map_size,
      (EFI_MEMORY_DESCRIPTOR*)map->buffer,
      &map->map_key,
      &map->descriptor_size,
      &map->descriptor_version);
}
  • UEFI はOSを起動するために必要な機能を提供するために必要な機能を提供するブートサービスとOS起動前起動後どちらでも使えるランタイムサービスがある
  • gBSはブートサービスを表すグローバル変数
  • gBS->GetMemoryMapの仕様
EFI_STATUS GetMemoryMap(
    IN OUT UINTN *MemoryMapSize,
    IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
    OUT UINTN *MapKey,
    OUT UINTN *DescriptorSize
    OUT UINT32 *DescriptorVersion);
  • IN や OUT は EDK II のマクロ
    • 引数がどう使われるかプログラマに伝えるためのもの
    • IN: 関数への入力, OUT: 関数からの出力
    • 入力用には関数を呼び出す前に有効な値を入れておく
    • 出力用は関数がその内容を書き換える
    • IN OUT は入力用として使用された後に出力にも使われる
  • gBS->GetMemoryMapは関数呼び出し時点のメモリマップを取得し、引数 MemoryMap で指定されたメモリ領域に書き込む
  • MemoryMapSize にはメモリマップ書き込み用のメモリ領域の大きさを設定し、出力として実際のメモリマップの大きさが設定される
  • MemoryMap にはメモリマップ書き込み用のメモリ領域の先頭ポインタを設定する
    • 先頭ポイントの設定としてIN, メモリマップが書き込まれるためOUTが指定されている
  • MapKey にはメモリマップを識別する値を書き込む変数を指定
  • DescriptorSize はメモリディスクリプタのバイト数
  • DescriptorVersion はメモリディスクリプタの構造体のバージョン番号

ゼロからのOS自作入門 読みメモ 2章 その3

  • 取ってきたedk2のディレクトリに自作OSのmain.c置いている場所のリンクを作る
  • source edksetup.shを実行する
  • Confディレクトリがその場に作られるのでその中のtarget.txtを編集する
  • ここは本に合わせて以下へ変更する
ACTIVE_PLATFORM = HogeLoaderPkg/HogeLoaderPkg.dsc
TOOL_CHAIN_TAG        = CLANG38
  • buildに失敗した

EDK II で UEFI アプリケーションを作る — osdev-jp core docs 1.0 ドキュメント

tools_def.txt の “Supported Tool Chains” からビルドに用いるツールチェインを選ぶ。VS2015 とか GCC5 とか。

  • tools_def.txtに書き方が載っているらしい
  • XCODE5 で行けそう
TOOL_CHAIN_TAG        = XCODE5
  • 行けました! f:id:dvi2911:20210410235624p:plain

  • 疲れたので続きはまた今度

AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー 読みメモ2

AWSの責任共有モデル

  • クラウド本体のセキュリティはAWS
    • データセンターやAWSサービスのソフトウェアなど
  • クラウド内のセキュリティはユーザー
    • クラウド内のソフトウェア、ネットワークなど

AWSクラウドのセキュリティ

グローバルインフラストラクチャ

  • リージョン
    • 世界のどこでサービスを使うか
  • アヴェイラビリティゾーン
    • リージョンにあるデータセンターの集合
    • 各リージョンに二つ以上ある
  • マルチサイト アクティブ-アクティブ
    • 複数リージョンに完全に同じシステムを構築して災害時のダウンタイムを最小にする構成

リージョンの選択条件

  • 保存するデータやシステムがそのリージョン地域の法律や扱う企業のガバナンス要件を満たしているか
  • ユーザや連携するデータに近いか
  • 必要なサービスが揃っているか
  • コスト効率がいいか

ゼロからのOS自作入門 読みメモ 2章 その2

Main.c

#include <Uefi.h>
#include <Library/UefiLib.h>

EFI_STATUS EFIAPI UefiMain( // Loader.inf で設定したエントリポイント、ここから始まる
    EFI_HANDLE image_handle,
    EFI_SYSTEM_TABLE *system_table) {
  Print(L"Hello, World!\n");
  while (1);
  return EFI_SUCCESS;
}
  • include することで EFI_STATUS, EFI_HANDLE, EFI_SYSTEM_TABLE, Printなどが扱える
  • EFI_STATUS, EFI_HANDLEはUefiBaseType.hにあったりする
/// Function return status for EFI API.
///
typedef RETURN_STATUS             EFI_STATUS;
///
/// A collection of related interfaces.
///
typedef VOID                      *EFI_HANDLE;
  • EFI_SYSTEM_TABLEはUefiSpec.hにPrintはUefiLibPrint.cにある

  • Uefi.h 周り読んでいたら時間がなくなったからタイムアップ。実行はまた今度

AWS認定資格試験テキスト AWS認定 クラウドプラクティショナー 読みメモ1

クラウドアーキテクチャの基本原理

故障に備えた設計(Design for Failure)

  • 単一障害点(SPOF)をなくそう
    • 1つのデータセンターのみで運用しない
    • 単一のインスタンスのみで構成しない

コンポーネントの分離

弾力性

  • 伸縮性ともいう
  • リソースの性能をスケールインしたりスケールアウトしたりできる
  • スケーリングの種類
    • 巡回スケーリング
      • 定期的なスケーリング
    • イベントベーススケーリング
      • 予定されたイベントに合わせてスケーリングする
      • スケジュールドスケールアウトパターンを利用する
    • オンデマンドの自動スケーリング
      • CPUの利用率やI/O量をトリガーとしてスケーリングする
      • スケールアウトパターンを利用する
  • スケールアウトは台数を増加すること
    • スケールアップは単体性能を上げること

AWS Well-Architected フレームワーク

  • 信頼性、セキュリティ、効率、コスト効果が高いシステムを設計するために作られたベストプラクティス

https://d1.awsstatic.com/whitepapers/ja_JP/architecture/AWS_Well-Architected_Framework.pdf

  • AWS クラウドラクティショナー を実際受けるのかはともかく、練習問題の日本語が理解できなくて既に不安を感じる

ゼロからのOS自作入門 読みメモ 2章 その1

EDK II

  • EDK II は IntelUEFI とその周辺のプログラムを実装したもの

GitHub - tianocore/edk2: EDK II

EDK II でハローワールド

パッケージ宣言ファイル(.dec)

[Defines]
  DEC_SPECIFICATION = 0x0001001b # DECの仕様のバージョンを記述1.27と10進数で書いてもいいらしい
  PACKAGE_NAME      = HogeOS # 名前
  PACKAGE_GUID      = df15f4c5-fbaa-54f8-979f-f2ff4aef85b1 # パッケージのGUID。配布とかするならちゃんと気をつける
  PACKAGE_VERSION   = 0.1

3.4 [Defines] Section - EDK II DEC Specification

パッケージ記述ファイル(dsc)

[Defines]
  PLATFORM_NAME           = HogeLoaderPkg
  PLATFORM_GUID           = f25be036-706e-570a-ab06-47a2dd0807f1
  PLATFORM_VERSION        = 0.1
  DSC_SPECIFICATION       = 0x0001001c
  OUTPUT_DIRECTORY        = Build/HogeLoader$(ARCH) # ARCHにはアーキテクチャの名前が入るようにしている(x64など)
  SUPPORTED_ARCHITECTURES = X64 # この本ではX64向けのOSを作るのでX64と入力
  BUILD_TARGETS           = DEBUG|RELEASE|NOOPT

3.5 [Defines] Section - EDK II DSC Specification

[LibraryClasses]
  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf

  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
  • LibraryClasses ではUEFIアプリを作成するのに必要なライブラリの名前とファイルへのパスが記述されている
  • 本に沿って作るのでよくわかってないけどそのまま記述

3.8 [LibraryClasses] Sections - EDK II DSC Specification

[Components]
  HogeLoaderPkg/Loader.inf # パッケージを構成するコンポーネントを指定。ここにあるものがビルド対象

3.10 [Components] Sections - EDK II DSC Specification

コンポーネント定義ファイル(Loader.inf)

[Defines]
  INF_VERSION                    = 0x0001001b
  BASE_NAME                      = Loader # コンポーネントの名前
  FILE_GUID                      = 3dae0f38-42f0-5d17-94f2-2d1722585667
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 0.1
  ENTRY_POINT                    = UefiMain # エントリポイントの名前。起動時にはここから実行される

#  VALID_ARCHITECTURES           = X64

[Sources]
  Main.c

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  UefiLib
  UefiApplicationEntryPoint

[Guids]
  gEfiFileInfoGuid
  gEfiAcpiTableGuid

[Protocols]
  gEfiLoadedImageProtocolGuid
  gEfiLoadFileProtocolGuid
  gEfiSimpleFileSystemProtocolGuid
  gEfiBlockIoProtocolGuid
  • ここも本に沿って作成するのでそのまま合わせて記述

EDK II Module Information (INF) File Specification - EDK II INF Specification

  • 次はMainファイルを書いていく

ゼロからのOS自作入門 読みメモ 1章

PCの仕組みとハローワールド

$ sum BOOTX64.EFI   
12430 2 BOOTX64.EFI

本の値と一致した!

  • BOOTX64.EFI を含むディスクイメージを作成する
$ qemu-img create -f raw disk.img 200M
  • -fオプションでディスクイメージの形式を指定
$ mkfs.fat -n 'HOGE OS' -s 2 -f 2 -R 32 -F 32 disk.img
  • mkfs.fatはフォーマットをおこなうコマンド
  • -n でボリューム名をつける
  • -s ではクラスタごとのセクタの数をきめる
  • -f FATの数を決める デフォルトは2(FATの数ってなんだろう)
  • -R reserved sectors の数を決める
  • -F FATのタイプ指定(12, 16, 32ビットから指定する)
  • 見た Design of the FAT file system - Wikipedia
  • Mac だと newfs_msdos で使えるっぽい?
newfs_msdos -v 'HOGE OS' -c 2 -n 2 -r 32 -F 32 disk.img
  • オプションは多分これ(-c == -s, -n == -f, -r == -R )
  • newfs_msdosの前にMacだとディスクイメージにattachしないといけなさそう?
$ hdiutil attach -nomount ./disk.img
> dev/disk2 # <=これを指定する
$ newfs_msdos -v 'HOGE OS' -c 2 -n 2 -r 32 -F 32 disk2
$ hdiutil mountvol /dev/disk2 # これでマウントされる
> /dev/disk2                                             /Volumes/HOGE OS
$ sudo mkdir /Volumes/HOGE\ OS/EFI/BOOT
$ sudo cp BOOTX64.EFI /Volumes/HOGE\ OS/EFI/BOOT/BOOTX64.EFI
$ hdiutil detach disk2
$ cp $HOME/edk2/Build/OvmfX64/DEBUG_XCODE5/FV/OVMF.fd .
$ qemu-system-x86_64 -bios OVMF.fd -hda disk.img

f:id:dvi2911:20210403193133p:plain

動いた!

C言語Hello Worldは昔やったので次は2章読もう