如同大部分驱动核心结构的情形, device_driver 结构常常被发现嵌到一个更高级的, 总 线特定的结构. lddbus 子系统不会和这样的趋势相反, 因此它已定义了它自己的 ldd_driver 结构:

struct ldd_driver { char *version;

struct module *module; struct device_driver driver;

struct driver_attribute version_attr;

};

#define to_ldd_driver(drv) container_of(drv, struct ldd_driver, driver);

这里, 我们要求每个驱动提供特定当前软件版本, 并且 lddbus 输出这个版本字串为它知 道的每个驱动. 总线特定的驱动注册函数是:

int register_ldd_driver(struct ldd_driver *driver)

{

int ret;

driver->driver.bus = &ldd_bus_type;

ret = driver_register(&driver->driver); if (ret)

return ret;

driver->version_attr.attr.name = "version"; driver->version_attr.attr.owner = driver->module; driver->version_attr.attr.mode = S_IRUGO;

driver->version_attr.show = show_version; driver->version_attr.store = NULL;

return driver_create_file(&driver->driver, &driver->version_attr);

}

这个函数的第一部分只注册低级的 device_driver 结构到核心; 剩下的建立版本属性. 因为这个属性在运行时被创建, 我们不能使用 DRIVER_ATTR 宏; 反之,

driver_attribute 结构必须手工填充.
注意我们设定属性的拥有者为驱动模块, 不是 lddbus 模块; 这样做的理由是可以在为这个属性的 show 函数的实现中见到:

static
ssize_t show_version(struct device_driver *driver, char *buf)

{

struct
ldd_driver *ldriver = to_ldd_driver(driver); sprintf(buf, "%s\n",
ldriver->version);

return strlen(buf);

}

有人可能认为属性拥有者应当是 lddbus 模块, 因为实现这个属性的函数在那里定义. 这 个函数, 但是, 是使用驱动自身所创建的
ldd_driver 结构. 如果那个结构在一个用户空 间进程试图读取版本号时要消失, 事情会变得麻烦. 指定驱动模块作为属性的拥有者阻止 了模块被卸载, 在用户空间保持属性文件打开时. 因为每个驱动模块创建一个对 lddbus 模块的引用, 我们能确信
lddbus 不会在一个不合适的时间被卸载.

为完整起见, sculld 创建它的
ldd_driver 结构如下:

static struct ldd_driver sculld_driver = { .version =
"$Revision: 1.1

$", .module = THIS_MODULE, .driver = { .name =
"sculld", }, };

一个简单的对 register_ldd_driver 的调用添加它到系统中. 一旦完成初始化, 驱动信 息可在
sysfs 中见到:

$
tree /sys/bus/ldd/drivers

/sys/bus/ldd/drivers

