前言

uevent是一个经常看见但是从来没有去研究过的一个东西。正好,这次重构一加第三方系统tri-state-key驱动的时候,发现里面也有相关的玩意儿,那就,不得不弄明白了

uevent

是什么

uevent是一种内核通知用户空间关于/sys目录下的kobject的更改的一种方式,比如在/sys目录下的节点创建、移除和更新时

uevent存在的意义在于:用户空间不再需要花费大量的时间和性能遍历sysfs,去寻找各种细微的变化,这对linux下设备的自动发现和挂载有重要作用,将在稍后阐述

当然,uevent也并非仅限于sysfs中节点的创建和删除,内核空间也可以向用户空间发送含有指定信息的自定义uevent,触发用户空间的指定事件

如何发送

uevent的发送方式主要分为三种(我目前只见过这三种)
一种是由内核空间自动发送:当sysfs中创建的kobject符合一定条件时,内核空间会自动发送其add与remove甚至还有change事件
另一种时内核空间手动发送:比如使用函数kobject_uevent或者kobject_uevent_env,第二个函数可以自定义环境变量,向用户空间发送含有指定信息的uevent
还有一种是由用户空间触发:往指定节点中写入事件名称即可,比如echo change > /sys/devices/**/uevent

内核中也有一些驱动,封装了通过往uevent里装数据来与用户空间进行通信的操作,比如extcon

menuconfig EXTCONtristate "External Connector Class (extcon) support"helpSay Y here to enable external connector class (extcon) support.This allows monitoring external connectors by userspacevia sysfs and uevent and supports external connectors withmultiple states; i.e., an extcon that may have multiplecables attached. For example, an external connector of a devicemay be used to connect an HDMI cable and a AC adaptor, and tohost USB ports. Many of 30-pin connectors including PDMI arealso good examples.

当然,并不是所有/sys目录下的条目都可以拥有uevent节点并自动发送uevent,这个似乎和内核中相关数据结构的定义方式有关,此处不展开

如何接收

uevent的接收分为两种方式

第一种,用户空间可以通过打开一个特定的netlink socket,然后poll在那里休眠等待事件唤醒,在获得uevent事件后解析并按照要求进行处理

另一种,内核可以直接调用用户空间的可执行文件,并把信息作为环境变量的方式发送过去?(未验证)(类似usermodehelper?)

安卓使用的是第一种,并在cutils/uevent.h中提供了开启这个socket的封装int uevent_open_socket(int buf_sz, bool passcred),用户空间也可以直接通过ssize_t uevent_kernel_multicast_recv(int socket, void* buffer, size_t length)来接收uevent message

安卓在platform/system/extras/tests/uevents提供了一个名为uevents的测试工具,可以使用mmm命令编译二进制文件并安装到system

在没有写sepolicy的情况下,这个二进制文件只能在root / permissive下使用

这个测试工具的内容非常简单,但同时也提供了使用uevent的不错的参考

