《Linux设备节点创建》用户空间ueventd创建设备节点规则

2023-10-31

转自:http://blog.csdn.net/tankai19880619/article/details/11726371


说明:本文基于Android2.3和Linux2.6,其余版本仅供参考。

一、devfs、udev和sysfs是什么关系?

linux2.6之前使用devfs设备文件系统,它存在与内核空间;

linux2.6之后使用udev设备文件系统,它存在与用户空间、但严重依赖与sysfs文件系统。

二、Android(使用linux2.6以后的设备节点创建策略)设备节点的创建

  在Android中,没有独立的类似于udev或者mdev的用户程序,这个功能集成到了init中做了。代码见:system/core/init/init.c文件,如下:

[cpp]  view plain copy
  1. if (ufds[0].revents == POLLIN)  
  2.   handle_device_fd(device_fd);  

其中handle_device_fd(device_fd)函数在system/core/init/devices.c中实现,参数device_fd 由函数device_init()->open_uevent_socket()->socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)函数调用返回。

函数handle_device_fd(device_fd)中,根据传进来的device_fd参数,调用recv(fd, msg, UEVENT_MSG_LEN, 0)函数,将内核探测到的设备并通过NETLINK机制传过来的socket描述符转化成消息。接着调用parse_event(msg, &uevent);函数将消息翻译成uevent事件,并将改事件传递给handle_device_event(&uevent)函数。

handle_device_event(&uevent)函数中,依据参数uevent->subsystem类型创建dev下的相应目录,如:/dev/graphics。紧接着根据uevent->action是"add"还是"remove"来实现设备节点的创建与删除。如果uevent->action是"add",则调用make_device(devpath, block, uevent->major, uevent->minor)函数生成设备节点。如果uevent->action是"remove",则调用unlink(devpath)对设备节点进行删除。

三、下边看看Android的ueventd进程

说明:其配置文件uevent.rc不起实际作用,只是对创建的设备节点文件属性做设置。

1.system/core/init/ueventd.c

[cpp]  view plain copy
  1. int ueventd_main(int argc, char **argv){  
  2.   device_init();  
  3.   /* 
  4.   system/core/init/device.c 
  5.   void device_init(void){ 
  6.     device_fd = uevent_open_socket(64*1024, true); 
  7.     coldboot("/sys/class"); 
  8.     coldboot("/sys/block"); 
  9.     coldboot("/sys/devices"); 
  10.   } 
  11.   */  
  12.   ufd.events = POLLIN;  
  13.   ufd.fd = get_device_fd();  
  14.   while(1) {  
  15.     ufd.revents = 0;  
  16.     nr = poll(&ufd, 1, -1);  
  17.     if (nr <= 0)  
  18.       continue;  
  19.     if (ufd.revents == POLLIN)  
  20.       handle_device_fd();  
  21.   }       
  22. }  

2.system/core/init/device.c

注意:只有主次设备号的事件才会创建设备节点