`--
sculld

|--
sculld0 -> ../../../../devices/ldd0/sculld0

|--
sculld1 -> ../../../../devices/ldd0/sculld1

|--
sculld2 -> ../../../../devices/ldd0/sculld2

|-- sculld3 -> ../../../../devices/ldd0/sculld3

[46] 这个总线的逻辑名子, 当然, 应当是"sbus", 但是这个名子已经被一个真实的, 物理总 线采用.

Linux 内核驱动结构嵌入的更多相关文章

  1. Linux 内核 设备结构嵌入

    设备结构包含设备模型核心需要的来模型化系统的信息. 大部分子系统, 但是, 跟踪关于 它们驻留的设备的额外信息. 结果, 对设备很少由空设备结构所代表; 相反, 这个结构, 如同 kobject 结构 ...

  2. linux内核驱动模型

    linux内核驱动模型,以2.6.32内核为例.(一边写一边看的,有点乱.) 1.以内核对象为基础.用kobject表示,相当于其它对象的基类,是构建linux驱动模型的关键.具有相同类型的内核对象构 ...

  3. linux 内核驱动--Platform Device和Platform_driver注册过程

    linux 内核驱动--Platform Device和Platform_driver注册过程 从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Pla ...

  4. 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化

    2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...

  5. Linux内核驱动学习(八)GPIO驱动模拟输出PWM

    文章目录 前言 原理图 IO模拟输出PWM 设备树 驱动端 调试信息 实验结果 附录 前言 上一篇的学习中介绍了如何在用户空间直接操作GPIO,并写了一个脚本可以产生PWM.本篇的学习会将写一个驱动操 ...

  6. Unix/Linux环境C编程新手教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaXRjYXN0Y3Bw/font/5a6L5L2T/font ...

  7. Unix/Linux环境C编程入门教程(12) openSUSECCPP以及Linux内核驱动开发环境搭建

    1. openSUSE是一款优秀的linux. 2.选择默认虚拟机 3.选择稍后安装操作系统 4.选择linux  opensuse 5. 选择默认虚拟机名称 6.设置处理器为双核. 7.内存设置为2 ...

  8. 【引用】Linux 内核驱动--多点触摸接口

    本文转载自James<Linux 内核驱动--多点触摸接口>   译自:linux-2.6.31.14\Documentation\input\multi-touch-protocol.t ...

  9. Linux内核驱动开发之KGDB原理介绍及kgdboe方式配置

    接博文<Linux内核驱动开发之KGDB单步调试内核(kgdboc方式)>.上篇博文中,仅简单介绍使用串口的Kgbd的流程(kgdboc方式),本文将重点介绍KGDB调试Linux内核的原 ...

随机推荐

  1. PLAY2.6-SCALA(十) 模板引擎Twirl

    一.语法 1.@ 它是一个特殊的字符,表示动态声明的开始.对于简单的动态声明结尾可以从代码块中自动推断结尾,对于复杂的表达式通常加上() Hello @(customer.firstName + cu ...

  2. 安装软件时候出现"无效驱动器D"

    安装软件的时候,出现以下问题. 如图:  无效驱动器 原因是因为之前安装过这样的软件在H盘,后期更改没了H,所以出现了错误. 解决方案: 打开注册表,搜索软件的关键字如  vmware 删除错误路径即 ...

  3. Codeforces 276D

    题目链接 这题真的体现了自己思维的不足,考虑问题只是考虑他的特殊性,却不能总结出它的一般性规律. 对于这题, 如果L == R , 那么结果为0. 否则, 我们只需要找到最高的某一位 (二进制数中的某 ...

  4. 利用IDEA构建springboot应用

    前提注意: 1.版本,java 1.8    maven  3.3.9 配置项目 项目版本 项目保存路径 在maven里面的conf里面的settings.xml里配置maven中央仓库  (阿里云) ...

  5. 《spring boot》8.2章学习时无法正常启动,报“ORA-00942: 表或视图不存在 ”

    在学习<spring boot>一书的过程中,由于原书作者难免有一些遗漏的的地方,或者系统.软件版本不一致.框架更新等各种因素,完全安装书中源码页不能实现项目的正常启动 在8.2章节,演示 ...

  6. Spring集成Hessian1

    Hessian是一个轻量级的远程调用工具,采用的是Binary RPC协议,很适合于发送二进制数据,基于HTTP具有防火墙穿透能力.Hessian一般是通过Web应用来提供服务,因此非常类似于平时我们 ...

  7. 阿里靠什么支撑 EB 级计算力?

    作者 关涛 阿里云智能事业群 研究员 导读:MaxCompute 是阿里EB级计算平台,经过十年磨砺,它成为阿里巴巴集团数据中台的计算核心和阿里云大数据的基础服务.去年MaxCompute 做了哪些工 ...

  8. HTTP Cookie header 中set-cookie格式

    Cookie相关的Http头     有 两个Http头部和Cookie有关:Set-Cookie和Cookie.     Set-Cookie由服务器发送,它包含在响应请求的头部中.它用于在客户端创 ...

  9. jQuery 练习 dom

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. linux下修改gcc编译器版本

    可以使用如下命令行来让 gcc 选择不同的 C++ 版本: g++ -std=c++11 main.cpp 在你的系统中,由于编译器或是编译器设定上的差别,操作也许有所不同.