用語集
これまでの記事に登場した専門用語を、カテゴリ別に整理した用語集です。記事が増えるのにあわせて随時更新します。
UEFI関連
- UEFI(Unified Extensible Firmware Interface):レガシーBIOSに代わる、現代のPCに搭載されているファームウェアの標準規格です。ファームウェア自身がPE/COFF形式の実行ファイルを直接読み込んで実行できる点が特徴です
- UEFI Boot Services:ファームウェアが、OSやブートローダーに対して起動処理の途中で提供する関数群です。メモリ確保(
AllocatePool)、プロトコルの検索(LocateProtocol)、メモリマップの取得(GetMemoryMap)などが含まれます。名前のとおり「起動処理の間だけ」使える点が重要で、ExitBootServicesを呼び出すと以後は一切使えなくなります - Runtime Services:Boot Servicesとは別に、
ExitBootServicesの後もOS側から呼び出し続けられる関数群です。UEFI変数の読み書きや時刻取得などが含まれます - ExitBootServices:Boot Servicesが使える世界から抜け、以後カーネルが直接ハードウェアを制御する体制に切り替えるための呼び出しです。直前の
GetMemoryMapで得たmap_keyが引数として必要で、途中で別のBoot Services呼び出しが挟まるとmap_keyが古くなり失敗します - メモリマップ:物理アドレス空間のどの範囲がどの用途に使われているか(空き領域か、ファームウェアが使用中か、ACPIテーブル用領域かなど)を記述した一覧です。UEFIでは
GetMemoryMapで取得し、MemoryDescriptorという構造体の配列として返されます。1エントリが4KiB単位のページ数で領域を表現します - メモリタイプ(
EfiConventionalMemoryなど):メモリマップの各エントリが持つ、その領域の種別です。もともと空いているEfiConventionalMemory、Boot Servicesが使っていたEfiBootServicesCode/EfiBootServicesData(ExitBootServices後は再利用可能)、実行中のブートローダー/カーネルの本体が置かれているEfiLoaderCode/EfiLoaderData(実行中のため再利用不可)などがあります - GOP(Graphics Output Protocol):フレームバッファの物理アドレス・サイズ・解像度・ピクセルフォーマットを取得するためのUEFIプロトコルです。ピクセル単位での直接描画を前提にした情報を提供する点が、文字単位のSimple Text Output Protocolと異なります
- Simple Text Output Protocol:UEFIでコンソールに文字列を出力するためのプロトコルです。System Tableの
ConOutフィールド経由でアクセスします - プロトコル(UEFI):UEFIにおける「機能単位のインターフェース」の呼び方です。GUIDで識別され、
LocateProtocolのような関数で検索して使います。レガシーBIOSのソフトウェア割り込み(INT 10hなど)に代わる、UEFI全体で共通のAPI呼び出し方式です - System Table:UEFIアプリケーションの起動時にファームウェアから渡される中心的な構造体です。コンソール入出力(
ConOut/ConIn)やBoot Services/Runtime Servicesへのポインタなど、ファームウェアが提供する機能一式への入り口になっています - ESP(EFI System Partition):UEFIファームウェアがブート対象の実行ファイルを探しに行く、FAT32でフォーマットされたパーティション(またはリムーバブルメディア)です。既定のパス
\EFI\BOOT\BOOTX64.EFIに実行ファイルを置くだけで、ブートエントリの手動登録なしに起動対象として認識されます - PE/COFF:UEFIアプリケーションの実行ファイル形式です。Windows実行ファイルと同じ系統のフォーマットで、Linux向けのELFとは別系統です
CPU/ハードウェア関連
- GDT(Global Descriptor Table):CPUが認識するセグメント(コードセグメント・データセグメントなど)の一覧を保持する表です。各エントリ(セグメントディスクリプタ)は、セグメントの権限や種別をビットフィールドとして持ちます。ロングモードではbase/limitの大半がCPUに無視されますが、権限まわりのビットは引き続き有効です
- コードセグメントセレクタ:GDT中の特定のセグメントディスクリプタを指し示す16bitの値です。
CSレジスタに設定することでCPUが参照するコードセグメントを切り替えます。IDTのゲートディスクリプタも、例外発生時にどのコードセグメントでハンドラを実行するかを指定するためにこの値を持ちます - IDT(Interrupt Descriptor Table):CPUが割り込みや例外に遭遇した際に、どこへジャンプすればよいかを引くための表です。256エントリのうち、vector 0〜31はCPU例外用としてIntelが意味を予約しています
- ゲートディスクリプタ:IDTの1エントリを指す言葉です。GDTのセグメントディスクリプタと同様にビットフィールドの集まりですが、ハンドラのアドレス・使用するコードセグメントセレクタ・特権レベル・ゲートの種類などを持つ点が異なります
- 特権レベル(DPL):Descriptor Privilege Levelの略で、0〜3の4段階からなる、CPUが提供する実行権限の階層です。0が最も高い権限(カーネルモードに相当)です。ゲートディスクリプタのDPLは、そのゲートを
int命令で明示的に呼び出せる最低の特権レベルを表し、CPU自身が発生させる例外はこの制限を受けません - ゲートの種類(割り込みゲート/トラップゲート):IDTのゲートディスクリプタが持つ属性で、ハンドラに入る瞬間にIFフラグ(割り込み許可フラグ)を自動的にクリアするかどうかが異なります。割り込みゲートはクリアし、トラップゲートはクリアしません
- vector(割り込み/例外番号):CPUが割り込みや例外の種類を識別するために使う0〜255の番号です。IDTはこの番号をインデックスとして該当するゲートディスクリプタを引きます。vector 0〜31はCPU例外用に予約されており、たとえばゼロ除算は0、ページフォルトは14です
- IRQ(Interrupt Request):キーボードやタイマーなど、ハードウェアデバイスが発生させる割り込みの要求です。レガシーPICは初期状態でIRQ0〜7をvector 8〜15にマッピングしており、これはCPU例外用のvector範囲と重なるため、そのままではvector番号が衝突します。IRQを安全に扱うには、PICを別のvector範囲へ再マッピングする作業が必要です
- PIC(Programmable Interrupt Controller、8259):ハードウェアからの割り込み要求(IRQ)を受け取り、CPUに伝える役割を持つチップです。IRQをどのvectorに割り当てるかは、ICW(Initialization Command Word)と呼ばれる一連のコマンドを送ることで変更(再マッピング)できます
- EOI(End Of Interrupt):割り込み処理が終わったことをPICに通知する信号です。これを送らないと、そのIRQ以降の優先度の割り込みがPICから配送されなくなります
- PIT(Programmable Interval Timer、8253/8254):一定間隔でIRQ0を発生させるタイマーチップです。入力クロック(1.193182MHz)を望みの割り込み頻度で割った値を「分周比」として設定します
- Protection Fault(#GP:General Protection Fault):CPUの保護機構に違反する操作(不正なセグメント参照や権限違反など)が起きたときに発生するCPU例外です。vector番号は13で、エラーコードを伴います
- ISRスタブ:CPUが割り込み/例外発生時にジャンプする、ごく短いハンドラの入り口部分です。CPUはハンドラのアドレスへ直接ジャンプするだけでvector番号を渡してくれないため、vectorごとに専用のスタブを用意し、vector番号(および必要に応じてダミーのエラーコード)をスタックに積んだうえで共通処理へ引き継ぐ、という役割を持ちます
- ロングモード:x86-64のネイティブな64bit動作モードです。GDT/IDTのエントリ構造やレジスタ幅など、多くの仕様がリアルモード・プロテクトモード(32bit)と異なります
- NMI(Non-Maskable Interrupt):
cliによるIFフラグのクリアではマスクできない特別な割り込みです。IF=0の状態でhlt命令を実行しても、NMI以外の要因ではCPUは目覚めません ud2:「この命令には絶対に到達してはいけない」ことを示すためにコンパイラが埋め込む、意図的な不正命令です。実行すると#UD(Invalid Opcode)例外が発生します。Zigの言語レベルの安全性チェック(unreachableや範囲外アクセスなど)が失敗した際のpanicトラップとして使われます- PML4 / PDPT / PD / PT:x86-64の4段階ページングを構成するテーブルの名前です(Page Map Level 4 / Page Directory Pointer Table / Page Directory / Page Table)。仮想アドレスの上位ビットを4つに区切った各9bitが、それぞれの段のインデックスとして使われます。各テーブルは512エントリ×8バイトでちょうど4KiB(1ページ)に収まります
- CR3:現在使われているPML4テーブルの物理アドレスを保持するレジスタです。ページテーブルを切り替えるには、
movでこのレジスタに新しいPML4の物理アドレスを書き込みます - 恒等マッピング(identity mapping):仮想アドレスと物理アドレスが常に一致するように構成されたページテーブルの状態です。物理アドレスをそのままポインタとして直接読み書きするコードが、ページング導入後も変更なく動き続けられます
- レジスタ:
RAXやRSPなどCPU内部の記憶領域全般を指します。各レジスタの役割や、AH/ALのような部分アクセスの意味についてはx86-64 汎用レジスタの逆引きガイドにまとめています - ABI(Application Binary Interface):コンパイル済みの機械語同士が正しく連携するための、バイナリレベルの取り決めです。関数の引数をどのレジスタに渡すか、戻り値をどこに置くか、呼び出し先がどのレジスタの値を保持すべきか、スタックの整列条件、構造体のメモリ上の並びなどを定めます。関数名や引数の型を人間が読んで理解するための契約であるAPI(ソースコードレベルの約束事)とは異なり、コンパイラが生成する機械語そのものに関わる規約です。呼ぶ側と呼ばれる側が別々にコンパイルされている場合、両者が同じABIに従っていないと、APIが一致していても正しく動作しません
- Microsoft x64 ABI / SysV ABI:x86-64における代表的な2つのABIです。Windows/UEFIはMicrosoft x64 ABIに、Linux等はSysV ABIに従っており、関数の引数をどのレジスタに渡すかなどが異なります。詳しくはx86-64 汎用レジスタの逆引きガイドを参照してください
メモリ管理関連
- ページ:物理メモリを固定サイズ(多くの場合4KiB)に区切った管理単位です。メモリの確保・解放をバイト単位ではなくページ単位で行うことで、管理する情報量を大幅に減らせます
- 物理フレーム:物理メモリ側のページ1つを指す言葉です。ページングを実装すると「仮想メモリ側のページ」も登場するため、物理側であることを明示してこう呼びます
- 物理フレームアロケータ:どの物理フレームが使用中/空きかを管理し、要求に応じて空きフレームを貸し出す仕組みです
- ビットマップアロケータ:物理フレームアロケータの実装方式の1つです。フレーム1つにつき1bitを対応させ、0/1でそのフレームの使用状況だけを記録します。実装が単純な一方、空きフレームを探す処理はビット列を先頭から走査する必要があり、割り当て済みフレームが増えるほど時間がかかります
- ヒープアロケータ(kmalloc相当):ページ単位より小さい、任意サイズのメモリ確保・解放を扱うアロケータです。物理フレームアロケータが貸し出すページを内部で切り分けて使います
- フリーリスト:空いている領域を連結リストとして管理する、ヒープアロケータの実装方式の1つです。空き領域のサイズがまちまちになる点はビットマップ方式と異なります
- 断片化:確保と解放を繰り返すうちに、本来まとまって使えるはずの空き領域が、細切れの小さなブロックに分かれてしまう現象です。隣接する空きブロックを結合しないフリーリスト実装では特に起こりやすくなります
グラフィックス関連
- フレームバッファ:画面に表示される内容をそのままピクセル単位で保持しているメモリ領域です。この領域に値を書き込むと、対応する位置の画面表示が変化します
- MMIO(Memory-Mapped I/O):デバイスの入出力を、通常のメモリ番地と同じ仕組み(読み書き命令)でアクセスできるようにする方式です。フレームバッファやPCIデバイスのレジスタなどは、実際にはRAMではなくデバイス側の回路に接続されたアドレス範囲ですが、CPUからは通常のメモリと同じ命令でアクセスできます
- ビットマップフォント / グリフ:1文字の見た目を、固定サイズのドット(ピクセル)のパターンとしてそのまま保持する形式のフォントです。個々の文字の字形そのものはグリフと呼びます。曲線の輪郭を数式的に定義するアウトラインフォント(TrueTypeなど)と異なり、拡大縮小には向きませんが、決まったサイズでの描画は各グリフのビット列を読んでピクセルを塗るだけで済みます
- Bresenhamのアルゴリズム:2点を結ぶ直線をピクセル単位で描画するための古典的なアルゴリズムです。浮動小数点演算や除算を使わず、整数の加減算だけで「次にどちらのピクセルを塗るか」を判定できるため、グラフィックスハードウェアが貧弱だった時代から広く使われてきました
USB関連
- PCI(Peripheral Component Interconnect):CPUと周辺デバイスを接続する規格、およびそのバスです。各デバイスはbus番号・device番号・function番号の組で識別され、コンフィグレーション空間と呼ばれる専用のレジスタ領域を通じて検出・設定を行います。x86では
CONFIG_ADDRESS(0xCF8)とCONFIG_DATA(0xCFC)という2つのI/Oポートを介してこの空間にアクセスする、レガシーな方式が広く使われています - BAR(Base Address Register):PCIデバイスがコンフィグレーション空間に持つレジスタで、そのデバイス自身のレジスタ群がメモリ空間上のどこにマッピングされているか(あるいはI/O空間のどこか)を示します。ファームウェアが起動時にアドレスを割り当てるため、OS側は基本的にBARを読み取るだけで済みます
- xHCI(Extensible Host Controller Interface):USB 3.0以降の世代で使われる、USBホストコントローラの標準的なレジスタ仕様です。以前の世代ごとに規格が分かれていたUHCI/OHCI(USB 1.1)・EHCI(USB 2.0)を統合し、USB 1.1〜3.xのデバイスを単一のコントローラ・単一のドライバで扱えるようにしています
- TRB(Transfer Request Block):xHCIにおける、コマンドやデータ転送を表現する16バイト固定長のデータ構造です。「何をどう転送するか」を記述するTRBを、後述のリングに並べてコントローラに渡します
- リングとCycle bit:xHCIがTRBを受け渡しする際に使うキュー構造です。送り手(ソフトウェアがコマンド・転送要求を積む場合と、コントローラが完了イベントを積む場合の両方があります)と受け手がそれぞれ自分の位置を指すポインタを持ち、リングの各エントリが「有効かどうか」をCycle bitと呼ばれる1bitで判定します。リングの終端で送り手・受け手の双方がこのbitを反転させることで、固定長のリングを終わりなく使い回せます
- ドアベルレジスタ(Doorbell Register):ソフトウェアがTRBをリングに積んだ後、「新しい作業がある」とコントローラに知らせるために書き込むレジスタです。xHCIでは対象(コマンドリング、あるいは特定デバイス・特定エンドポイント)ごとに個別のドアベルが用意されています
- USBディスクリプタ:USBデバイスが自分の構成(ベンダー・製品情報、電源要件、提供する機能の一覧など)をホスト側に伝えるためのデータ構造群です。Device Descriptor(デバイス全体の情報)、Configuration Descriptor(電源設定などを束ねた構成の単位)、Interface Descriptor(キーボードやマウスなど機能ごとの単位)、Endpoint Descriptor(実際にデータをやり取りする通信路の単位)が階層的に連なっています
- HID(Human Interface Device):キーボード・マウスなど、人間からの入力を扱うUSBデバイスの機器クラスです
- Boot Protocol:HIDキーボード・マウスが対応を義務付けられている、固定フォーマットのレポート形式です。通常のHIDデバイスは自分がやり取りするデータの構造を記述したReport Descriptorを個別に解析する必要がありますが、Boot Protocolは常に決まったバイト数・決まった意味のデータ(キーボードなら8バイト:モディファイアキー1バイト・予約1バイト・同時押しキーコード6バイト)を返すため、Report Descriptorの解析を省略できます。PC起動直後のファームウェア画面でキー入力を受け付けられるのは、この固定フォーマットのおかげです
- コントロール転送(Control Transfer):USBデバイスの設定・照会に使う転送方式です。要求内容を伝えるSetup Stage、必要に応じてデータをやり取りするData Stage、転送の成否を確認するStatus Stageの3段階からなります
- 割り込み転送(Interrupt Transfer):一定の周期でホスト側からポーリングし、デバイス側に送るデータがある時だけ実際の転送が起きる、USBの転送方式の1つです。キーボードやマウスのように、データが発生するタイミングが不定期な機器に使われます
Zig言語関連
packed struct:フィールドをビット単位で隙間なく詰めて配置する、Zigの構造体宣言です。GDTのセグメントディスクリプタやIDTのゲートディスクリプタのような、ビットフィールドの集まりとして規格が定義されているハードウェア向けデータ構造を、意味の分かる名前付きフィールドとして表現するのに向いていますcomptime:Zigにおける「コンパイル時に評価する」ことを表すキーワードです。型や値を引数に取るジェネリックな関数・データ構造を、実行時のオーバーヘッドなしに生成する、といった用途で使われますnoreturn:関数が絶対に戻らないことを表す型です。無限ループで停止する関数や、エラー時に必ず異常終了する関数の戻り値型として使われますcallconv(.naked)(naked関数):関数のプロローグ/エピローグ(レジスタ退避やスタックフレーム構築などの自動生成コード)をコンパイラに生成させず、中身をアセンブラで完全に制御するための関数属性です。CPUや外部から直接ジャンプされるエントリポイント(割り込みハンドラなど)の実装に使われますextern struct:メモリ上のレイアウトをC言語と同じ規則に固定する構造体宣言です。CPUが積んだスタック上のデータや、ハードウェアが規定するバイナリレイアウトをそのまま構造体としてマッピングする際に使われます- モジュール(
@import):Zigのビルド単位です。Zig 0.16では、モジュールのルートディレクトリの外へ相対パスで@importできないという制約があり、複数のディレクトリにまたがるコードを共有する際は、共有したいファイルを独立したモジュールとしてbuild.zig側に定義し、依存として追加する必要があります std.mem.Allocator:Zig標準ライブラリ全体で共通して使われる、メモリ確保のインターフェースです。確保・解放・サイズ変更を行う関数ポインタの集まり(VTable)を実装することで、標準ライブラリの機能に独自のアロケータをそのまま渡せるようになりますstd_options/pub const panic:実行ファイルのルートモジュールで宣言することで、Zig標準ライブラリのデフォルト挙動(ログ出力やpanicハンドラなど)を上書きできる仕組みです。pub const panic = std.debug.FullPanic(myPanicFn);のように書くと、言語レベルの安全性チェック(unreachableや範囲外アクセスなど)が失敗した際の処理を差し替えられます
開発環境・ツール関連
- QEMU:CPUやハードウェアをソフトウェアでエミュレートする仮想マシンです。実機を使わずに素早く起動確認のループを回すために使われます
- OVMF:QEMU上でUEFIファームウェアの動作をエミュレートする、TianoCore EDK IIベースの実装です。
OVMF_CODE.fd(ファームウェア本体、読み取り専用)とOVMF_VARS.fd(UEFI変数の永続化領域、書き込み可能)の2ファイルで構成されます - KVM:Linuxカーネルが提供する仮想化支援機能です。QEMU起動時に
-enable-kvmを付けることでハードウェア支援による高速化が有効になります。/dev/kvmへの読み書き権限が必要で、Ubuntuではkvmグループへの参加が必要です - QMP(QEMU Machine Protocol):QEMUをUnixソケット経由で外部から操作・問い合わせするためのプロトコルです。
query-statusでVMの実行状態を、screendumpで画面の内容をPPM画像として取得できます。ソフトウェアエミュレーション(TCG)と異なり、-enable-kvm使用時はゲスト内部の例外処理がハードウェア支援で完結するため、QEMU側の-d intのような命令トレースオプションでは捕捉できない点に注意が必要です zig build:Zigのビルドシステムを実行するコマンドです。build.zigに定義したターゲット・モジュール構成に従ってビルドし、成果物をzig-out/以下に生成します
参考リンク
- OSDev Wiki —— 各記事を通して繰り返し参照している、OS自作コミュニティによる定番のリファレンスサイトです
- UEFI Specification(UEFI Forum) —— UEFI関連用語の一次情報源です
- Intel 64 and IA-32 Architectures Software Developer's Manual —— CPU/ハードウェア関連用語の一次情報源です