当前位置: 首页 > news >正文

用返利网站做爆款国外网站推广公司

用返利网站做爆款,国外网站推广公司,网站怎么优化自己免费,小游戏不用实名认证的游戏一、Linux 驱动-总线-设备模型 1、驱动分层 Linux内核需要兼容多个平台#xff0c;不同平台的寄存器设计不同导致操作方法不同#xff0c;故内核提出分层思想#xff0c;抽象出与硬件无关的软件层作为核心层来管理下层驱动#xff0c;各厂商根据自己的硬件编写驱动…一、Linux 驱动-总线-设备模型 1、驱动分层         Linux内核需要兼容多个平台不同平台的寄存器设计不同导致操作方法不同故内核提出分层思想抽象出与硬件无关的软件层作为核心层来管理下层驱动各厂商根据自己的硬件编写驱动代码作为硬件驱动层 2、设备总线驱动 Linux内核建立的 设备-总线-驱动 模型定义如下 1、device include\linux\device.h struct device {...struct bus_type *bus; /* type of bus device is on */struct device_driver *driver; /* which driver has allocated this device */struct device_node *of_node; /* associated device tree node */... }2、driver include\linux\device\driver.h struct device_driver {...struct bus_type *bus;... }3、bus include\linux\bus\bus.h struct bus_type {...int (*match)(struct device *dev, struct device_driver *drv);int (*probe)(struct device *dev);... }这里提到的是虚拟总线总线能将对应的设备和驱动进行匹配可以用下面的命令查看不同总线类型 /sys/bus # ls -l ...... drwxr-xr-x 4 root root 0 2023-02-21 13:35 i2c drwxr-xr-x 4 root root 0 2023-02-21 13:35 mmc drwxr-xr-x 5 root root 0 2023-02-21 13:35 pci drwxr-xr-x 4 root root 0 2023-02-20 07:09 platform drwxr-xr-x 4 root root 0 2023-02-21 13:35 scsi drwxr-xr-x 4 root root 0 2023-02-21 13:35 usb ...... 总线类型描述I2C总线挂在i2c总线(硬件)下的从设备比如加密芯片、rtc芯片、触摸屏芯片等等都需要驱动自然也要按照分离思想来设计。内核中的i2c 总线就是用来帮助i2c从设备的设备信息和驱动互相匹配的Platform总线 像i2c、spi这样硬件有实体总线的从设备驱动可以用总线来管理。那么没有总线的硬件外设怎么办比如gpio、uart、i2c控制器、spi 控制器…等等这些通通用 platform 总线来管理 二、驱动匹配设备过程简述 在写驱动时会用到一些注册函数比如platform_driver_registerspi_register_driver、i2c_add_driver接下来分析内核驱动和设备匹配的流程原理就是在注册到总线的时候去获取对方的链表并根据规则检测匹配后调用probe()也就是驱动的入口函数 以Platform Driver举例整个匹配过程如下 2.1 整体调用逻辑 module_platform_driver|-- module_driver|-- __platform_driver_register|-- driver_register|-- bus_add_driver|-- driver_attach|-- bus_for_each_dev|-- __driver_attach|-- driver_match_device|-- platform_match|-- of_driver_match_device|-- of_match_device|-- __of_match_node|-- driver_probe_device|-- really_probe|-- call_driver_probe|-- platform_probe|-- drv-probe() 2.2 module_platform_driver 封装了一层展开后实际上就是module_init和module_exit /* module_platform_driver() - Helper macro for drivers that dont do* anything special in module init/exit. This eliminates a lot of* boilerplate. Each module may only use this macro once, and* calling it replaces module_init() and module_exit()*/ #define module_platform_driver(__platform_driver) \module_driver(__platform_driver, platform_driver_register, \platform_driver_unregister) 例如对于MTK某平台UFS驱动传入__platform_driver 参数为 static struct platform_driver ufs_mtk_pltform {.probe ufs_mtk_probe,.remove ufs_mtk_remove,.shutdown ufshcd_pltfrm_shutdown,.driver {.name ufshcd-mtk,.pm ufs_mtk_pm_ops,.of_match_table ufs_mtk_of_match,}, }; 2.3 module_driver /*** module_driver() - Helper macro for drivers that dont do anything* special in module init/exit. This eliminates a lot of boilerplate.* Each module may only use this macro once, and calling it replaces* module_init() and module_exit().** __driver: driver name* __register: register function for this driver type* __unregister: unregister function for this driver type* ...: Additional arguments to be passed to __register and __unregister.** Use this macro to construct bus specific macros for registering* drivers, and do not use it on its own.*/ #define module_driver(__driver, __register, __unregister, ...) \ static int __init __driver##_init(void) \ { \return __register((__driver) , ##__VA_ARGS__); \ } \ module_init(__driver##_init); \ static void __exit __driver##_exit(void) \ { \__unregister((__driver) , ##__VA_ARGS__); \ } \ module_exit(__driver##_exit);2.4 __platform_driver_register 注意此处的__register是传进来的__platform_driver_register /*** __platform_driver_register - register a driver for platform-level devices* drv: platform driver structure* owner: owning module/driver*/ int __platform_driver_register(struct platform_driver *drv,struct module *owner) {drv-driver.owner owner;drv-driver.bus platform_bus_type;return driver_register(drv-driver); } EXPORT_SYMBOL_GPL(__platform_driver_register); 对bus参数进行赋值  struct bus_type platform_bus_type {.name platform,.dev_groups platform_dev_groups,.match platform_match,.uevent platform_uevent,.probe platform_probe,.remove platform_remove,.shutdown platform_shutdown,.dma_configure platform_dma_configure,.dma_cleanup platform_dma_cleanup,.pm platform_dev_pm_ops, }; EXPORT_SYMBOL_GPL(platform_bus_type);2.5 driver_register /*** driver_register - register driver with bus* drv: driver to register** We pass off most of the work to the bus_add_driver() call,* since most of the things we have to do deal with the bus* structures.*/ int driver_register(struct device_driver *drv) {......other driver_find(drv-name, drv-bus);if (other) {pr_err(Error: Driver %s is already registered, aborting...\n, drv-name);return -EBUSY;}ret bus_add_driver(drv);...... } EXPORT_SYMBOL_GPL(driver_register); 2.6 bus_add_driver drv-bus-p-drivers_autoprobe默认是1结构体定义时就赋值了 struct subsys_private {...unsigned int drivers_autoprobe:1; } /*** bus_add_driver - Add a driver to the bus.* drv: driver.*/ int bus_add_driver(struct device_driver *drv) {......if (drv-bus-p-drivers_autoprobe) {error driver_attach(drv);if (error)goto out_del_list;}...... } 2.7 driver_attach /*** driver_attach - try to bind driver to devices.* drv: driver.** Walk the list of devices that the bus has on it and try to* match the driver with each one. If driver_probe_device()* returns 0 and the dev-driver is set, weve found a* compatible pair.*/ int driver_attach(struct device_driver *drv) {return bus_for_each_dev(drv-bus, NULL, drv, __driver_attach); } EXPORT_SYMBOL_GPL(driver_attach); 2.8 bus_for_each_dev 此函数 fn 即为  __driver_attach 函数指针data参数 是 drv int bus_for_each_dev(struct bus_type *bus, struct device *start,void *data, int (*fn)(struct device *, void *)) {struct klist_iter i;struct device *dev;int error 0;if (!bus || !bus-p)return -EINVAL;klist_iter_init_node(bus-p-klist_devices, i,(start ? start-p-knode_bus : NULL));while (!error (dev next_device(i)))error fn(dev, data);klist_iter_exit(i);return error; } EXPORT_SYMBOL_GPL(bus_for_each_dev); 2.9 __driver_attach  static int __driver_attach(struct device *dev, void *data){......ret driver_match_device(drv, dev);......ret driver_probe_device(drv, dev);...... } 2.9.1.1 driver_match_device static inline int driver_match_device(struct device_driver *drv,struct device *dev) {return drv-bus-match ? drv-bus-match(dev, drv) : 1; }/* 返回 1 是可以继续往下走的 ret 0 不行*/ 可以看到在Register时有match回调  struct bus_type platform_bus_type {.......match platform_match,.probe platform_probe,...... }; 2.9.1.2 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);/* 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); }2.9.1.3 of_driver_match_device /*** of_driver_match_device - Tell if a drivers of_match_table matches a device.* drv: the device_driver structure to test* dev: the device structure to match against*/ 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; } of_match_table定义如下 static struct platform_driver ufs_mtk_pltform {.probe ufs_mtk_probe,.remove ufs_mtk_remove,.shutdown ufshcd_pltfrm_shutdown,.driver {.name ufshcd-mtk,.pm ufs_mtk_pm_ops,.of_match_table ufs_mtk_of_match,}, }; static const struct of_device_id ufs_mtk_of_match[] {{ .compatible mediatek,mtxxxx-ufshci }, };2.9.1.4 of_match_device const struct of_device_id *of_match_device(const struct of_device_id *matches,const struct device *dev) {if (!matches || !dev-of_node || dev-of_node_reused)return NULL;return of_match_node(matches, dev-of_node); } EXPORT_SYMBOL(of_match_device);2.9.1.5 of_match_node const struct of_device_id *of_match_node(const struct of_device_id *matches,const struct device_node *node) {match __of_match_node(matches, node); } EXPORT_SYMBOL(of_match_node);2.9.1.6 __of_match_node static const struct of_device_id *__of_match_node(const struct of_device_id *matches,const struct device_node *node) {for (; matches-name[0] ||matches-type[0] || matches-compatible[0]; matches) { /* 每次循环选择Vendor驱动中的match table结构体数组的下一个比较 */score __of_device_is_compatible(node, matches-compatible,matches-type, matches-name);if (score best_score) {best_match matches;best_score score;}}return best_match; }2.9.1.7 __of_device_is_compatible static int __of_device_is_compatible(const struct device_node *device,const char *compat, const char *type, const char *name) {......if (of_compat_cmp(cp, compat, strlen(compat)) 0) {score INT_MAX/2 - (index 2);break;}...... }cp即为从设备树节点中获取的compatible信息示例如下 ufshci: ufshci112b0000 {compatible mediatek,mtxxxx-ufshci;reg 0 0x112b0000 0 0x2a00; }2.9.2.1 driver_probe_device static int driver_probe_device(struct device_driver *drv, struct device *dev) {......ret __driver_probe_device(drv, dev);...... } 2.9.2.2 __driver_probe_device initcall_debug是一个内核参数可以跟踪initcall用来定位内核初始化的问题。在cmdline中增加initcall_debug后内核启动过程中会在调用每一个init函数前有一句打印结束后再有一句打印并且输出了该Init函数运行的时间通过这个信息可以用来定位启动过程中哪个init函数运行失败以及哪些init函数运行时间较长 really_probe_debug()内部还是调用了really _probe() static int __driver_probe_device(struct device_driver *drv, struct device *dev) {......if (initcall_debug)ret really_probe_debug(dev, drv);elseret really_probe(dev, drv);...... } 2.9.2.3 really_probe static int really_probe(struct device *dev, struct device_driver *drv) {......ret call_driver_probe(dev, drv);...... } 2.9.2.4 call_driver_probe static int call_driver_probe(struct device *dev,struct device_driver *drv) {......if (dev-bus-probe)ret dev-bus-probe(dev);else if (drv-probe)ret drv-probe(dev);...... } 2.9.2.5 platform_probe 不管走没有dev-bus-probe最终都会走到drv-probe static int platform_probe(struct device *_dev) {struct platform_driver *drv to_platform_driver(_dev-driver);struct platform_device *dev to_platform_device(_dev);......if (drv-probe) {ret drv-probe(dev);if (ret)dev_pm_domain_detach(_dev, true);}...... } 此时驱动匹配设备成功会走到之前Register的probe  static struct platform_driver ufs_mtk_pltform {.probe ufs_mtk_probe,...... }; 【参考博客】 [1] Linux设备驱动和设备匹配过程_linux驱动和设备匹配过程-CSDN博客 [2] platform 总线_怎么查询platform 总线-CSDN博客 [3] Linux Driver 和Device匹配过程分析1_linux设备驱动和设备树的match过程-CSDN博客 [4] Linux驱动四platform总线匹配过程_platform平台设备匹配过程-CSDN博客
http://www.dnsts.com.cn/news/76434.html