[cpp]  view plain copy
  1. void handle_device_fd(){  
  2.   while ((n = uevent_kernel_multicast_recv(device_fd, msg, UEVENT_MSG_LEN)) > 0) {  
  3.     handle_device_event(&uevent);  
  4.   }  
  5. }  
  6. static void handle_device_event(struct uevent *uevent){  
  7.   if (!strcmp(uevent->action,"add"))  
  8.     fixup_sys_perms(uevent->path);  
  9.   
  10.   /* if it's not a /dev device, nothing else to do */  
  11.   if((uevent->major < 0) || (uevent->minor < 0)){//只有主次设备号的事件才会创建设备节点  
  12.     //ERROR("TK------------>>>>device.c>>>>>>handle_device_event>>>>>>uevent->major and minor < 0\n");//add by tankai  
  13.     return;  
  14.   }  
  15.   if(!strncmp(uevent->subsystem, "block", 5)) {  
  16.     block = 1;  
  17.     base = "/dev/block/";  
  18.     mkdir(base, 0755);  
  19.     if (!strncmp(uevent->path, "/devices/platform/", 18))  
  20.       links = parse_platform_block_device(uevent);  
  21.   } else {  
  22.     block = 0;  
  23.     /* this should probably be configurable somehow */  
  24.     if (!strncmp(uevent->subsystem, "usb", 3)) {  
  25.       if (!strcmp(uevent->subsystem, "usb")) {  
  26.         /* This imitates the file system that would be created 
  27.         * if we were using devfs instead. 
  28.         * Minors are broken up into groups of 128, starting at "001" 
  29.         */  
  30.         int bus_id = uevent->minor / 128 + 1;  
  31.         int device_id = uevent->minor % 128 + 1;  
  32.         /* build directories */  
  33.         mkdir("/dev/bus", 0755);  
  34.         mkdir("/dev/bus/usb", 0755);  
  35.         snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id);  
  36.         mkdir(devpath, 0755);  
  37.         snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id);  
  38.         devpath_ready = 1;  
  39.       } else {  
  40.         /* ignore other USB events */  
  41.         return;  
  42.       }  
  43.     } else if (!strncmp(uevent->subsystem, "graphics", 8)) {  
  44.       base = "/dev/graphics/";  
  45.       mkdir(base, 0755);  
  46.     } else if (!strncmp(uevent->subsystem, "oncrpc", 6)) {  
  47.       base = "/dev/oncrpc/";  
  48.       mkdir(base, 0755);  
  49.     } else if (!strncmp(uevent->subsystem, "adsp", 4)) {  
  50.       base = "/dev/adsp/";  
  51.       mkdir(base, 0755);  
  52.     } else if (!strncmp(uevent->subsystem, "msm_camera", 10)) {  
  53.       base = "/dev/msm_camera/";  
  54.       mkdir(base, 0755);  
  55.     } else if(!strncmp(uevent->subsystem, "input", 5)) {  
  56.       base = "/dev/input/";  
  57.       mkdir(base, 0755);  
  58.     } else if(!strncmp(uevent->subsystem, "mtd", 3)) {  
  59.       base = "/dev/mtd/";  
  60.       mkdir(base, 0755);  
  61.     } else if(!strncmp(uevent->subsystem, "sound", 5)) {  
  62.       base = "/dev/snd/";  
  63.       mkdir(base, 0755);  
  64.     } else if(!strncmp(uevent->subsystem, "misc", 4) &&  
  65.                     !strncmp(name, "log_", 4)) {  
  66.       base = "/dev/log/";  
  67.       mkdir(base, 0755);  
  68.       name += 4;  
  69.     } else  
  70.       base = "/dev/";  
  71.   }  
  72.   
  73.   if (!devpath_ready)  
  74.     snprintf(devpath, sizeof(devpath), "%s%s", base, name);  
  75.   
  76.   if(!strcmp(uevent->action, "add")) {  
  77.     //ERROR("TK------_>>>>>>>>>make_devices\n");//add by tankai  
  78.     make_device(devpath, uevent->path, block, uevent->major, uevent->minor);  
  79.     if (links) {  
  80.       for (i = 0; links[i]; i++)  
  81.         make_link(devpath, links[i]);  
  82.     }  
  83.   }  
  84. }  
  85. static void make_device(const char *path,  
  86.                         const char *upath,  
  87.                         int block, int major, int minor)  
  88. {  
  89.   mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR);  
  90.   setegid(gid);  
  91.   mknod(path, mode, dev);  
  92.   chown(path, uid, -1);  
  93.   setegid(AID_ROOT);  
  94. }  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《Linux设备节点创建》用户空间ueventd创建设备节点规则 的相关文章

