[A Tutorial on the Device Tree (Zynq) -- Part III](A Tutorial on the Device Tree (Zynq) -- Part III)

定义外设

可能你读本文是为了给你的设备写一个Linux驱动,在这方面要推荐著名的《Linux Device Driver》。但是在写一个设备驱动之前,允许我分享写Linux驱动的第一诫:永远不要为Linux写设备驱动

更好的办法是找一个维护状态良好的类似功能的设备驱动,然后修改它。这不仅仅意味着更容易,更可能帮我们避免我们一些未意识到的问题。从其他驱动移植过来可以让这份驱动更容易被理解,可移植,更可能被内核树接受。

所以现在的重点变为理解其他驱动,然后做一点调整。有疑问的地方就照着别人的做法做。创新和个人风格在这里没什么用。

现在,回到设备树。让我们来看看第二部分省略的内容:

  ps7_axi_interconnect_0: axi@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "xlnx,ps7-axi-interconnect-1.00.a", "simple-bus";
ranges ;
gic: interrupt-controller@f8f01000 {
#interrupt-cells = < 3 >;
compatible = "arm,cortex-a9-gic";
interrupt-controller ;
reg = < 0xf8f01000 0x1000 >,< 0xf8f00100 0x100 >;
} ;
pl310: pl310-controller@f8f02000 {
arm,data-latency = < 3 2 2 >;
arm,tag-latency = < 2 2 2 >;
cache-level = < 2 >;
cache-unified ;
compatible = "arm,pl310-cache";
interrupts = < 0 34 4 >;
reg = < 0xf8f02000 0x1000 >;
} ; [ ... more items ... ] xillybus_0: xillybus@50000000 {
compatible = "xlnx,xillybus-1.00.a";
reg = < 0x50000000 0x1000 >;
interrupts = < 0 59 1 >;
interrupt-parent = <&gic>;
xlnx,max-burst-len = <0x10>;
xlnx,native-data-width = <0x20>;
xlnx,slv-awidth = <0x20>;
xlnx,slv-dwidth = <0x20>;
xlnx,use-wstrb = <0x1>;
} ;
} ;

这里只列出原始DTS文件中的两个设备。

第一个条目:Zynq处理器的中断控制器。这个条目确保中断控制器被加载。注意它的标签是“gic"。这个标签被每个使用中断的设备引用。

终于可以讲述最有趣的部分了:以上说的这些如何与内核代码配合工作。

关于内核驱动

设备驱动加载和卸载时有四件事情会发生:

  • 硬件存在时(比如在设备树中声明),内核代码加载相应驱动
  • 驱动需要了解设备的物理地址
  • 驱动需要了解设备触发的中断号,用来注册中断处理函数。
  • 一些特殊信息需要被获取

内核中有直接访问设备树的API,但是设备驱动使用专用接口更方便,这些专用接口受PCI/PCIe驱动的API影响。来看下xillybus_0条目,这是一个挂载于AXI总线上的典型逻辑设备。

标签和节点名

首先,标签("xillybus")和条目名("xillybus@50000000")。标签可以省略,条目节点名的格式为(some-name@address),最后在/sys下产生一个标准的条目(/sys/devices/axi.0/50000000.xillybus/)。这个设备树的数据位于/proc/device-tree/axi@0/xillybus@50000000/,不过内核肯定不是从这里访问设备树的。

驱动自动加载

节点中的第一个赋值语句compatible = “xlnx,xillybus-1.00.a”是最重要的一句:它连接硬件和驱动。当内核在总线上扫描设备时(设备节点在设备树里挂在一个总线节点下),内核检索"compatible"字段,然后将其字符串与一些已知的字符串比较。这个过程会在启动时自动发生两次:

  • 内核启动时,编译进内核的驱动与设备树中某个"compatible"条目匹配
  • 之后加载内核模块时,再触发一次匹配操作

内核驱动和"compatible"条目的连接由驱动代码中的一小段完成:

static struct of_device_id xillybus_of_match[] __devinitdata = {
{ .compatible = "xlnx,xillybus-1.00.a", },
{}
}; MODULE_DEVICE_TABLE(of, xillybus_of_match);

这段代码使得驱动与某一个"compatible"条目匹配。注意上面的id表中有一个空结构,用这个空意绪标志id表的结束。

在上段代码之后,一定有类似如下的一段代码:

static struct platform_driver xillybus_platform_driver = {
.probe = xilly_drv_probe,
.remove = xilly_drv_remove,
.driver = {
.name = "xillybus",
.owner = THIS_MODULE,
.of_match_table = xillybus_of_match,
},
};

platform_driver_register(&xillybus_platform_driver)在模块初始化里被调用。这个结构告诉内核,当驱动与某个硬件匹配时,xilly_drv_probe 被调用。

