当前位置: 首页 > news >正文

Linux设备管理之权限倾斜——mem、proc、devfs、sysfs、udev(下)

linux发展第一阶段

01devfs(linux2.6之前)

02udev(用户空间)

03sysfs(linux2.6之后,描述设备属性)

linux发展第二阶段

01sysfs+udev(udev用户空间)

02devfs(内核空间)

03proc:在用户态检查内核状态的机制

 

 各个内容简介:

01 sysfs特性:

同比devfs而言:linux2.6之后

作用:表示设备结构,属性

在驱动中用到函数:

/*------------------------------------------------------------------------------------
sysfs访问设置设备属性-*/ 
/*访问设置属性方法 */  
static ssize_t hello_val_show(struct device* dev, struct device_attribute* attr,  char* buf);  
static ssize_t hello_val_store(struct device* dev, struct device_attribute* attr, const char* buf, size_t count);  
  
/*定义设备属性*/  
static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, hello_val_show, hello_val_store);  

/*----------------------------------------------------------------------------------*/ 

 

02 udev

与sysfs同是linux2.6之后出现

简述:udev仅仅是根据sysfs来干活的一个工具而已。完全在用户态工作。

03 devfs

 

 

 

Jack:淫龙,Linux实现的设备管理机制是什么样子的呢?

我:在2.4内核里,主流的解决方案是devfs

Jack:我知道。在2.6里,devfs已经被udev替代了(谬论)

我:这种说法是不准确的,是一种外行看热闹的说法。

Jack:怎么说?

我:让我给你讲一讲proc文件系统的起源吧。听完了,你自然就明白了。

Jack:proc文件系统?穿越了。

我:在很久很久很久以前,Linux内核的所有代码都是写死的,如果你想修改其中一些参数,必须要手动修改源代码,然后重新编译,重新写软盘,重新跑起来。在很久很久以前,在Unix的/dev目录下出现了一个文件——/dev/mem。这是一个特殊(变异)的设备文件,通过对这个文件的读写(从用户进程),可以改变整个内核的内存。从此,内核的内存可以动态进行修改,而不需要停机修改内核代码、重新编译、重新写软盘、重新启动这一些列的复杂过程。

Jack:然后,然后,王子和公主性福地生活在一起了?

我:去死吧。Linux内核的开发者从/dev/mem这个变异的设备文件中尝到了甜头后,就一发不可收拾了。他们接着在/下设立了一个/proc目录,同时创建了proc文件系统。/proc目录下的文件都是变异型文件,不存在磁盘中,而是在访问时动态建立,存在于ramfs里。这些文件在早期主要是对内存使用情况的统计以及动态修改,而到了后来,内核设计人员的胃口越来越难以满足。所有他们认为易于管理的理念都应该加入这个目录,/proc下就不再局限于内存信息,甚至包括外部设备管理信息——sysfs

Jack:那这个devfs是什么关系呢?

我:devfs就是在这种背景下成长起来的。算是proc文件系统的一种推广或者变异。但是,devfs有很多致命的缺陷,导致devfs的作者没有解决的能力与信心,终于,决定宣布失败,彻底放弃。然后,在Linux2.5的内核中,尝试构建一种sysfs文件系统。这个文件系统挂接在/sys下。

Jack:devfs的致命缺陷是什么呢?

我:这个问题网上已经很多了,随便Google一下就行了。

Jack:那么udev又是怎么回事儿呢?

我:先不要急。让我把sysfs说完,你再听udev就完全明白了。sysfs相比于devfs,它已经是一套成型的、统一的设备管理模型。sysfs的描述能力不仅仅局限于干活的外部设备,甚至包括外部总线(pci总线等)。挂接在/sys目录下的文件的根目录是按类型(而非层级)来分类的。包括/sys/bus,/sys/block,/sys/class等

Jack:那么,udev是怎么来的呢?

我:sysfs文件系统能直观地反应加入计算机的总线、设备的信息(通过kobject对象实现)。但是,它仅仅是一种体现和反应,并不能如devfs一样,在生成设备文件时(不管设备在不在),就直接把设备驱动加载进来(其实,这是不必要的)。如果想智能地控制外部设备的管理,还需要一个任务,一个专业的工具。在devfs里,干这个活儿的是一个内核线程。而udev正好相反,它通过等待内核注册过的设备热插拔引起的事件,激发相应的功能

