今天我以fb设备的注册过程来分析platform设备的添加流程
platform总线是kernel中最近加入的一种虚拟总线,它被用来连接处在仅有最少基本组件的总线上的那些设备.这样的总线包括许多片上系统上的那些用来整合外设的总线, 也包括一些"古董" PC上的连接器; 但不包括像PCI或USB这样的有庞大正规说明的总线.
平台设备
~~~~~~
平台设备通常指的是系统中的自治体, 包括老式的基于端口的设备和连接外设总线的北桥(host bridges),以及集成在片上系统中的绝大多数控制器. 它们通常拥有的一个共同特征是直接编址于CPU总线上. 即使在某些罕见的情况下, 平台设备会通过某段其他类型的总线连入系统, 它们的寄存器也会被直接编址.平台设备会分到一个名称(用在驱动绑定中)以及一系列诸如地址和中断请求号(IRQ)之类的资源. 那什么情况可以使用platform driver机制编写驱动呢? 我的理解是只要和内核本身运行依赖性不大的外围设备(换句话说只要不在内核运行所需的一个最小系统之内的设备),相对独立的,拥有各自独自的资源(addresses and IRQs),都可以用platform_driver实现。如:lcd,usb,uart等,都可以用platfrom_driver写,而timer,irq等最小系统之内的设备则最好不用platfrom_driver机制,实际上内核实现也是这样的。下面继续我们的分析过程。 首先要定义一个platform_device,我们先来看一下platform_device结构的定义,如下所示: // include/linux/platform_device.h: 16struct platform_device { 17 const char * name; 18 u32 id; 19 struct device dev; 20 u32 num_resources; 21 struct resource * resource; 22}; 下面是对应的FB设备的变量定义 // arch/arm/mach-pxa/generic.c 229static struct platform_device pxafb_device = { 230 .name = "pxa2xx-fb", 231 .id = -1, 232 .dev = { 233 .platform_data = &pxa_fb_info, 234 .dma_mask = &fb_dma_mask, 235 .coherent_dma_mask = 0xffffffff, 236 }, 237 .num_resources = ARRAY_SIZE(pxafb_resources), 238 .resource = pxafb_resources, 239}; 由上可以看出,name成员表示设备名,系统正是通过这个名字来与驱动绑定的,所以驱动里面相应的设备名必须与该项相符合;id表示设备编号,id的值为-1表示只有一个这样的设备。 该结构中比较重要的一个成员就是resource, Linux设计了这个通用的数据结构来描述各种I/O资源(如:I/O端口、外设内存、DMA和IRQ等)。它的定义如下: // include/linux/ioport.h: 16struct resource { 17 const char *name; 18 unsigned long start, end;