在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

linux內(nèi)核中的driver_register介紹

嵌入式小生 ? 來源:嵌入式小生 ? 2023-07-14 09:17 ? 次閱讀

1、簡介

linux內(nèi)核注冊驅(qū)動由driver_register()完成。它將驅(qū)動程序的信息添加到內(nèi)核的驅(qū)動程序列表中,使得內(nèi)核能夠在需要時與該驅(qū)動程序進行交互。

當(dāng)調(diào)用driver_register()函數(shù)時,內(nèi)核會將驅(qū)動程序添加到內(nèi)核驅(qū)動程序列表中,并在需要時使用該驅(qū)動程序來匹配和初始化設(shè)備。驅(qū)動程序的探測函數(shù)(probe)將在設(shè)備與驅(qū)動程序匹配時調(diào)用,以便進行設(shè)備的初始化。移除函數(shù)(remove)將在設(shè)備從系統(tǒng)中移除時調(diào)用,以進行相關(guān)的清理操作。

通過調(diào)用driver_register()函數(shù),驅(qū)動程序可以將自身注冊到內(nèi)核中,從而使得內(nèi)核能夠管理和與驅(qū)動程序進行交互。這為設(shè)備的探測、初始化、配置和移除提供了必要的框架和支持。

內(nèi)核中,幾乎所有的驅(qū)動子系統(tǒng)都會以該函數(shù)進行封裝,開放出對應(yīng)驅(qū)動的注冊函數(shù),例如PCI驅(qū)動框架,在/drivers/pic/pci-driver.c文件中會調(diào)用該函數(shù):

78dbf582-21db-11ee-962d-dac502259ad0.png

再比如對應(yīng)i2c設(shè)備驅(qū)動,在i2c驅(qū)動框架下的/driver/i2c/i2c-core.c文件中有如下代碼:

793a14b4-21db-11ee-962d-dac502259ad0.png

綜上可知,driver_register()在幾乎所有的驅(qū)動子系統(tǒng)中都會使用到。兜兜轉(zhuǎn)轉(zhuǎn),最后都會調(diào)用到該函數(shù)。

2、driver_register分析

在linux內(nèi)核中,struct device_driver結(jié)構(gòu)體用于表示一個設(shè)備驅(qū)動程序。它包含了驅(qū)動程序的相關(guān)信息,如名稱、總線類型、探測函數(shù)、移除函數(shù)等,用于與設(shè)備進行匹配、初始化和清理操作。struct device_driver結(jié)構(gòu)體提供了設(shè)備驅(qū)動程序的基本信息和回調(diào)函數(shù),用于與設(shè)備進行匹配、初始化、清理和管理。

通過使用該結(jié)構(gòu)體,驅(qū)動程序能夠在設(shè)備與驅(qū)動程序匹配時進行初始化操作,并在設(shè)備移除或系統(tǒng)關(guān)機時進行相應(yīng)的清理操作。此外,還可以通過屬性組和電源管理操作等擴展功能來增強驅(qū)動程序的功能和靈活性。該結(jié)構(gòu)定義如下:

structdevice_driver{
constchar*name;//
structbus_type*bus;//驅(qū)動程序所屬的總線類型。

structmodule*owner;//模塊擁有者
constchar*mod_name;//在構(gòu)建內(nèi)建模塊時使用

boolsuppress_bind_attrs;//是否禁用通過sysfsbound/unbound操作

conststructof_device_id*of_match_table;//設(shè)備樹匹配表
conststructacpi_device_id*acpi_match_table;//ACPI匹配表。

int(*probe)(structdevice*dev);//驅(qū)動程序的探測函數(shù),用于在設(shè)備與驅(qū)動程序匹配時進行初始化。
int(*remove)(structdevice*dev);//驅(qū)動程序的移除函數(shù),用于在設(shè)備從系統(tǒng)中移除時進行清理。
void(*shutdown)(structdevice*dev);//驅(qū)動程序的關(guān)機函數(shù),用于在系統(tǒng)關(guān)機時進行相關(guān)的清理操作。
int(*suspend)(structdevice*dev,pm_message_tstate);//驅(qū)動程序的掛起函數(shù),用于在設(shè)備進入掛起狀態(tài)時進行相關(guān)的操作。
int(*resume)(structdevice*dev);//驅(qū)動程序的恢復(fù)函數(shù),用于在設(shè)備從掛起狀態(tài)恢復(fù)時進行相關(guān)的操作。
conststructattribute_group**groups;//驅(qū)動程序的屬性組,用于提供設(shè)備的特定屬性。

conststructdev_pm_ops*pm;//驅(qū)動程序的電源管理操作,用于控制設(shè)備的電源管理。

structdriver_private*p;//驅(qū)動核心的私有數(shù)據(jù)。驅(qū)動核心能訪問。
};