对内核来说,"compatible"字串需要与某个驱动名相同。”xlnx"前缀用于防止名字冲突。

另外,一个设备可以有多个"compatible"。因为一个设备可以有多个模块对应多个驱动。

可能会需要匹配硬件的名字和类型,但这不常用。

写内核模块时需要特别注意,自动加载机制依赖于/lib/modules/{kernel version}/modules.ofmap文件中的"compatible"字串,其他定义文件也在这个目录下。正确的方式是把*.ko文件复制到/lib/modules/{kernel version}/kernel/drivers/下的相关目录中,然后:

depmod -a

翻译:A Tutorial on the Device Tree (Zynq) -- Part III的更多相关文章

  1. 翻译:A Tutorial on the Device Tree (Zynq) -- Part V

    A Tutorial on the Device Tree (Zynq) -- Part V Application-specific data 之前提过,设备树中是一些特殊信息,这样一个驱动可以管理 ...

  2. 翻译:A Tutorial on the Device Tree (Zynq) -- Part II

    A Tutorial on the Device Tree (Zynq) -- Part II 设备树结构 Zynq的设备树如下: /dts-v1/; / { #address-cells = < ...

  3. 翻译:A Tutorial on the Device Tree (Zynq) -- Part I

    A Tutorial on the Device Tree (Zynq) -- Part I 此教程的目的 本教程是针对Xilinx' Zynq-7000 EPP设备(一个集成了FPGA的ARM Co ...

  4. 翻译:A Tutorial on the Device Tree (Zynq) -- Part IV

    获取资源信息 内核模块驱动加载之后,就开始把硬件资源管理起来,如读写寄存器.接收中断. 来看看设备树里的一条: xillybus_0: xillybus@50000000 { compatible = ...

  5. Device Tree Usage 【转】

    转自:http://blog.chinaunix.net/uid-20522771-id-3457184.html 原文链接:http://devicetree.org/Device_Tree_Usa ...

  6. Device Tree(二):基本概念

    转自:http://www.wowotech.net/linux_kenrel/dt_basic_concept.html 一.前言 一些背景知识(例如:为何要引入Device Tree,这个机制是用 ...

  7. Device Tree Usage( DTS文件语法)

    http://elinux.org/Device_Tree_Usage Device Tree Usage     Top Device Tree page This page walks throu ...

  8. 【转】Device Tree(二):基本概念

    原文网址:http://www.wowotech.net/linux_kenrel/dt_basic_concept.html 一.前言 一些背景知识(例如:为何要引入Device Tree,这个机制 ...

  9. Device Tree Usage(理解DTS文件语法)

    Basic Data Format The device tree is a simple tree structure of nodes and properties. Properties are ...

随机推荐

  1. Linux下文件打包与解包

    打包(.tar):  tar -cvf Pro.tar /home/lin/Pro   #将/home/lin/Pro文件夹下的所有文件打包成Pro.tar 打解包(.tar.gz)  tar -cv ...

  2. 2017-2018 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)

    先把代码扔上来 E. Field of Wonders time limit per test 3 seconds memory limit per test 256 megabytes input ...

  3. 牛客网Wannafly模拟赛

    A矩阵 时间限制:1秒 空间限制:131072K 题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行 ...

  4. MySQL 待解决死锁

    官方文档:https://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html 线上出现一个死锁现象,信息显示的是两条对同一个表的不同记录的upd ...

  5. hihoCoder 1367 等式填空

    明确题意 等号左边是由'+'和'?'组成的算式,其中处于某个整数(即便这个整数只有一位)首位的'?'可以填入1-9中的某个数字,其余'?'可以填入0-9中的某个数字. SOURCE 这里未明确等号左边 ...

  6. [Vijos1308]埃及分数(迭代加深搜索 + 剪枝)

    传送门 迭代加深搜索是必须的,先枚举加数个数 然后搜索分母 这里有一个强大的剪枝,就是确定分母的范围 #include <cstdio> #include <cstring> ...

  7. dockerfile各种命令解析

    1.ADD命令,如果ADD的是压缩包,ADD之后会自动进行解压.....

  8. javaScriptCore 实战与小结

      源码在这,看不懂的直接撸源码就行,转载声明出处 原生调用JS的大致流程,做了个思维简图 这是代码流程 // JS数据 func getJSVar() { let context: JSContex ...

  9. 51nod1053 最大M子段和 V2

    $n \leq 50000$的序列,问选不超过$m \leq 50000$个区间使得和最大. 如果正数区间总数比$m$小那肯定全选.否则有两种方式减少区间数量:丢掉一个正区间:补一个负区间连接两个正区 ...

  10. Yii 安装学习

    (1)打开yii官方网站: http://www.yiichina.com (2)点击下载,跳转到下载页面: (3)找到从归档文件安装,新手学习,使用[ Yii2的基本应用程序模板]: (4)下载解压 ...