# 機能設計書 67-EFIブートマネージャ

## 概要

本ドキュメントは、UEFI環境でのブートエントリ管理を行うefibootmgr、efivar、efitableコマンド群の機能設計を記述する。これらのツールはUEFI NVRAMに格納されたブート変数を操作し、ブート順序やブートエントリの管理を可能にする。

### 本機能の処理概要

**業務上の目的・背景**：UEFI環境ではブート構成がNVRAM内のEFI変数として管理される。OSのインストール、マルチブート環境の構成、ブート順序の変更、一時的なブートターゲットの指定など、ブート構成を管理するためのユーザランドツールが必要である。

**機能の利用シーン**：新しいOSのブートエントリ追加、ブート順序の変更、不要なブートエントリの削除、次回ブートターゲットの一時的設定、UEFI Firmwareセットアップ画面への遷移設定、ブートタイムアウトの設定変更に使用される。

**主要な処理内容**：
1. EFI変数の読み取り・書き込み（efivar）
2. ブートエントリの作成・削除・アクティブ化/非アクティブ化（efibootmgr）
3. ブート順序（BootOrder）の設定
4. 次回ブート（BootNext）の設定・削除
5. ブートタイムアウトの設定・削除
6. EFIデバイスパスの解析・表示
7. UEFI Firmware UI への遷移フラグ設定
8. EFIテーブル情報の表示（efitable）

**関連システム・外部連携**：カーネルのEFI RTサービスインタフェース（/dev/efi）を通じてUEFI NVRAMにアクセスする。libefivar ライブラリがEFI変数操作の低レベルAPIを提供する。libgeomを使用してディスクデバイスパスを解析する。

**権限による制御**：EFI変数の書き込みにはroot権限が必要。読み取りは一般ユーザでも可能な変数がある。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能にはGUI画面の関連はない |

## 機能種別

ブート構成管理 / UEFI NVRAM操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -c | flag | No | 新規ブートエントリ作成 | -l（loader）が必須 |
| -B | flag | No | ブートエントリ削除 | -b（bootnum）が必須 |
| -a / -A | flag | No | アクティブ化/非アクティブ化 | -b が必須 |
| -n / -N | flag | No | BootNext設定/削除 | -b が必須（設定時） |
| -o bootorder | string | No | ブート順序設定 | カンマ区切りの16進数 |
| -t timeout | int | No | ブートタイムアウト設定（秒） | 正の整数 |
| -T | flag | No | ブートタイムアウト削除 | なし |
| -b bootnum | hex | No | 操作対象のブート番号 | 16進数 |
| -l loader | string | No | EFIローダパス | バックスラッシュ区切り |
| -L label | string | No | ブートエントリラベル | 文字列 |
| -k kernel | string | No | カーネルパス | ファイルパス |
| -f / -F | flag | No | Firmware UI遷移設定/解除 | なし |
| -D | flag | No | ドライラン | なし |
| -v | flag | No | 詳細表示 | なし |

### 入力データソース

- UEFI NVRAM: EFI変数（/dev/efi経由）
- コマンドライン引数
- GEOMディスク情報: デバイスパス解析用

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ブートエントリ一覧 | text | 現在のブートエントリとBootOrder |
| EFI変数値 | バイト列 | efivar出力 |
| 操作結果 | text | 成功/失敗メッセージ |

### 出力先

- 標準出力: ブートエントリ情報
- UEFI NVRAM: EFI変数の書き込み

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数パース
   └─ getopt_longによるオプション解析
2. EFI変数読み取り
   └─ libefivar経由でBootOrder、Boot####等の変数を読み取り
3. 操作実行
   └─ 作成/削除/変更/表示の各操作を実行
4. EFI変数書き込み
   └─ efi_set_variable()によるNVRAM書き込み（ドライラン時はスキップ）
5. 結果表示
   └─ 更新後のブートエントリ一覧を表示
```

### フローチャート

```mermaid
flowchart TD
    A[efibootmgr起動] --> B[引数パース]
    B --> C[EFI変数読み取り]
    C --> D{操作種別}
    D -->|作成 -c| E[ブートエントリ作成]
    D -->|削除 -B| F[ブートエントリ削除]
    D -->|順序変更 -o| G[BootOrder更新]
    D -->|BootNext -n| H[BootNext設定]
    D -->|表示のみ| I[エントリ一覧表示]
    E --> J{ドライラン?}
    F --> J
    G --> J
    H --> J
    J -->|No| K[NVRAM書き込み]
    J -->|Yes| L[操作内容表示のみ]
    K --> I
    L --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-67-01 | LOAD_OPTION_ACTIVE | ブートエントリはACTIVEフラグ(0x00000001)で有効/無効を制御 | エントリ操作時 |