Jack:这样有什么优势吗?

我:这样做,最大的优势在于,内核的负载降低了,工作移交到了用户进程里。

Jack:可是,从CPU的角度来讲,不是一样要干活吗?整体的负载并没有降低。

我:是的。从CPU的角度讲,负载并没有降低,但是,devfs所负责的工作并非操作系统最核心的工作,这种工作能移交到用户空间是最好。好处至少有三点:

        1、如果该线程(或进程)崩溃,对整个系统而言,在用户空间崩溃比在内核空间崩溃的负面影响要小得多(尤其是在一些金融系统内)

         2、运行在内核空间的线程会碰到大量的同步与互斥的问题,设计起来会比较困难,如果以后想在内核添加一个什么功能(尤其是核心功能),那么难度将会成指数增长。

         3、内核并非是垃圾场,不能什么都往里扔,即便现在没有坏。但是,如果根基打坏了,10年后,整个系统遗留下来的问题将会非常可怕。这种现象在各大互联网公司非常严重。

Jack:这么说来,udev和devfs根本就不是同一个层次的概念devfs不仅包括了一个文件系统机制,还包括了监控外部设备以及干活的线程。而udev仅仅是根据sysfs来干活的一个工具而已。(该文总解释)

我:可以这样理解。所以,我说“devfs被udev替代”是一种外行看热闹的说法

Jack:那你可以说一说devfs与udev实现上的差异吗?

我:不可以。(单)devfs(体系)已经在2.6内核里被彻底废弃了,我对它的实现没有认识。关于sysfs+udev可以简单谈一下它的原理。最重要的是3个结构体:kobjects、ksets、subsystems。其中,当一个kobjects结构体对象被生成的时候(驱动工程师实现)会发生两个重要的事情:1、在/sys/目录下会有相应的文件夹。2、产生一个hotplug事件,当有外部设备被插/拔时,内核将会把这个时间主动通知到用户空间的进程(udev。本质上,hotplug是一种信号或者软中断机制,信号也是广义上的软中断)。相比于kobjects的高度抽象,kset更具体一些。具体到什么程度呢?所有具有相同属性的kobjects被分为一个kset。至于什么样的设备具有相同的kobjects属性,由驱动工程是自己判断。而一个设备具体是怎么加入Linux的,就不是设备模型应该考虑的问题,而是驱动工程师的实现。设备模型仅仅是给出了一个框架,所有的设备都需要遵守,但并不是手把手教驱动工程师写驱动。

 

 

 

 

-------

转载于:https://www.cnblogs.com/Ph-one/p/4445081.html

相关文章:

  • cdev[典]
  • devfs,proc,udev
  • AIDL与stub
  • Android 系统的四层结构
  • STM32硬件复位时间
  • allegro添加多个过孔
  • 珠宝
  • Unable to open c
  • allegro飞线隐藏
  • 23.allegro中钻孔[原创]
  • mediatek
  • 24.allegro中光绘gerber[原创]
  • allegro中数据库检查
  • 25.allegro中模块复用[原创]
  • 成板
  • 77. Combinations
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • React-flux杂记
  • Sass Day-01
  • spring-boot List转Page
  • yii2中session跨域名的问题
  • 百度地图API标注+时间轴组件
  • 从零搭建Koa2 Server
  • 多线程事务回滚
  • 排序(1):冒泡排序
  • 前嗅ForeSpider采集配置界面介绍
  • 浅谈web中前端模板引擎的使用
  • 什么是Javascript函数节流?
  • 数组的操作
  • 与 ConTeXt MkIV 官方文档的接驳
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • 通过调用文摘列表API获取文摘
  • 我们雇佣了一只大猴子...
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (附源码)springboot人体健康检测微信小程序 毕业设计 012142
  • (附源码)springboot社区居家养老互助服务管理平台 毕业设计 062027
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失
  • (原創) 物件導向與老子思想 (OO)
  • (转)详解PHP处理密码的几种方式
  • (状压dp)uva 10817 Headmaster's Headache
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NetCore实践篇:分布式监控Zipkin持久化之殇
  • 。Net下Windows服务程序开发疑惑
  • @EnableConfigurationProperties注解使用
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [2016.7.Test1] T1 三进制异或
  • [ABP实战开源项目]---ABP实时服务-通知系统.发布模式
  • [AIGC] Java 和 Kotlin 的区别