/** Copyright (C) 2012 The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**      http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/#include <cutils/uevent.h>
#include <stdio.h>#define UEVENT_MSG_LEN  1024int main(int argc, char *argv[])
{int device_fd;char msg[UEVENT_MSG_LEN+2];int n;int i;device_fd = uevent_open_socket(64*1024, true);if(device_fd < 0)return -1;while ((n = uevent_kernel_multicast_recv(device_fd, msg, UEVENT_MSG_LEN)) > 0) {msg[n] = '\0';msg[n+1] = '\0';for (i = 0; i < n; i++)if (msg[i] == '\0')msg[i] = ' ';printf("%s\n", msg);}return 0;
}

安装到系统后,在adb root环境下输入uevents即可获得所有关于uevent事件的汇报

常见的uevent使用

比如电池电量/电流等信息的更新就是通过uevent传递的,硬件设备的插拔也是通过uevent通知用户空间的,当然,还有文章开篇的一加三段式按键驱动,也是通过uevent通知用户空间按键的切换状态的

除了某些非常secure的信息传递需要自建节点来poll外,对别的来说,uevent确实是一个非常不错的封装。毕竟,uevent是个广播,具有一定权限的进程都能拿到其内容,虽然有selinux的保护,但也别对它的安全性太有期待

ueventd

你看呐,这个东西啊,以d结尾,那很显然,它是一个daemon(守护进程)
没错,它是安卓的一个非常核心也非常有特色的进程,和uevent有关,你猜它是一个uevent的转发器?那就错了

从devfs说起

从网上的一些历史资料来看,devfs出现的很早,大约是在Linux 2.4的时候,嗯,它就是最最最原始的/dev目录,里面显示了内核中挂载的各种设备的信息,但是,它却因为混乱、难管理、性能开销巨大等问题,在Linux 2.6被取代
取代的方式是,引入sysfs(没错,devfs出现的比sysfs早),结构化的存储各所挂载的总线等详细信息,然后使用一个用户空间程序根据sysfs中的设备信息来创建和更新/dev目录,从而解决上述问题
所以说啊,uevent的原教旨其实就是在这里——向用户空间程序通知sysfs的更改,即时在dev中创建/删除/更新设备,并通过这种可睡眠的被动的方式(指poll)来有效降低开销

而这个用户空间程序,在正宗的Linux上,叫udev,在迷你嵌入式设备上,叫mdev,而在安卓上,叫ueventd

我们可以通过df指令清晰的看到,现代Linux下,挂载到/dev的究竟是什么

别致的/dev

但是在安卓上,挂载到/dev下的东西就非常有意思了

什么?tmpfs?没错,就是一个非常非常普通的tmpfs,这意味着它下面的内容甚至是可以随意创建删除修改的(只要权限够)

怎么样,把/dev/null给删了,再创建了一个fuck节点

Linux之uevent与ueventd区别相关推荐

  1. Linux进程与线程的区别 详细总结(面试经验总结)

    首先,简要了解一下进程和线程.对于操作系统而言,进程是核心之核心,整个现代操作系统的根本,就是以进程为单位在执行任务.系统的管理架构也是基于进程层面的.在按下电源键之后,计算机就开始了复杂的启动过程, ...

  2. Linux进程与线程的区别

    2019独角兽企业重金招聘Python工程师标准>>> Linux进程与线程的区别 cnyinlinux 本文较长,耐心阅读,必有收获! 进程与线程的区别,早已经成为了经典问题.自线 ...

  3. 【Linux】Linux简介以及 与UNIX区别

    一直以来对Linux.Unix.linux内核.linux发行版的概念比较模糊,最近查找资料并经过自己的整理,主要总结了Linux和UNIX的区别和联系.内核和操作系统的关系.Linux操作系统和结构 ...

  4. 从Docker在Linux和Windows下的区别简单理解Docker的层次结构

    上篇文章我们成功在Windows下安装了Docker,输出了一个简单的Hello World程序.本文中我们将利用Docker已有的云端镜像training/webapp来发布一个简单Python的W ...

  5. linux服务器知识学习:Linux与Windows之间的区别

    目前国内Linux更多的是应用于服务器上,而桌面操作系统更多使用的是Window. linux与Windows主要的区别如下: 从界面上来看, Windows界面统一,外壳程序固定所有Windows程 ...

  6. 103.107.189.XXX机房服务器linux和windows系统的区别:

    机房服务器linux和windows系统的区别: 1.首先从界面上个人感觉windows的界面比linux漂亮,从视觉效果上来看windows给人感觉更好 2.软件的使用,linux软件都是开源的由全 ...

  7. centos linux 和 centos stream 的区别

    文章目录 CentOS Linux 和 CentOS Stream 的区别 项目终止日期(EOL) 上游 vs 下游 更新频率 贡献方式 测试 CentOS Linux 和 CentOS Stream ...

  8. linux 和windows 内存管理区别

    linux 和windows 内存管理区别 在 80 年代初,IBM 推出的 IBM PC 机采用了 Intel 16 位的 8088 处理器,该处 理器可以访问最多 1MB 的存储器.当应用程序需要 ...

  9. linux64和x86,Linux x86和x64的区别

    0x01:寄存器分配的不同 (1)64位有16个寄存器,32位只有8个.但是32位前8个都有不同的命名,分别是e _ ,而64位前8个使用了r代替e,也就是r _.e开头的寄存器命名依然可以直接运用于 ...

最新文章

  1. K-BERT | 基于知识图谱的语言表示模型
  2. Android启动脚本init.rc(2)
  3. 【转】SSM框架搭建流程与解析
  4. 计算机编程老鸟的心得,java入门123——一个老鸟java学习心得.docx
  5. 使用uuid作为数据库主键,被技术总监怼了!
  6. [转]测试淘宝站内的搜索系统
  7. Chrome 远程调试协议分析与实战
  8. 大规模数据作成时的注意点。
  9. Jupyter-notebook安装问题及解决
  10. Android平台中实现对XML的三种解析方式
  11. 2010年11.30日 爱普生 武昌培训 Technical workshop OPOS INSTALL
  12. WAP PUSH 技术
  13. CDR话单主要字段介绍
  14. IBM 人工智能黑科技
  15. JavaScript发送短信案例
  16. 分库分表:应用场景、方式方法、面临问题
  17. winform的FormBorderStyle设置为None窗口的最小宽度不能小于132
  18. 字符串 拼接方法报错 not defined
  19. AI读书笔记:《剑桥五重奏—机器能思考吗?》
  20. python如何拼读英语单词怎么写_怎么用英标快速拼读英语单词,这些技巧你知道吗...

热门文章

  1. 方管图纸标注_结构图纸悬挑梁的标注方式
  2. 近期想跳槽的程序员必看!阿里P7级别面试经验总结,使用指南
  3. open-dingtalk和nginx 做内网转发
  4. Windows 10系统点击任务计划程序,提示找不到远程电脑如何处理
  5. 【优化算法】基于matlab量子粒子群算法求解单目标优化问题【含Matlab源码 2203期】
  6. react实现聊天界面_使用react做的聊天对话列表
  7. linux提取驱动程序,linux驱动程序调试常用方法
  8. C语言实现根据阳历(公历)显示农历,干支,生肖
  9. Zemax学习笔记(2)- 镜头数据编辑器及快速编辑器的使用方法介绍
  10. Unity的object被销毁时陷进