| BR-67-02 | EFI_GLOBAL_GUID | BootOrder等の標準変数はEFI_GLOBAL_GUIDネームスペースに格納 | 変数アクセス時 |
| BR-67-03 | COMMON_ATTRS | 標準変数はNON_VOLATILE, BOOTSERVICE_ACCESS, RUNTIME_ACCESSの3属性 | 変数書き込み時 |
| BR-67-04 | ローダパス変換 | Unixパス区切り(/)をEFIパス区切り(\)に変換 | -l指定時 |
| BR-67-05 | Boot番号指定 | "Boot"プレフィックス付きでも受け付ける（Boot0001→0001に変換） | -b指定時 |

### 計算ロジック

特になし。

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースを使用しない。UEFI NVRAMが永続的な設定ストアとして機能する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EPERM | 権限不足 | root以外でのNVRAM書き込み | root権限で実行 |
| ENOENT | 変数不存在 | 指定Boot番号が存在しない | エントリ番号確認 |
| ENOSPC | NVRAM容量不足 | 新規エントリ作成時に容量不足 | 不要エントリ削除 |
| - | Copy未実装 | -Cオプション使用時 | errx(1, "Copy not implemented") |

### リトライ仕様

リトライは行わない。エラー時は即座に終了する。

## トランザクション仕様

NVRAM操作はアトミックではない。BootOrder更新と個別Boot####変数の操作は独立して行われる。

## パフォーマンス要件

特に厳密な性能要件はない。NVRAM操作は低頻度の管理操作である。

## セキュリティ考慮事項

- NVRAM書き込みはroot権限が必要
- EFI変数の不正な変更はシステムが起動不能になる可能性がある
- Firmware UIへの遷移フラグ（OsIndications）はセキュアブート設定の変更を可能にするため注意が必要

## 備考

- efivarコマンドはEFI変数の低レベル操作（読み取り/書き込み/削除/一覧）を提供
- efitableコマンドはEFIシステムテーブル情報の表示を提供
- -C（Copy）オプションは現時点で未実装

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | efibootmgr.c | `usr.sbin/efibootmgr/efibootmgr.c` | bmgr_opts_t構造体（69-99行目）、entry構造体（136-148行目） |

**読解のコツ**: EFI変数操作はlibefivar（lib/libefivar/）が提供するAPIを使用する。efi_get_variable()、efi_set_variable()が基本操作。EFI_GLOBAL_GUIDはUEFI仕様で定義された標準GUIDである。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | efibootmgr.c | `usr.sbin/efibootmgr/efibootmgr.c` | parse_args()（202-299行目）でのオプション解析とmain()での操作ディスパッチ |

**主要処理フロー**:
1. **69-99行目**: bmgr_opts_t - 全操作オプションの構造体定義
2. **101-128行目**: lopts[] - getopt_long用のオプション定義
3. **136-148行目**: entry構造体 - EFI変数エントリのリスト管理
4. **154-164行目**: mangle_loader() - パス区切り変換（/ → \）
5. **175-181行目**: set_bootvar() - EFI変数書き込みの共通関数
6. **202-299行目**: parse_args() - コマンドラインオプション解析

#### Step 3: efivarコマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | efivar.c | `usr.sbin/efivar/efivar.c` | EFI変数の低レベル操作コマンド |
| 3-2 | efiutil.c | `usr.sbin/efivar/efiutil.c` | ユーティリティ関数 |

### プログラム呼び出し階層図

```
efibootmgr main()
    |
    +-- parse_args() [202-299行目]
    |
    +-- EFI変数読み取り
    |       +-- efi_get_variable() [libefivar]
    |               └─ /dev/efi ioctl
    |
    +-- 操作実行
    |       +-- 作成: load_option構築 → set_bootvar()
    |       +-- 削除: efi_del_variable()
    |       +-- 順序: BootOrder変数更新
    |       +-- BootNext: BootNext変数設定
    |
    +-- set_bootvar() [175-181行目]
            +-- efi_set_variable(EFI_GLOBAL_GUID, ..., COMMON_ATTRS)
                    └─ /dev/efi ioctl
```

### データフロー図

```
[入力]                       [処理]                        [出力]

コマンドライン ──────▶ parse_args() ──────────▶ bmgr_opts_t
UEFI NVRAM ──────────▶ efi_get_variable() ──▶ entry リスト
GEOMデバイス情報 ────▶ デバイスパス解析 ────▶ EFI Device Path

bmgr_opts_t ─────────▶ 操作実行 ────────────▶ UEFI NVRAM更新
                                               標準出力表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| efibootmgr.c | `usr.sbin/efibootmgr/efibootmgr.c` | ソース | ブートエントリ管理メイン |
| efibootmgr.8 | `usr.sbin/efibootmgr/efibootmgr.8` | マニュアル | マニュアルページ |
| efivar.c | `usr.sbin/efivar/efivar.c` | ソース | EFI変数操作コマンド |
| efiutil.c | `usr.sbin/efivar/efiutil.c` | ソース | ユーティリティ関数 |
| efivar.8 | `usr.sbin/efivar/efivar.8` | マニュアル | efivarマニュアル |
