# EFISTUB (日本語)

Warning: カーネルバージョンとマザーボードのモデルによっては EFISTUB の起動が失敗するというバグが報告されています。詳しくは [1] や [2] を見て下さい。

Linux カーネル (linux>=3.3) は `EFISTUB (EFI BOOT STUB)` ブートをサポートしています。カーネル設定で `CONFIG_EFI_STUB=y` を設定することで有効にすることができ、Arch Linux のカーネルではデフォルトで有効にされています (詳しくは EFI Boot Stub を参照してください)。

EFISTUB カーネルだけでは他のカーネルを起動することはできません。よってブートメニューエントリごとに EFISTUB カーネル + Initramfs のペアが必要です。このため、複数のカーネルを使う場合は、UEFI Boot Manager を使うことが推奨されています。

## EFISTUB の設定

1. EFI System Partition を作成してください。
2. `/boot` (推奨) かどこか他の好きなところに (他のディストロやツールは大抵 `/boot/efi` を使っています) EFI System Partition をマウントしてください。以後このマウントポイントは `$esp` として示します。

### カーネルと initramfs を ESP にコピーする

Warning: この手順は EFISYS のマウントポイントとして `/boot` を使っていない場合にのみ必要です。マウントポイントとして `/boot` を選んだ時は、#EFISTUB の起動 に進むことができます。

1. `$esp/EFI/arch/` を作成してください
2. 以下のファイルを移動元から移動先にコピーしてください

ブートファイルの移動元 | UEFI の移動先
--- | ---
/boot/vmlinuz-linux | $esp/EFI/arch/vmlinuz-arch.efi
/boot/initramfs-linux.img | $esp/EFI/arch/initramfs-arch.img
/boot/initramfs-linux-fallback.img | $esp/EFI/arch/initramfs-arch-fallback.img

Warning: カーネルがアップデートされる度に EFISTUB カーネルを更新する必要があります。また、以下の方法のどれか一つを使うことで EFISTUB カーネルを自動で更新することができます:

#### systemd

Systemd にはイベントトリガータスク機能があります。これで、パス上の変更を検知する能力を使って、`boot` にある EFISTUB カーネルと initramfs のファイルが更新されたときにそれらを同期させることが可能です。

Warning: mkinitcpio がカーネルスタブと initramfs を作成するのには時間がかかるので、以下の systemd サービスが新しいカーネルスタブと initramfs の代わりに古いものをコピーしてしまう可能性があります。このエラーの可能性を減らすために、(mkinitcpio によって最後に作成される) initramfs-linux-fallback.img が更新されたか確認する efistub のコピーサービスをバインドすると良いでしょう。

    /etc/systemd/system/efistub-update.path

    [Unit]
    Description=Copy EFISTUB Kernel to UEFISYS Partition

    [Path]
    PathChanged=/boot/initramfs-linux-fallback.img

    [Install]
    WantedBy=multi-user.target

    /etc/systemd/system/efistub-update.service

    [Unit]
    Description=Copy EFISTUB Kernel to UEFISYS Partition

    [Service]
    Type=oneshot
    ExecStart=/usr/bin/cp -f /boot/vmlinuz-linux $esp/EFI/arch/vmlinuz-arch.efi
    ExecStart=/usr/bin/cp -f /boot/initramfs-linux.img $esp/EFI/arch/initramfs-arch.img
    ExecStart=/usr/bin/cp -f /boot/initramfs-linux-fallback.img $esp/EFI/arch/initramfs-arch-fallback.img

次のコマンドでサービスを有効にしてください:

    # systemctl enable efistub-update.path

#### Incron

incron を使って更新後に EFISTUB カーネルを同期するスクリプトを実行することができます。

Tip: 下のスクリプトを `/usr/local/bin/efistub-update.sh` として保存してください

    #!/usr/bin/env bash
    /usr/bin/cp -f /boot/vmlinuz-linux $esp/EFI/arch/vmlinuz-arch.efi
    /usr/bin/cp -f /boot/initramfs-linux.img $esp/EFI/arch/initramfs-arch.img
    /usr/bin/cp -f /boot/initramfs-linux-fallback.img $esp/EFI/arch/initramfs-arch-fallback.img

Tip: 下のスクリプトを `/etc/incron.d/efistub-update.conf` として保存してください
Note: 最初のパラメータ `/boot/initramfs-linux-fallback.img` は監視するファイルです。2番目のパラメータ `IN_CLOSE_WRITE` は監視するイベントです。3番目のパラメータ `/usr/local/bin/efistub-update.sh` は起動するスクリプトです。

    /boot/initramfs-linux-fallback.img IN_CLOSE_WRITE /usr/local/bin/efistub-update.sh

