LinuxドライバはUEFIファームウェアが提供する機能をどのように呼び出しますか?

LinuxドライバはUEFIファームウェアが提供する機能をどのように呼び出しますか?

私は仕事用コンピュータアーキテクチャについてもっと学んでおり、ACPIを終えました。私が他のエンジニアと話している間にNVMeと同じことを理解したのは、OEMにUEFI NVMeドライバがあることですが、起動後にOSドライバがその機能に代わるということです。

起動プロセス中に、LinuxはUEFIドライバを活用し、ロードされると独自のドライバと置き換えられます。

私の質問は、ソースコードがどのように見えるかです。たとえば、私が見ているのはNVMeソースコード

ファームウェアがLinuxドライバが呼び出す必要があるいくつかの標準ベースのインターフェイスを公開する必要があるとしますか? (ACPI?)

答え1

今日、外部デバイスは通常PCIeです。各PCIeデバイスには独自のPCIe構成スペースがあり、ブリッジされていないデバイスの場合、このスペースのヘッダーは次のとおりです。

PCIe構成スペース

BIOS(またはUEFI)の主なタスクの1つは、各PCIeデバイスBase Address Registers(= BAR)に必要なメモリ量を尋ね、その領域をCPUメモリのどこかに予約し、その領域の開始アドレスを書き換えることです。

オペレーティングシステムが起動したら、各デバイスのPCIe構成スペースのVendor ID値を確認Device IDし、その情報に基づいて適切なドライバを設定します。ドライバはBIOS(UEFI)によって作成されたBARレジスタから値を読み込み、対応するメモリ(またはio)を使用します。

このように、デバイスドライバからUEFIサービスを要求せずに、基本情報がデバイス自体に書き込まれます。

Linux APIの場合、これらのBARで使用できるいくつかの機能があります。たとえば、次のことを確認してください。

unsigned long pci_resource_start(struct pci_dev *dev, int bar);
unsigned long pci_resource_end(struct pci_dev *dev, int bar);
unsigned long pci_resource_flags(struct pci_dev *dev, int bar);

または

int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name)

より完全な文書については、次のLinux Device Drivers本を参照してください。 https://www.xml.com/ldd/chapter/book/ch15.html

またはPCIのカーネル文書:

https://www.kernel.org/doc/html/latest/driver-api/pci/pci.html#c.pci_request_region

https://www.kernel.org/doc/html/latest/PCI/pci.html

関連情報