相关文章:

  • 如何在vps上搭建网站自学制作网站难不难
  • 农安县住房城乡建设局网站工商核名官网
  • 基于php的个人网站设计论文台州本地做网站的
  • 做ppt素材的网站网站做qq链接
  • 网站的icp 备案信息网站开发有哪几个阶段
  • php网站开发用什么phpwordpress 全站404
  • app和网站哪个难做互联网公司排名保定
  • 网站个人简介怎么做作风建设简报--门户网站
  • 学校网站 制作科技魏
  • 好的优化网站推广公司网站的icp 备案信息
  • 手机网站建设的公司开发网站如何选需要注意什么问题
  • 计算机上网题的模拟网站怎么做渭南企业网站建设
  • 著名办公空间设计seo服务器配置
  • 课程网站资源建设小结哪个网站做外贸生意
  • 万维网 网站到期云南住房建设厅网站
  • 专业做网站建设的公司江苏工信部网站备案
  • wordpress 课程插件南阳seo优化公司
  • 怎么自己做网站app上海最新新闻热点事件
  • 东莞做网站的联系电话吉林网站建设哪家有
  • c 做的网站怎么上传申请一个网站需要多少钱
  • 可以制作网站的软件交易类网站建设功能表
  • 如何建设一免费的网站wordpress 框架选择
  • 代理加盟网站上传了网站源码怎么做
  • 加强网站微信公众号平台建设城市建设与管理网站
  • 网站建设教程免费下载烟台百度网站推广
  • 泰安网站营销推广html引导页源码
  • .net网站模版母婴网站的功能设计
  • php网站后台密码忘记wordpress如何开发手机
  • 创建全国文明城市应知应会知识贵阳seo技术
  • 学生诚信档案建设网站公园网站建设方案 ppt