随机推荐

  • Java中接口和抽象类有什么区别

    题目 请问Java中接口和抽象类有什么区别 解答 1 先看接口和抽象类的概念 接口是Java编程语言中的抽象类型 是抽象方法的集合 抽象类是一个类中含有抽象方法 抽象类前面用abstract关键词修饰 2 再说接口和抽象类间区别 接口可以含
  • MySQL的主键和外键

    使用 MySQL必知必会 中的表 向表products插入数据出错 从报错信息看 应当是表的主键和外键的问题 先用show create table products查看表products的创建信息 外键关系涉及一个包含中心数据值的父表 以
  • git高级特性之 - cherry-pick

    文章目录 背景 介绍 配置项 e edit n no commit x s signoff m parent number mainline parent number 实践案例 自动提交 不自动提交 增加额外说明信息 重新编辑提交信息 有
  • vue的优势为什么使用vue?

    问题网址 http bbs daxiangclass com thread 35 htm 轻量级框架 只关注视图层 是一个构建数据的视图集合 大小只有几十kb 简单易学 国人开发 中文文档 不存在语言障碍 易于理解和学习 双向数据绑定 保留
  • 使用 Spring 2.5 基于注解驱动的 Spring MVC

    概述 继 Spring 2 0 对 Spring MVC 进行重大升级后 Spring 2 5 又为 Spring MVC 引入了注解驱动功能 现在你无须让 Controller 继承任何接口 无需在 XML 配置文件中定义请求和 Cont
  • windows环境变量 set使用

    windows环境变量 set使用 一 查看所有环境变量的名称和值 Linux下 export Windows下 set 二 根据名称查该环境变量的值 Linux下 echo 环境变量名 比如 echo ORACLE HOME Window
  • 图像识别平台建设之路(自建+三方产品)

    强烈推荐一个大神的人工智能的教程 http www captainai net zhanghan 前言 之前做过东南亚的相关业务 业务流程中需要进行身份证或人脸识别 在国内相关的基础设施比较完善 但是在东南亚相对设施不健全 针对真人识别 有
  • 中间件的安装和优化——开源软件诞生6

    赤龙ERP软件及中间件的安装和配置 第6篇 用日志记录 开源软件 的诞生 赤龙ERP开源地址 点亮星标 感谢支持 与开发者交流 kzca2000 码云 https gitee com redragon redragon erp GitHub
  • vue.js 全局组件学习笔记

    用法 注册或获取全局组件 注册组件 传入一个扩展过的构造器 Vue component my component Vue extend 注册组件 传入一个选项对象 自动调用 Vue extend Vue component my compo
  • windows 10安装elasticsearch-head-master

    目录 1 下载安装包 2 安装依赖 2 1 安装node 2 2 安装grunt 3 安装head 1 下载安装包 es环境是在这个链接安装的 CentOS7 9安装elasticsearch 8 3 1 kibana 8 3 1和wind
  • Altium Designer学习2:如何屏蔽原理图中部分电路,保留电路的同时且不导入PCB?

    Altium Designer学习2 如何屏蔽原理图中部分电路 保留电路的同时且不导入PCB 注 本文章是我在使用Altium Designer中的总结 任何人不得商用 如有侵权 请联系我删除 谢谢 打开想要屏蔽的原理图 然后place g
  • C++ MFC学习 基于对话框实现猜数字游戏

    界面的设计 1 为控件添加变量 右键添加变量即可 Tips 为STATIC TEXT添加变量时 需要更改ID 后缀 不能为STATIC 2 初始化 OnInitDialog 中创建随机数种子 srand unsigned time NULL
  • Shell 脚本中经典的13个面试题

    经典的Shell十三问 1 为何叫做shell 2 Shell prompt PS1 与Carriage Return CR 的关系 3 别人echo 你也echo 是问echo知多少 4 双引号 与 单引号 有什么区别 5 var val
  • 解决“warning #188-D enumerated type mixed with another type”告警

    今天分享一个之前我之前在嵌入式开发时候遇到的一个告警提示 首先我们看一下这个告警提示 warning 188 D enumerated type mixed with another type 其翻译过来是 警告 188 D枚举类型与其他类
  • C--小Why的商品归位-- 牛客小白月赛77

    输入 3 3 1 1 2 1 3 2 3 输出 2 解析 先不考虑购物车的容量 即购物车容量为无限大 这样我们可以通过每种货物上车 下车的时间计算出每一个时间点内 购物车中货物的数量 统计出所有时间点内 货物数量的最大值max 这个最大值所
  • 电商平台项目----项目搭建

    目录 项目介绍 其他配置 eslint 校验功能关闭 src文件简写方法 配置别名 项目路由分析 vue router 路由 路由组件 完成非路由组件 Header Footer 组件 步骤 配置less 路由组件的搭建 路由组件与非路由组
  • 关于微信小程序使用JavaScript求解背包问题

    背包问题求解 拟解决生活中常见的问题之一 背包问题 wxml wxss js 拟解决生活中常见的问题之一 背包问题 该问题要求在一个物品集合中选择合适的物品放入背包 在放入背包中的物品总重量不超过背包容量的前提下 希望放入背包的物品总价值最
  • 学scratch和机器人编程哪个好

    学scratch和机器人编程哪个好 小孩的学习一直都是家长们非常关心和重视的一件事情 很多的家长在培养孩子的学习方面也可以说是相当耐心的 会给孩子选择一些能够有利于孩子成长的课程 就拿现在很多的家长想要孩子去学习机器人编程的课程来说 有的家
  • 电脑取消撤销快捷键是什么_电脑健盘中的所有英文组合意思超值解释建议收藏...

    电脑键盘上 所有英文键的意思 1 Esc 取消和退出键 2 Tab 表格键切换键 3 Caps Lock 字母大小写切换键 4 Shift 转换键 5 Ctrl 控制键 需要配合其他键或鼠标使用 例如复制CtrI C 6 Alt 可选 切换
  • 《Linux设备节点创建》用户空间ueventd创建设备节点规则

    转自 http blog csdn net tankai19880619 article details 11726371 说明 本文基于Android2 3和Linux2 6 其余版本仅供参考 一 devfs udev和sysfs是什么关