欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > DOC文档下载  

    Linux 设备文件的创建和mdev.doc

    • 资源ID:3255220       资源大小:39.50KB        全文页数:9页
    • 资源格式: DOC        下载积分:4
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要4
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Linux 设备文件的创建和mdev.doc

    Linux 设备文件的创建和mdev一、设备类相关知识设备类是虚拟的,并没有直接相应的物理实物。仅仅是为了更好地管理同一类设备导出到用户空间而产生的文件夹和文件。整个过程涉及到sysfs文件系统,该文件系统是为了展示linux设备驱动模型而构建的文件系统,是基于ramfs,linux根文件夹中的/sysfs即挂载了sysfs文件系统。Struct kobject数据结构是sysfs的基础。kobject在sysfs中代表一个文件夹,而linux的驱动(struct driver)、设备(struct device)、设备类(struct class)均是从kobject进行派生的,因此他们在sysfs中都相应于一个文件夹。而数据结构中附属的struct device_attribute、driver_attribute、class_attribute等属性数据结构在sysfs中则代表一个普通的文件。Struct kset是struct kobject的容器。即Struct kset能够成为同一类struct kobject的父亲,而其自身也有kobject成员。因此其又可能和其它kobject成为上一级kset的子成员。本文无意对sysfs和linux设备驱动模型进行展开,以后再另写文章进行分析。二、两种创建设备文件的方式在设备驱动中cdev_add将struct file_operations和设备号注冊到系统后,为了可以自己主动产生驱动相应的设备文件。须要调用class_create和device_create,并通过uevent机制调用mdev(嵌入式linux由busybox提供)来调用mknod创建设备文件。当然也可以不调用这两个接口。那就手工通过命令行mknod来创建设备文件。三、设备类和设备相关数据结构1include/linux/kobject.hstruct kobject const char *name;/名称struct list_head entry;/kobject链表struct kobject *parent;/即所属kset的kobjectstruct kset *kset;/所属ksetstruct kobj_type *ktype;/属性操作接口;struct kset struct list_head list;/管理同属于kset的kobjectstruct kobject kobj;/能够成为上一级父kset的子文件夹const struct kset_uevent_ops *uevent_ops;/uevent处理接口;如果Kobject A代表一个文件夹,kset B代表几个文件夹(包含A)的共同的父文件夹。则A.kset=B; A.parent=B.kobj.2include/linux/device.hstruct class /设备类const char *name; /设备类名称struct module *owner;/创建设备类的modulestruct class_attribute *class_attrs;/设备类属性struct device_attribute *dev_attrs;/设备属性struct kobject *dev_kobj;/kobject再sysfs中代表一个文件夹.struct class_private *p;/设备类得以注冊到系统的连接件;3drivers/base/base.hstruct class_private /该设备类相同是一个kset,包括以下的class_devices。同一时候在class_subsys填充父ksetstruct kset class_subsys;struct klist class_devices;/设备类包括的设备(kobject)struct class *class;/指向设备类数据结构,即要创建的本级文件夹信息;4include/linux/device.hstruct device /设备struct device *parent;/sysfs/devices/中的父设备struct device_private *p;/设备得以注冊到系统的连接件struct kobject kobj;/设备文件夹const char *init_name;/设备名称struct bus_type *bus;/设备所属总线struct device_driver *driver; /设备使用的驱动struct klist_node knode_class;/连接到设备类的kliststruct class *class;/所属设备类const struct attribute_group *groups;5drivers/base/base.hstruct device_private struct klist klist_children;/连接子设备struct klist_node knode_parent;/增加到父设备链表struct klist_node knode_driver;/增加到驱动的设备链表struct klist_node knode_bus;/增加到总线的链表struct device *device;/相应设备结构;6解释class_private是class的私有结构。class通过class_private注冊到系统中。device_private是device的私有结构,device通过device_private注冊到系统中。注冊到系统中也是将对应的数据结构增加到系统已经存在的链表中,可是这些链接的细节并不希望暴露给用户,也没有必要暴露出来,所以才有private的结构。而class和device则通过sysfs向用户层提供信息。四、创建设备类文件夹文件1.在驱动通过cdev_add将struct file_operaTIons接口集和设备注冊到系统后。即利用class_create接口来创建设备类文件夹文件。led_class = class_create(THIS_MODULE, "led_class");_class_create(owner, name, cls->name = name;/设备类名cls->owner = owner;/所属moduleretval = _class_register(cls, key);struct class_private *cp;/将类的名字led_class赋值给相应的ksetkobject_set_name(/填充class_subsys所属的父kset:ket:sysfs/class.cp->class_subsys.kobj.kset = class_kset;/填充class属性操作接口cp->class_subsys.kobj.ktype = cp->class = cls;/通过cp能够找到classcls->p = cp;/通过class能够找到cp/创建led_class设备类文件夹kset_register(/在led_class文件夹创建class属性文件add_class_attrs(class_get(cls)。2.继续展开kset_registerkset_register(kobject_add_internal(/ parent即class_kset.kobj,即/sysfs/class相应的文件夹parent = kobject_get(kobj->parent);create_dir(kobj);/创建一个led _class设备类文件夹sysfs_create_dir(kobj);/该接口是sysfs文件系统接口,代表创建一个文件夹,不再展开。3.上述提到的class_kset在class_init被创建class_kset = kset_create_and_add("class", NULL, NULL);第三个传參为NULL。代表默认在/sysfs/创建class文件夹。五、创建设备文件夹和设备属性文件1.利用class_create接口来创建设备类文件夹文件后,再利用device_create接口来创建详细设备文件夹和设备属性文件。led_device = device_create(led_class, NULL, led_devno, NULL, "led");device_create_vargsdev->devt = devt;/设备号dev->class = class;/设备类led_classdev->parent = parent;/父设备。这里是NULLkobject_set_name_vargs(">device_register(dev) 注冊设备2.继续展开device_register(dev)device_iniTIalize(dev);dev->kobj.kset = devices_kset;/设备所属/sysfs/devices/device_add(dev)device_private_init(dev)/初始化device_privatedev_set_name(dev, "%s", dev->init_name);/赋值dev->kobject的名称setup_parent(dev, parent);/建立device和父设备的kobject的联系/kobject_add在/sysfs/devices/文件夹下创建设备文件夹led,kobject_add是和kset_register相似的接口。仅仅只是前者针对kobject。后者针对kset。kobject_add(kobject_add_vargkobj->parent = parent;kobject_add_internal(kobj)create_dir(kobj);/创建设备文件夹/在刚创建的/sysfs/devices/led文件夹下创建uevent属性文件,名称是”uevent”device_create_file(dev, /在刚创建的/sysfs/devices/led文件夹下创建dev属性文件,名称是”dev”。该属性文件的内容就是设备号device_create_file(dev, /在/sysfs/class/led_class/文件夹下建立led设备的符号连接,所以打开/sysfs/class/led_class/led/文件夹也能看到dev属性文件,读出设备号。device_add_class_symlinks(dev);/创建device属性文件,包含设备所属总线的属性和attribute_group属性device_add_attrs()bus_add_device(dev) /将设备增加总线/触发uevent机制,并通过调用mdev来创建设备文件。kobject_uevent(/匹配设备和总线的驱动,匹配成功就调用驱动的probe接口,不再展开bus_probe_device(dev);3.展开kobject_uevent(kobject_uevent_env(kobj, acTIon, NULL);kset = top_kobj->kset;uevent_ops = kset->uevent_ops; /即device_uevent_ops/ subsystem即设备所属的设备类的名称”led_class”subsystem = uevent_ops->name(kset, kobj);/devpath即/sysfs/devices/led/devpath = kobject_get_path(kobj, GFP_KERNEL);/加入各种环境变量add_uevent_var(env, "ACTION=%s", action_string);add_uevent_var(env, "DEVPATH=%s", devpath);add_uevent_var(env, "SUBSYSTEM=%s", subsystem);uevent_ops->uevent(kset, kobj, env);add_uevent_var(env, "MAJOR=%u", MAJOR(dev->devt);add_uevent_var(env, "MINOR=%u", MINOR(dev->devt);add_uevent_var(env, "DEVNAME=%s", name);add_uevent_var(env, "DEVTYPE=%s", dev->type->name);/还会添加总线相关的一些属性环境变量等等。#if defined(CONFIG_NET)/假设是PC的linux会通过socket的方式向应用层发送uevent事件消息,但在嵌入式linux中不启用该机制。#endifargv 0 = uevent_helper;/即/sbin/mdevargv 1 = (char *)subsystem;/”led_class”argv 2 = NULL;add_uevent_var(env, "HOME=/");add_uevent_var(env,"PATH=/sbin:/bin:/usr/sbin:/usr/bin");call_usermodehelper(argv0, argv,env->envp, UMH_WAIT_EXEC);4.上述提到的devices_kset在devices_init被创建devices_kset = kset_create_and_add("devices", /第三个传參为NULL,代表默认在/sysfs/创建devices文件夹5.上述设备属性文件static struct device_attribute devt_attr =_ATTR(dev, S_IRUGO, show_dev, NULL);static ssize_t show_dev(struct device *dev, struct device_attribute *attr,char *buf)return print_dev_t(buf, dev->devt);/即返回设备的设备号6.devices设备文件夹响应uevent事件的操作static const struct kset_uevent_ops device_uevent_ops = .filter =dev_uevent_filter,.name = dev_uevent_name,.uevent = dev_uevent,;7.call_usermodehelper是从内核空间调用用户空间程序的接口。8.对于嵌入式系统来说,busybox採用的是mdev,在系统启动脚本rcS中会使用命令echo /sbin/mdev > /proc/sys/kernel/hotpluguevent_helper数组即读入/proc/sys/kernel/hotplug文件的内容,即 “/sbin/mdev” .六、创建设备文件轮到mdev出场了,以上描写叙述都是在sysfs文件系统中创建文件夹或者文件,而应用程序訪问的设备文件则须要创建在/dev/文件夹下。该项工作由mdev完毕。Mdev的原理是解释/etc/mdev.conf文件定义的命名设备文件的规则。并在该规则下依据环境变量的要求来创建设备文件。Mdev.conf由用户层指定,因此更具灵活性。本文无意展开对mdev配置脚本的分析。Busybox/util-linux/mdev.cint mdev_main(int argc UNUSED_PARAM, char *argv)xchdir("/dev");if (argv1 ">elseaction = getenv("ACTION");env_path = getenv("DEVPATH");G.subsystem = getenv("SUBSYSTEM");snprintf(temp, PATH_MAX, "/sys%s", env_path);/到/sysfs/devices/led文件夹make_device(temp, /*delete:*/ 0);strcpy(dev_maj_min, "/dev"); /读出dev属性文件。得到设备号open_read_close(path, dev_maj_min + 1, 64);.mknod(node_name, rule->mode | type, makedev(major, minor)终于我们会跟踪到mknod在/dev/文件夹下创建了设备文件。 

    注意事项

    本文(Linux 设备文件的创建和mdev.doc)为本站会员(白大夫)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开