Linux 3.x 的platform

众所周知2011linux创始人Linus Torvalds在社区的一句脏话!引发了社区震动!从而导致代码大换血!Dts(device tree source)则就是这个时候被应用在我们的各种处理器中目录下的!早期这种模式被用于IBM PowerPC等体系架构下使用的Flattened Device TreeFDT)。Device Tree是一种描述硬件的数据结构,它起源于 OpenFirmware (OF)。在Linux 2.6中,各种架构的板极硬件过多地被硬编码在arch/xxx/plat-xxxarch/xxx/mach-xxx,采用Device Tree后,许多硬件的细节可以直接透过它传递给Linux,而不再需要在上述代码中进行大量的冗余编码。
具体Device Tree介绍等到这里查看:

凡是走platform架构的所有device都可以用于此模型:如:

CPU的数量和类别

内存基地址和大小

总线和桥

外设连接

中断控制器和中断使用情况

GPIO控制器和GPIO使用情况

Clock控制器和Clock使用情况

Ethernet控制器等等

都是可以被集成到dts中的!

一丶概述:

Platform_driver 驱动模型是内核中比较常用的一种模型!因为这是一种虚拟总线,其好处就是不管是字符设备块设备都可以通过此总线来实现设备集中!驱动模型的铁三角那就是:总线,设备,驱动!

 那么首先回顾一下2.6中的platform架构驱动的写法:

 常规的写法都是通过platform_deiver 和 platform_device 来进行一个类型月老牵线式的匹配!platform_driver填充

{

.probe = ,

.remove = ,

.driver = {

.name = “”,

.owner = “”,

},

}

Plarform_device 则在BSP(math-xxx)中填充:

Struct platform_device{

const char *name;

u32 id;

u32 num_resource;

sruct resource *resource;

}

然后进行匹配!主要看name字段是否相同!

int platform_match(struct device* dev,struct device_driver *drv)

{

struct platform_device *pdev;

pdev = container_of(dev,struct platform_device,dev);

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

}

到这里就已经ok了!我们看到上述是通过一个strcncmp()进行比较的!

那么我们的3.x又是如何写的呢?
二丶开始工作?

dts 中的节点属性含义 --出现频率最多的就是compible这个属性 

、那么如何匹配呢?-- 月老肯定还在,但是换了一个月老(21世纪了)

三丶添加一个自己的platform设备

static struct of_device_id nlm_common_ide_dt_ids[] = { 

        {.compatible = "netlogic,xlp-ide-commpact"},

};

static struct platform_driver nlm_common_ide_driver = { 

        .driver = { 

                .name = "xlp-ide-commpact",

                .owner = THIS_MODULE,

                .of_match_table = nlm_common_ide_dt_ids,

        },  

        .probe          = nlm_drv_ide_probe,

        .remove         = nlm_common_ide_remove,

};

上述就是新世纪(3.x)中的写法啦!

四、如何执行?

/*

 * XLP3XX Device Tree Source for SVP boards

 */

/ {

        model = "netlogic,XLP-SVP";

        compatible = "netlogic,xlp";

        #address-cells = <2>;

        #size-cells = <2>;

        soc {

                #address-cells = <2>;

                #size-cells = <1>;

                compatible = "simple-bus";

                ranges = <0 0  0 0x18000000  0x04000000   

                          1 0  0 0x16000000  0x02000000>; 

                serial0: serial@30000 {

                      .....................

                };

                commpact: xlp_commpact@35000 {

                        compatible = "netlogic,xlp-ide-commpact";

                        reg = <0 0x35100 0x1000>;

 

                        #interrupt-cells = <1>;

                        interrupts = <39>;

                        interrupt-controller;

                };

        };

        chosen {

                bootargs = "console=ttyS0,9600 rdinit=/sbin/init";

        };

};

看到compatible了吗?

这就是他们匹配的变量!和以前一样也是判断字符串是否相等!

那么在那匹配?

在扳级硬件编码中有如下的代码

146 void __init device_tree_init(void)

147 {

148         unsigned long dt_size;

149         void    *blob;

150 

151         if (!initial_boot_params)

152                 panic("No device tree!\n");

153 

154         /*

155          * boot mem available now, make a copy of the blob, and

156          * update initial_boot_params to point there.

157          */

158         dt_size = be32_to_cpu(initial_boot_params->totalsize);

159         blob = early_init_dt_alloc_memory_arch(dt_size, 8);

160         if (blob == NULL)

161                 panic("Could not allocate initial_boot_params\n");

162         memcpy(blob, initial_boot_params, dt_size);

163         nlm_fdt_blob = initial_boot_params = blob;

164         pr_info("fdt copied to %p, size %ld\n", blob, dt_size);

165 

166         unflatten_device_tree();

167 }

168 

169 static struct of_device_id __initdata xlp_ids[] = {

170         { .compatible = "simple-bus", },

171         {},

172 };

173 

174 int __init xlp8xx_ds_publish_devices(void)

175 {

176         if (!of_have_populated_dt())

177                 return 0;

178         return of_platform_bus_probe(NULL, xlp_ids, NULL);

179 }

180 

181 device_initcall(xlp8xx_ds_publish_devices);

 

一眼就看出了是初始化device tree的代码!

看代码流程走向...

从下往上看:

device_initcall(xlp8xx_ds_publish_devices);

注册的是xlp8xx_ds_publish_devices这个函数

跳到此函数!到174

看到执行了两个函数

一个of_have_poplated_dr()

一个of_platform_bus_probe()

第一个函数为检查dts节点是否为空的!

如果为空则返回0

第二个函数为

396 /**

397  * of_platform_bus_probe() - Probe the device-tree for platform buses

398  * @root: parent of the first level to probe or NULL for the root of the tree

399  * @matches: match table for bus nodes

400  * @parent: parent to hook devices from, NULL for toplevel

401  *

402  * Note that children of the provided root are not instantiated as devices

403  * unless the specified root itself matches the bus list and is not NULL.

404  */

可以理解为探测xlp_ids是否存在!并且是否匹配!如果匹配,创建子节点!其实就是展开子节点!

xlp_ids 我们又看到了compible这个属性!

这里填充了simple-bus..

何为simple-bus

这种虚拟总线可以兼容很多总线设备!

到这里基本上所有的疑惑已经解开了!

五、总结

3.x版本其实改变了很多原来的东西!可以看出来Linus一怒是非常的牛逼的!而且是带着腥风谢雨的!

Echo “keven”;

附注:Linux OF API

 在drivers/of/platform.c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值