- 论坛徽章:
- 0
|
下面是建议:
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);- /*
- * Determine i/o configuration for a machine.
- */
- static void
- configure_first(dummy)
- void *dummy;
- {
- /* nexus0 is the top of the amd64 device tree */
- device_add_child(root_bus, "nexus", 0);
- }
- 下面是一个简单的设备树:
- nexus0
- acpi0
- pcib0
- pci0
- em0 <----intel网卡
- 当探测到intel网卡时,驱动程序就会调用函数bus_setup_intr建立中断等.
- /**
- * @brief Wrapper function for BUS_SETUP_INTR().
- *
- * This function simply calls the BUS_SETUP_INTR() method of the
- * parent of @p dev.
- */
- int
- bus_setup_intr(device_t dev, struct resource *r, int flags,
- driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep)
- {
- int error;
- if (dev->parent == NULL)
- return (EINVAL);
- error = BUS_SETUP_INTR(dev->parent, dev, r, flags, filter, handler,
- arg, cookiep);
- if (error != 0)
- return (error);
- if (handler != NULL && !(flags & INTR_MPSAFE))
- device_printf(dev, "[GIANT-LOCKED]\n");
- return (0);
- }
- BUS_SETUP_INTR基本上都是调用父设备的bus_setup_intr方法,在到达设备nexus0之前,相应设备的bus_setup_intr方法可以简单的认为是调用bus_generic_setup_intr方法.
- /**
- * @brief Helper function for implementing BUS_SETUP_INTR().
- *
- * This simple implementation of BUS_SETUP_INTR() simply calls the
- * BUS_SETUP_INTR() method of the parent of @p dev.
- */
- int
- bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
- int flags, driver_filter_t *filter, driver_intr_t *intr, void *arg,
- void **cookiep)
- {
- /* Propagate up the bus hierarchy until someone handles it. */
- if (dev->parent)
- return (BUS_SETUP_INTR(dev->parent, child, irq, flags,
- filter, intr, arg, cookiep));
- return (EINVAL);
- }
- 当到达设备nexus0时,将调用nexus_setup_intr方法:
- 下面的在文件/usr/src/sys/x86/x86/nexus.c中:
- /*
- * This code implements a `root nexus' for Intel Architecture
- * machines. The function of the root nexus is to serve as an
- * attachment point for both processors and buses, and to manage
- * resources which are common to all of them. In particular,
- * this code implements the core resource managers for interrupt
- * requests, DMA requests (which rightfully should be a part of the
- * ISA code but it's easier to do it here for now), I/O port addresses,
- * and I/O memory address space.
- */
- static device_method_t nexus_methods[] = {
- ..........................................................
- DEVMETHOD(bus_print_child, nexus_print_child),
- DEVMETHOD(bus_add_child, nexus_add_child),
- DEVMETHOD(bus_alloc_resource, nexus_alloc_resource),
- DEVMETHOD(bus_adjust_resource, nexus_adjust_resource),
- DEVMETHOD(bus_release_resource, nexus_release_resource),
- DEVMETHOD(bus_activate_resource, nexus_activate_resource),
- DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
- DEVMETHOD(bus_setup_intr, nexus_setup_intr), <-------------
- DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
- ...........................................................
- { 0, 0 }
- };
复制代码 |
评分
-
查看全部评分
|