Tip: この方法を使うには、incron が有効になっている必要があります。有効になっていない場合は次を実行してください

    # systemctl enable incrond.service

#### Mkinitcpio フック

Mkinitcpio はフックを生成することができシステムレベルデーモンを機能させる必要はありません。バックグラウンドプロセスを生成して `vm-linuz`, `initramfs-linux.img`, `initramfs-linux-fallback.img` の生成を待ち; そして #EFISTUB の設定 の手順4に従います。

Tip: 下のスクリプトを `/usr/lib/initcpio/install/efistub-update` として保存してください

    #!/usr/bin/env bash

    build() {
    	/root/watch.sh &
    }

    help() {
    	cat <<HELPEOF
    This hook waits for mkinitcpio to finish and copies the finished ramdisk and kernel to the ESP
    HELPEOF
    }

Tip: 下のスクリプトを `/root/watch.sh` として保存し実行可能にしてください

    #!/usr/bin/env bash

    while [[ -d "/proc/$PPID" ]]; do
    	sleep 1
    done

    /usr/bin/cp -f /boot/vmlinuz-linux $esp/EFI/arch/vmlinuz-arch.efi
    /usr/bin/cp -f /boot/initramfs-linux.img $esp/EFI/arch/initramfs-arch.img
    /usr/bin/cp -f /boot/initramfs-linux-fallback.img $esp/EFI/arch/initramfs-arch-fallback.img

    echo "Synced kernel with ESP"

Tip: `efistub-update` を `/etc/mkinitcpio.conf` 内の hook のリストに加えて下さい

#### /etc/fstab バインドマウント

Note:

- The following method should work similarly with any distribution that does not symlink in `/boot`. See Warnings for caveats.
- This involves no special scripts, services, or bootloader filesystem drivers.
- This centralizes and organizes kernels and initrds across installations on one partition.
- This avoids possible limitations imposed by firmware and/or the bootloader on boot device configuration as can often occur with RAID and/or LVM (excepting the standard FAT32 EFI system partition, of course).
- Beyond initial configuration this should persist without special consideration or maintenance.
- This should be transparent to any action normally affecting `/boot` and the files therein.

Warning:

- This requires both a kernel and a bootloader compatible with the FAT32 filesystem.
- Because the FAT32 filesystem cannot handle symlinks, this will not behave as intended with an installation that requires them in `/boot`.
- Initial configuration requires `root` level access.
- This may require a large EFI system partition in order to accomodate multiple installations.
- All kernels will require at least a `root=system root` parameter passed at boot.
- per rEFInd's author: OpenSUSE definitely uses symbolic links in `/boot`... Fedora, Ubuntu, and ... OpenSUSE all refuse a FAT partition as `/boot` in ... setup [which] can be worked around [in] `/etc/fstab`. Forum post [here].

方法
  通常は EFI system partition を `/boot/efi` サブフォルダにマウントしますが、以下ではその逆を行います。

- 他で記述されているように FAT32 フォーマットの `ef00` タイプの EFI system partition を作成してください。

  Tip:
  - It may be beneficial to make it several gigabytes in size to accomodate multiple installations.
  - Use the GPT partition name feature for added convenience. For example name the partition `esp`.

- マウントポイントを作成して EFI system partition をファイルシステムのどこかにマウントしてください。例:

  `$ mkdir /esp
  $ mount -L esp /esp`

- システムの `/boot` ファイルを含めるため、EFI system parition の `/EFI/boot` にフォルダを作成してください。例:

  `$ mkdir /esp/EFI/boot/arch64-laptop`
  Tip:
  - The refind bootloader automatically detects and adds EFI loadable kernel files installed to the EFI system partition in `/EFI/boot/*/` by default.
  - Keying `F2` on a highlighted refind boot menu entry enables adding the required `root=` kernel parameter to an auto-added or otherwise unconfigured menu entry.

- `/boot` にある全てのファイルを削除して EFI system partition に新しくフォルダを作成します。例:

  `$ mv /boot/* /esp/EFI/boot/arch64-laptop/`

- EFI system partition に新しく生成したフォルダを `/boot` にバインドマウントしてください。例:

  `$ mount --bind /esp/EFI/boot/arch64-laptop /boot`

- `$ ls /boot/` でファイルが大丈夫か確認してから、`/etc/fstab` を編集して変更を永続的にしてください。例:

  `##/etc/fstab
  LABEL=arch64-laptop_rootfs / ext4 defaults 0 0
  LABEL=esp /esp vfat defaults 0 0
  /esp/EFI/boot/arch64-laptop /boot none defaults,bind 0 0`

- 必要に応じて `root=` カーネルブートパラメータを適用するようにブートローダを更新してください。例:

  `##/boot/refind_linux.conf
  ... root=LABEL=arch64-laptop_rootfs ...`

Note: refind-efi 0.2.7 現在、refind は `/boot` にあるカーネルを自動で検知します。名前を変更して `.efi` 拡張子を付ける必要はありません。そのため、同期スクリプトは refind を使うなら必要ありません。ただし、カーネルが保存されている Linux のファイルシステムを読み込むために EFI ドライバーをインストールしなくてはなりません。

## EFISTUB の起動

Warning: Linux Kernel EFISTUB initramfs のパスは EFI System Partition のルートからの相対パスでなければなりません。例えば、initramfs が `$esp/EFI/arch/initramfs-linux.img` にあったとしたら、適切な UEFI 行は `initrd=/EFI/arch/initramfs-linux.img` か `initrd=\EFI\arch\initramfs-linux.img` になります。

以下の方法のどれか一つを使うことで EFISTUB カーネルを起動することができます:

### gummiboot を使う

Gummiboot は EFISTUB カーネルのナイスなメニューを提供する UEFI Boot Manager です。EFISTUB ブートの推奨ブートマネージャです。詳細は gummiboot を見て下さい。

### rEFInd を使う

rEFInd は (Intel Mac で使われている) rEFIt Boot Manager の Rod Smith (GPT-fdisk の作者) によるフォークです。rEFInd は Mac 以外の UEFI ブートについて rEFIt の多くの問題を修正してあり EFISTUB カーネルをサポートしています。詳しくは rEFInd を見て下さい。

### UEFI Shell を使う

通常の UEFI アプリケーションのように UEFI Shell から EFISTUB カーネルを起動することが可能です。この場合カーネルパラメータは通常のパラメータとして起動する EFISTUB カーネルファイルに渡します。

    > fs0:
    > cd \EFI\arch
    > vmlinuz-arch.efi root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rootfstype=ext4 add_efi_memmap initrd=EFI/arch/initramfs-arch.img

また、ブートパラメータを記述したシンプルな `archlinux.nsh` ファイルを書いて UEFI System Partition に置き、それを実行することもできます:

    > fs0:
    > archlinux

スクリプト例:

    $ESP/archlinux.nsh

    echo -on
    \EFI\arch\vmlinuz-arch.efi root=PARTUUID=3518bb68-d01e-45c9-b973-0b5d918aae96 rootfstype=ext4 add_efi_memmap initrd=/EFI/arch/initramfs-arch.img

この方法では名前をメモしておいたり20-30文字も入力せずとも UUID を指定することができます。

### ブートマネージャを使わずに直接起動する

Warning: カーネルと efibootmgr の組み合わせによっては手動で調整しないと動かないことがあります [3]。ブートエントリを削除することはできますが作成することは出来なくなります。
Note: UEFI ファームウェアによってはブートエントリの uefi アプリケーションにコマンドラインパラメータを埋め込むことができません。

UEFI ブートエントリに直接カーネルパラメータを埋め込むことが可能です。つまりあなたの UEFI ブートオーダー・GUI を使って GRUB など他のブートローダーを使わずに直接 Arch Linux を起動することができます (下のコマンドの `X` と `Y` は EFI System Partition があるディスクとパーティションに置き換えてください、`root=` パラメータは root にあわせて変更してください)。

    # mount -t efivarfs efivarfs /sys/firmware/efi/efivars              # 既にマウントされている場合は無視して下さい
    # efibootmgr -d /dev/sdX -p Y -c -L "Arch Linux" -l /vmlinuz-linux -u "root=/dev/sda2 rw initrd=/initramfs-linux.img"

作成されたエントリが問題ないか確認するために次のコマンドを実行すると良いでしょう:

    # efibootmgr -v

ブートの順番を設定するには、次を実行します:

    # efibootmgr -o XXXX,XXXX

XXXX は `efibootmgr` コマンドによって出力されるそれぞれのエントリの番号に置き換えてください。

Tip: シェルスクリプトでブートエントリを作成するコマンドをどこかに保存しておけば、修正 (例えばカーネルパラメータの変更) が楽になります。

efibootmgr の詳細は UEFI#efibootmgr で説明しています。フォーラムの投稿 https://bbs.archlinux.org/viewtopic.php?pid=1090040#p1090040 。

Category:

- Boot loaders (日本語)