序文
(1) Linux ドライバー開発では、ドライバーをデバイス c ファイルまたはデバイス ツリー dts ファイルと照合できるためです。ドライバーとドライバーのマッチングルールを理解するために、いくつかの情報を参照し、ソースコードを読み、最終的には写真を使用して具体的にブログを書くことを計画しました。
(2) インターネット上の情報は基本的に同じで、ソースコードを辛口に載せて解析する。ただし、Linux の呼び出し関係は複雑すぎて目まいがしやすいので
(3) そこで、偉い人の分析をもとに、少しずつゆっくりとコードを見ていきました。最後に、ドライバーとデバイス間の一致ルールについてある程度理解しました。
(4)ソース コードから、Linux には 5 つの一致ルールがあることがわかります。。しかし、多くの場合、インターネット上には 4 つしか存在せず、acpi 一致ルールが無視されているか、デバイスの driver_override 一致ルールが無視されています。また、Punctual Atom、Wei Dongshan、Beijing Xunwei のチュートリアルも読みましたが、いずれもこれらの一致ルールをある程度無視していることがわかりました。無視される理由については後ほど説明します。
Linux ドライバーとデバイスの 5 つの一致ルール
ソースコードと一致するドライバーとデバイス
(1) Linux プラットフォーム バスでは、platform_match() 関数を使用してデバイスとドライバーを照合します。
(2) platform_match() 関数は drivers/base/platform.c ファイルに定義されており、
関数の内容は次のとおりです。
static int platform_match(struct device *dev, struct device_driver *drv)
{
struct platform_device *pdev = to_platform_device(dev);
struct platform_driver *pdrv = to_platform_driver(drv);
/* When driver_override is set, only bind to the matching driver */
if (pdev->driver_override)
return !strcmp(pdev->driver_override, drv->name);
/* Attempt an OF style match first */
if (of_driver_match_device(dev, drv))
return 1;
/* Then try ACPI style match */
if (acpi_driver_match_device(dev, drv))
return 1;
/* Then try to match against the id table */
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
/* fall-back to driver name match */
return (strcmp(pdev->name, drv->name) == 0);
}
(3) 上記のコードを見ると、if 判定が 4 つあり、最後の return でも strcmp() 関数を呼び出して文字列を比較していることがわかります。したがって、次のように結論付けることができます。Linux では、ドライバーとデバイスに対して 5 つの一致ルールがあります。
一致ルール 1
(1) まず、dev、drv、pdev、pdrv がそれぞれ何を表すかを知る必要があります。実際、彼の変数定義からそれがわかります。
<1>pdev = platform_device
<2>dev = platform_device.dev
<3>pdrv = platform_driver
<4>drv = platform_driver.driver
(2) このことからわかるように、まず、platform_device.driver_override に値が割り当てられているかどうかを判断し、割り当てられている場合は、一致するかどうかに関係なく、以降の手順は続行されません。
(3) platform_device.driver_override が割り当てられている場合は、platform_device.driver_override == platform_driver.driver.nameが true であるかどうかの判断を開始します。確立された場合、照合は成功し、そうでない場合、照合は失敗します。
if (pdev->driver_override)
return !strcmp(pdev->driver_override, drv->name);
マッチルール2
(1)これは主にデバイス ツリーと一致させるために使用されます。ここに知識ポイントがあります。この関数は type であり、接頭辞 of が付いている関数はデバイス ツリーと照合するために使用されていることがわかります。
(2) これは実際には、デバイス ツリーの互換性属性と一致するplatform_driver.driver.of_match_tableであることがわかります。(下図の通り)
static inline int of_driver_match_device(struct device *dev,const struct device_driver *drv)
{
return of_match_device(drv->of_match_table, dev) != NULL;
}
if (of_driver_match_device(dev, drv))
return 1;
マッチルール3
(1) この記事の多くの人は、ACPI マッチング方式について直接述べていますが、それ以上はありません。最初は、使っている人が少なすぎるからだと思って、そのことについて話すのを避けていました。まったく変更できないことがわかりました。
(2) ACPI は主に、x86 アーキテクチャの従来の PC プラットフォーム、特にデスクトップやラップトップで使用されます。これはより複雑で、豊富なシステム管理機能と電源管理機能が含まれています。開発者は変更できません。BIOS ファームウェアを変更できるのはマザーボード ベンダーのみです。
(3)したがって、これについて心配する必要はありません。
if (acpi_driver_match_device(dev, drv))
return 1;
マッチルール4
(1)4番目のルールは、platform_driver.id_tableに値が割り当てられているかどうかを判断し、割り当てられている場合は、一致するかどうかに関係なく、以降の手順は再度実行されません。
(2) 端的に言えば、platform_driver.id_table.name == platform_device.nameに名前マッチングを行わせ、名前が同じであればマッチング成功です。
static const struct platform_device_id *platform_match_id(
const struct platform_device_id *id,
struct platform_device *pdev)
{
while (id->name[0]) {
if (strcmp(pdev->name, id->name) == 0) {
pdev->id_entry = id;
return id;
}
id++;
}
return NULL;
}
if (pdrv->id_table)
return platform_match_id(pdrv->id_table, pdev) != NULL;
マッチルール5
(1) これは次のステップです。platform_device.driver_override と platform_driver.id_table は定義されていません。同時に、デバイス ツリーが正常に一致しませんでした。この試合は最終的に行われます。
(2) この照合は非常に簡単です。platform_device.name == platform_driver.driver.nameが等しいかどうか、等しい場合、ドライバーとデバイスが正常に一致したことを意味します。そうしないと、ドライバーとデバイス間の完全な一致が失敗します。
return (strcmp(pdev->name, drv->name) == 0);
要約する
(1) 一般的に、ドライバーの platform_driver 構造体には 2 つだけ記述します。
<1>platform_driver.driver.name は、c ファイルと一致させるために使用されます。
<2>platform_driver.driver.of_match_table は、デバイス ツリーとの照合に使用されます。
(2)注: 上記の 2 つの一致するメソッドのみを作成した場合、platform_device.driver_override も platform_driver.id_table も割り当てることができません。
(3) Linux ドライバーには一致ルールが 4 つしかない、とよく言われるのはなぜですか? 理由は簡単で、ACPI 開発者は変更を加えることができず、マザーボード サプライヤーだけが BIOS ファームウェアを変更できるため、誰もがそれを無視することを選択するからです。
(4) なぜ多くの人が driver_override 一致ルールを無視するのでしょうか? 非常に単純ですが、driver_override マッチング ルールが割り当てられている場合、次の 4 つのルールは無効になります。したがって、通常はこれを書かないでください。
static struct platform_driver gpio_platform_driver = {
.driver = {
.name = "100ask_gpio_plat_drv", //用于和设备c文件匹配
.of_match_table = gpio_dt_ids, //用于与设备树匹配
},
.probe = gpio_drv_probe,
.remove = gpio_drv_remove,
};