driver_register函數(shù)用于向設(shè)備驅(qū)動模型注冊一個設(shè)備驅(qū)動,實現(xiàn)在/drivers/base/driver.c文件中:

intdriver_register(structdevice_driver*drv)
{
intret;
structdevice_driver*other;

BUG_ON(!drv->bus->p);

if((drv->bus->probe&&drv->probe)||
(drv->bus->remove&&drv->remove)||
(drv->bus->shutdown&&drv->shutdown))
printk(KERN_WARNING"Driver'%s'needsupdating-pleaseuse"
"bus_typemethods
",drv->name);

other=driver_find(drv->name,drv->bus);
if(other){
printk(KERN_ERR"Error:Driver'%s'isalreadyregistered,"
"aborting...
",drv->name);
return-EBUSY;
}

ret=bus_add_driver(drv);
if(ret)
returnret;
ret=driver_add_groups(drv,drv->groups);
if(ret){
bus_remove_driver(drv);
returnret;
}
kobject_uevent(&drv->p->kobj,KOBJ_ADD);

returnret;
}

driver_register()具體執(zhí)行流程如下:

(1)調(diào)用driver_find()通過名字找到bus上的driver。

(2)調(diào)用bus_add_driver()添加一個driver到bus。

(3)調(diào)用driver_add_groups()將屬性組(attribute_group)添加到驅(qū)動程序中。

(4)調(diào)用kobject_uevent()觸發(fā)內(nèi)核KOBJ_ADD事件,用于向用戶空間發(fā)送KOBJ_ADD事件通知。

下文將展開driver_find()和bus_add_driver()進行分析。

(2-1)driver_find分析

該函數(shù)接收兩個參數(shù)

(1)name:驅(qū)動程序的名稱。

(2)bus:待被掃描的bus。

函數(shù)實現(xiàn)如下:

79690530-21db-11ee-962d-dac502259ad0.png

調(diào)用kset_find_obj()根據(jù)name尋找是否有kobject,如果找到了,則使用to_driver()返解出struct driver_private,然后將driver_private->driver作為參數(shù)返回;否則返回NULL。

該行代碼中:

structkobject*k=kset_find_obj(bus->p->drivers_kset,name);

bus->p->drivers_kset本質(zhì)是struct kset,struct kset是linux內(nèi)核對象的集合,添加的設(shè)備驅(qū)動將作為內(nèi)核對象添加到對應(yīng)的kset集合中。kset_find_obj()則用于在kset中搜索出對應(yīng)name的內(nèi)核對象,該函數(shù)實現(xiàn)如下:

79855bcc-21db-11ee-962d-dac502259ad0.png

回到driver_register()中,如果driver_find()找到了對應(yīng)的device_driver,則證明該設(shè)備驅(qū)動已經(jīng)注冊過了,這時候則返回退出driver_register();否則繼續(xù)執(zhí)行后續(xù)的bus_add_driver()操作。

(2-2)bus_add_driver分析

bus_add_driver()實現(xiàn)在/drivers/base/bus.c中,將執(zhí)行下列具體的邏輯:

(1)從drv->bus中解析出bus,如果bus為NULL,則返回退出bus_add_driver:

bus=bus_get(drv->bus);
if(!bus)
return-EINVAL;

(2)調(diào)用kzalloc()分配一個struct driver_private內(nèi)存空間:

79c2e424-21db-11ee-962d-dac502259ad0.png

(3)調(diào)用klist_init()初始化設(shè)備鏈表klist_devices:

klist_init(&priv->klist_devices,NULL,NULL);

(4)設(shè)置驅(qū)動私有數(shù)據(jù)的driver和kobj.kset字段,并將驅(qū)動私有數(shù)據(jù)設(shè)置到驅(qū)動程序的->p字段:

priv->driver=drv;
drv->p=priv;
priv->kobj.kset=bus->p->drivers_kset;

(5)調(diào)用kobject_init_and_add()初始化設(shè)備私有數(shù)據(jù)中的內(nèi)核對象,并指定驅(qū)動類型driver_ktype:

error=kobject_init_and_add(&priv->kobj,&driver_ktype,NULL,
"%s",drv->name);
if(error)
gotoout_unregister;

driver_ktype定義如下:

staticstructkobj_typedriver_ktype={
.sysfs_ops=&driver_sysfs_ops,
.release=driver_release,
};

(6)使用klist_add_tail()將priv->knode_bus節(jié)點添加到bus->p->klist_drivers總線的驅(qū)動鏈表中。

(7)如果設(shè)置了驅(qū)動所屬的bus的drivers_autoprobe,則調(diào)用drvier_attach()嘗試將驅(qū)動程序綁定到設(shè)備:

79ec2f28-21db-11ee-962d-dac502259ad0.png

(8)使用moudle_add_drvier將設(shè)備驅(qū)動程序添加到內(nèi)核模塊系統(tǒng)中,使之可以與設(shè)備進行關(guān)聯(lián)。通過調(diào)用這個函數(shù),可以將設(shè)備驅(qū)動程序注冊到內(nèi)核的設(shè)備驅(qū)動程序列表中,以便在設(shè)備被發(fā)現(xiàn)時自動加載并與之匹配。

(9)調(diào)用driver_create_file()為設(shè)備驅(qū)動創(chuàng)建sysfs中的屬性文件。該文件將顯示在/sys/bus//drivers//目錄下,其中是設(shè)備所屬的總線類型,是設(shè)備驅(qū)動程序的名稱。

(10)調(diào)用driver_add_groups()將設(shè)備驅(qū)動程序的bus的屬性組添加到sysfs中,這些屬性組將顯示在/sys/bus//drivers//目錄下,其中是設(shè)備所屬的總線類型,是設(shè)備驅(qū)動程序的名稱。

3、總結(jié)

driver_register()是linux 內(nèi)核中用于注冊設(shè)備驅(qū)動程序的函數(shù)。它屬于linux設(shè)備驅(qū)動模型的一部分,用于將驅(qū)動程序添加到內(nèi)核的設(shè)備驅(qū)動程序列表中,以便內(nèi)核可以與相應(yīng)的硬件設(shè)備進行交互。在內(nèi)核中的大部分驅(qū)動都會形成自己的驅(qū)動框架核心,例如:USB、i2c、spi等,這些驅(qū)動框架核心也一般都會封裝出自己的注冊函數(shù),但是這些注冊函數(shù)本質(zhì)上都是調(diào)用driver_register()實現(xiàn)驅(qū)動的注冊。例如下圖所示:

7a21d18c-21db-11ee-962d-dac502259ad0.png





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • USB接口
    +關(guān)注

    關(guān)注

    9

    文章

    701

    瀏覽量

    55651
  • 電源管理
    +關(guān)注

    關(guān)注

    115

    文章

    6183

    瀏覽量

    144506
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    316

    瀏覽量

    21650
  • I2C驅(qū)動
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    7058
  • ADD
    ADD
    +關(guān)注

    關(guān)注

    1

    文章

    20

    瀏覽量

    9428

原文標(biāo)題:linux內(nèi)核中竟有如此“高冷”的driver_register

文章出處:【微信號:嵌入式小生,微信公眾號:嵌入式小生】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    Linux內(nèi)核開發(fā)工具介紹

    進行嵌入式Linux產(chǎn)品開發(fā),往往需要對內(nèi)核進行裁剪和定制,以滿足嵌入式產(chǎn)品的功能和性能需求。本文介紹幾種閱讀Linux內(nèi)核源碼的工具和方法
    發(fā)表于 12-29 15:20 ?4710次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>內(nèi)核</b>開發(fā)工具<b class='flag-5'>介紹</b>

    Linux內(nèi)核開發(fā)工具介紹

    進行嵌入式Linux產(chǎn)品開發(fā),往往需要對內(nèi)核進行裁剪和定制,以滿足嵌入式產(chǎn)品的功能和性能需求。本文介紹幾種閱讀Linux內(nèi)核源碼的工具和方法
    發(fā)表于 01-06 17:20

    總線設(shè)備驅(qū)動模型淺析

    時,最終都會調(diào)用到:int driver_register(structdevice_driver *drv){ // 將驅(qū)動綁定在對應(yīng)的總線上,主要工作把驅(qū)動(device_driver)添加到總線
    發(fā)表于 08-22 16:19

    iMX6Q開發(fā)板設(shè)備樹內(nèi)核-注冊驅(qū)動例程介紹

    `文檔主要講解在 iMX6Q/D/PLUS 開發(fā)板的設(shè)備樹內(nèi)核(4.1.15)源碼,設(shè)備樹注冊驅(qū)動和非設(shè)備樹的類似。 1 注冊驅(qū)動源碼分析 設(shè)備樹的內(nèi)核驅(qū)動,platform_
    發(fā)表于 07-18 15:42

    Linux內(nèi)核教程

    本章學(xué)習(xí)目標(biāo)掌握LINUX內(nèi)核版本的含義理解并掌握進程的概念掌握管道的概念及實現(xiàn)了解內(nèi)核的數(shù)據(jù)結(jié)構(gòu)了解LINUX內(nèi)核的算法掌握
    發(fā)表于 04-10 16:59 ?0次下載

    Linux內(nèi)核學(xué)習(xí)起步課件

    Linux內(nèi)核學(xué)習(xí)起步介紹
    發(fā)表于 04-10 17:22 ?0次下載

    Linux內(nèi)核配置系統(tǒng)詳解

    隨著 Linux 操作系統(tǒng)的廣泛應(yīng)用,特別是 Linux 在嵌入式領(lǐng)域的發(fā)展,越來越多的人開始投身到 Linux 內(nèi)核級的開發(fā)。面對日益龐
    發(fā)表于 11-01 15:45 ?4次下載

    Linux設(shè)備模型:device和device driver

    device和device driverLinux驅(qū)動開發(fā)的基本概念。Linux kernel的思路很簡單:驅(qū)動開發(fā),就是要開發(fā)指定的軟件(driver)以驅(qū)動指定的設(shè)備,所以ker
    發(fā)表于 05-10 11:21 ?2458次閱讀

    你了解Embeded linux的probe

    所謂的"probe”,是指在Linux內(nèi)核,如果存在相同名稱的device和device_driver內(nèi)核就會執(zhí)行device_
    發(fā)表于 05-14 16:18 ?3960次閱讀
    你了解Embeded <b class='flag-5'>linux</b><b class='flag-5'>中</b>的probe

    linux內(nèi)核參數(shù)設(shè)置_linux內(nèi)核的功能有哪些

    本文主要闡述了linux內(nèi)核參數(shù)設(shè)置及linux內(nèi)核的功能。
    發(fā)表于 09-17 14:40 ?1375次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b>參數(shù)設(shè)置_<b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b>的功能有哪些

    Linux內(nèi)核的編譯與運行

    本文檔的主要內(nèi)容詳細(xì)介紹的是Linux內(nèi)核的編譯與運行免費下載。
    發(fā)表于 03-25 13:48 ?11次下載

    Linux內(nèi)核結(jié)構(gòu)介紹

    通常情況下,Linux內(nèi)核的結(jié)構(gòu)被認(rèn)為包含以下11個主要層次。
    的頭像 發(fā)表于 04-14 11:59 ?1272次閱讀

    萬千設(shè)備,linux內(nèi)核如何知道?

    linux內(nèi)核設(shè)備的注冊由device_register()函數(shù)完成,這個函數(shù)是linux設(shè)備驅(qū)動模型的核心函數(shù)
    的頭像 發(fā)表于 07-12 08:52 ?851次閱讀
    萬千設(shè)備,<b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b>如何知道?

    使用 PREEMPT_RT 在 Ubuntu 構(gòu)建實時 Linux 內(nèi)核

    的實時內(nèi)核補丁來完成。簡介我們曾介紹過在Ubuntu22.04啟用實時Linux內(nèi)核有多簡單,因為Canonical已將該
    的頭像 發(fā)表于 04-12 08:36 ?2458次閱讀
    使用 PREEMPT_RT 在 Ubuntu <b class='flag-5'>中</b>構(gòu)建實時 <b class='flag-5'>Linux</b> <b class='flag-5'>內(nèi)核</b>

    linux內(nèi)核通用HID觸摸驅(qū)動

    linux內(nèi)核,為HID觸摸面板實現(xiàn)了一個通用的驅(qū)動程序,位于/drivers/hid/hid-multitouch.c文件。hid觸摸驅(qū)動是以struct hid_
    的頭像 發(fā)表于 10-29 10:55 ?603次閱讀
    <b class='flag-5'>linux</b><b class='flag-5'>內(nèi)核</b><b class='flag-5'>中</b>通用HID觸摸驅(qū)動
    主站蜘蛛池模板: 轻点灬大ji巴太粗太长了啊h| 天天摸天天操天天干| 天天干天天操天天射| 天天精品在线| tube69日本| 色偷偷7777www人| 俺去啦五月| 四虎黄色网| 四虎影院在线观看网站| 男人天堂久久| 成人免费看黄页网址大全| 视频在线精品| 国产男靠女免费视频网站| 深爱综合网| 国产又色| 免费观看在线永久免费xx视频| 欧美精品网站| 亚洲综合香蕉| 美女视频永久黄网站免费观看国产 | 欧美猛交lxxxxxxxxx| 四虎精品影院| 亚洲黄色一区| 久久在线精品| 国产性色视频| 手机在线你懂的| 综合网 色天使| 女人被狂躁视频免费网站| 台湾一级毛片| 亚洲综合成人网在线观看| 高清成人| 114毛片免费观看网站| 色香五月| 色综合久久88| 亚洲人在线| 国产四虎| 4455亚洲| 精品啪啪| ccav在线永久免费看| 毛片免费网| 日本高清在线3344www| 欧美天天视频|