免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6147 | 回复: 0
打印 上一主题 下一主题

[FreeBSD] freebsd源代码中设备驱动接口bus_setup_intr怎么实现的 [复制链接]

论坛徽章:
0
1 [报告]
发表于 2015-08-04 14:17 |显示全部楼层
下面是建议:

1:
认真看一下<Freebsd操作系统设计与实现>第7章第5节,其中关键一句话--"newbus系统在设计上的关键目标是给编写驱动程序的程序员提供一个
稳定的应用程序二进制接口".

2:
参考<Freebsd系统结构手册>第三章的简单描述.

3:
对于/usr/src/sys/kern/ 目录下的.m结尾的文件,以bus_if.m文件为例,可以执行下面:
awk -f /usr/src/sys/tools/makeobjops.awk ./bus_if.m -h -> 生成bus_if.c
awk -f /usr/src/sys/tools/makeobjops.awk ./bus_if.m -c -> 生成bus_if.h

在bus_if.c里面能找到BUS_SETUP_INTR的定义.
上面awk的处理实在构建kernel阶段自动完成的.

4:
看一下freebsd驱动程序的框架.

typedef struct kobj_class        driver_t;
宏DRIVER_MODULE以及驱动程序中如何使用DRIVER_MODULE.

分析完宏DRIVER_MODULE的实现以及在驱动程序代码中如何使用后,你会发现完全可以导出freebsd的设备树结构的简单模型.


5:
在初始化阶段,会先对DRIVER_MODULE注册到内核的模块进行处理,建立必要的数据结构等.

6:
配置设备阶段,看一下函数configure_first就可以,当这个函数执行完后,设备的树形结构就会建立.
SYSINIT(configure1, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure_first, NULL);
  1. /*
  2. * Determine i/o configuration for a machine.
  3. */
  4. static void
  5. configure_first(dummy)
  6.         void *dummy;
  7. {

  8.         /* nexus0 is the top of the amd64 device tree */
  9.         device_add_child(root_bus, "nexus", 0);
  10. }


  11. 下面是一个简单的设备树:
  12. nexus0
  13.   acpi0
  14.     pcib0
  15.       pci0
  16.        em0 <----intel网卡

  17. 当探测到intel网卡时,驱动程序就会调用函数bus_setup_intr建立中断等.

  18. /**
  19. * @brief Wrapper function for BUS_SETUP_INTR().
  20. *
  21. * This function simply calls the BUS_SETUP_INTR() method of the
  22. * parent of @p dev.
  23. */
  24. int
  25. bus_setup_intr(device_t dev, struct resource *r, int flags,
  26.     driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
  27. {
  28.         int error;

  29.         if (dev->parent == NULL)
  30.                 return (EINVAL);
  31.         error = BUS_SETUP_INTR(dev->parent, dev, r, flags, filter, handler,
  32.             arg, cookiep);
  33.         if (error != 0)
  34.                 return (error);
  35.         if (handler != NULL && !(flags & INTR_MPSAFE))
  36.                 device_printf(dev, "[GIANT-LOCKED]\n");
  37.         return (0);
  38. }

  39. BUS_SETUP_INTR基本上都是调用父设备的bus_setup_intr方法,在到达设备nexus0之前,相应设备的bus_setup_intr方法可以简单的认为是调用bus_generic_setup_intr方法.

  40. /**
  41. * @brief Helper function for implementing BUS_SETUP_INTR().
  42. *
  43. * This simple implementation of BUS_SETUP_INTR() simply calls the
  44. * BUS_SETUP_INTR() method of the parent of @p dev.
  45. */
  46. int
  47. bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
  48.     int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
  49.     void **cookiep)
  50. {
  51.         /* Propagate up the bus hierarchy until someone handles it. */
  52.         if (dev->parent)
  53.                 return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
  54.                     filter, intr, arg, cookiep));
  55.         return (EINVAL);
  56. }

  57. 当到达设备nexus0时,将调用nexus_setup_intr方法:

  58. 下面的在文件/usr/src/sys/x86/x86/nexus.c中:
  59. /*
  60. * This code implements a `root nexus' for Intel Architecture
  61. * machines.  The function of the root nexus is to serve as an
  62. * attachment point for both processors and buses, and to manage
  63. * resources which are common to all of them.  In particular,
  64. * this code implements the core resource managers for interrupt
  65. * requests, DMA requests (which rightfully should be a part of the
  66. * ISA code but it's easier to do it here for now), I/O port addresses,
  67. * and I/O memory address space.
  68. */

  69. static device_method_t nexus_methods[] = {
  70. ..........................................................
  71.         DEVMETHOD(bus_print_child,      nexus_print_child),
  72.         DEVMETHOD(bus_add_child,        nexus_add_child),
  73.         DEVMETHOD(bus_alloc_resource,   nexus_alloc_resource),
  74.         DEVMETHOD(bus_adjust_resource,  nexus_adjust_resource),
  75.         DEVMETHOD(bus_release_resource, nexus_release_resource),
  76.         DEVMETHOD(bus_activate_resource, nexus_activate_resource),
  77.         DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
  78.         DEVMETHOD(bus_setup_intr,       nexus_setup_intr), <-------------
  79.         DEVMETHOD(bus_teardown_intr,    nexus_teardown_intr),
  80. ...........................................................

  81.         { 0, 0 }
  82. };
复制代码

评分

参与人数 1可用积分 +10 信誉积分 +6 收起 理由
lsstarboy + 10 + 6 赞一个!

查看全部评分

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP