【Android】细数Linux和Android系统中的伪文件系统

文章目录

  • 前言
  • Linux伪文件系统
  • cgroupfs
    • Linux的cgroups
    • Android的cgroups
  • debugfs
  • functionfs(/dev/usb-ffs/adb)
    • functionfs 的引入
      • sysfs是什么
  • procfs(/proc)
  • pstore(/sys/fs/pstore)
  • selinuxfs(/sys/fs/selinux)
  • sysfs(/sys)
  • 参考

前言

做了好些年Android开发,你了解过Linux伪文件系统吗?
在 Linux 中,伪文件系统(Pseudo Filesystem)是一种特殊的文件系统,它不涉及具体的物理存储设备,而是提供了一种接口,允许用户和应用程序以文件和目录的形式访问内核和其他系统信息。这些文件和目录在运行时被内核动态地生成,因此被称为伪文件系统。
阅读本文,我们一起来学习Android中的伪文件系统的方方面面。

Linux伪文件系统

尽管不是严格意义上的Android 文件系统,但 Linux 内核中提供的其他三种值得注意的文件系统也在 Android 上被使用。

请注意术语“伪文件系统”, 这些文件系统没有一个会被存储到物理存储设备上去的,相反它们是直接由内核中的回调函数维护的。也就是说,当要访问其中的一个文件或目录时,某个对应的内核级处理函数就会被调用。

这也意味着,这些文件系统并不真正占用存储空间(在内核所用的内存中,用于存放对应的 inode 和目录数据结构的开销不算)。更进一步说,每次访问伪文件系统中的某个文件或目录都要去调用系统的回调函数,所以这些文件和目录反映出的总是最新的实时更新的数据。

由此可以推出,讨论(伪文件系统中) 文件的大小是没有意义的,这也就是为什么用“Is -l”命令看到的这些文件都是空的的原因。

注意,由于这些文件都是由内核代码(由整个内核,或者在某些情况下,由某些内核模块
导出的,所以根据内核版本的不同,这些文件有时也会有所不同,而且文件中的内容(特别是 sysfs 中文件的内容)也是和硬件紧密相关的。

大多数伪文件系统中的文件都是以只读权限创建的,因为其用途是提供实时的诊断信息,向用户态程序提供一种使之能够查看一些内核态中原本是不可访问的变量和结构的机制。

不过有些文件实际上是可写的,这提供了一种更有用的能力,使得我们在用户态中就能实时地对内核中的数据施加影响。

不像在某些基于注册表的系统中,修改配置需要对各种隐藏的而且通常是不公开文档的注册表键和值进行操作那样,对伪文件系统中文件进行的修改,会立即产生作用,而且还不需要系统重启。

cgroupfs

Linux的cgroups

Linux 内核提供了一种重要的资源控制机制,它就是 cgroups。

一个 cgroup 就是一个可容纳一个或多个线程的组容器 (container group),它能把组中的所有线程视为一个整体,统一进行操作和策略设置。

在 Linux 内核文档以中,提供了关于 groups 的相当详尽的文档。为了便于在用户态中能把各个线程放置到不同的组中,cgroups 通过伪文件系统把它们自己导出到用户态中,这使得只需对这些文件进行简单的“写”操作,就能把一个线程添加到某个组中。

Android的cgroups

尽管 cgroups 用途广泛,可以以各种不同方式使用,但是在 Android 中却是以一种非常受限的方式使用它的。

只用于 CPU 使用记时和线程调度,如图:
在这里插入图片描述

Bionic 在每个进程启动时,通过/acct 为其设置了CPU 使用记时器,因此它能应用到系统中所有的进程上。

/sys/fs/cgroup/memory 可以被 ActivityManager(通过 android.os.Process 及其JNI方法 setSwappiness)访问。

最后,是/dev/cpuctl 目录,尽管它位于/dev 目录下,但仍是个由 Android调度策略 (scheduling policy)安装的 cgroup 目录。

在/init 启动时,它会安装该目录并创建其下的各个子目录,即

  • dev/cpuctl/tasks 对应系统任务
  • /dev/cpuctl/apps/tasks 对应运行在前台的应用
  • /dev/cpuctl/apps/bg_non_interactive/tasks 对应运行在后台的应用。

并以此对各个组进行调度。

每个组都被分配到一个“共享”CPU 的数值,并被赋予了一个可以运行的时间上限。这样就能防止因有意或无意的错误操作,导致某个进程完全占据整个 CPU 运行时间的情况发生。

/dev/cpuctl的配置是在/init.rc 中完成的,下图是/init.rc脚本中安装cpuctl cgroups的部分代码:
在这里插入图片描述

debugfs

debugfs 文件系统是用于(输出)内核级的调试信息的。

驱动以及类似的子系统可以自由地把驱动的调试信息转储到这个文件系统中。和其他伪文件系统一样,如果文件系统已经被 mount了,大量的调试信息就能像读取其他文件那样被读取出来。

不过请注意,debugfs 没有必要一定要被 mount 到系统中,而且内核也可以被编译成不支持debugfs 的形式。如果内核支持 debugfs,它就可以用下面这行简单的命令行命令 (通常是在/init.hardware.rc中执行)mount 上来:

mount -t debugfs none /sys/kernel/debug

尽管理论上可以把它 mount 到任意一个 mount 点上,但是因为它实在是太有用了,所以通常都能在“/”目录中找到它的符号链接。

比如,在模拟器镜像中,就有一个“/d”符号链接指向 debugfs 的 mount 点。

debugfs 中的内容是完全由内核的版本以及内核中实现了哪些 debug 特性决定的。

下图给出的是在各个版本的Android 内核中常见的几个文件/目录,位于/sys/kernel/debug目录中:
在这里插入图片描述

functionfs(/dev/usb-ffs/adb)

在Android 系统中,USB 的功能经常会需要根据用户的选择 ,即是以

  • USB 调试、
  • 大容量存储介质
  • 还是以其他方式连接设备

用户的这一选择将通过 init动态地进行重新配置,它是由一个特定的“gadget”驱动进行控制的。

传统的驱动程序(Android L之前的内核版本)需要通过sysfs 导出它的重新配置参数。这一做法是它被认为非常臃肿,并需要改进的原因之一。

functionfs 的引入

在2010年某个时候,一个相对较新的特性被引入Linux 内核,由 Linux内核提供一个通用的文件系统,使驱动能够获取用户态空间中发出的对配置修改的请求。

这一文件系统可以被认为是对 sysfs 的一个补充,只不过设计后者的目的是向用户态输出一些内核中的变量和驱动信息,而前者的设计目的是从用户态获取输入。root 用户可以使用 mkdir(2)创建目录,这会引起内核创建相应的内核对象,这些对象可以在稍后由在用户态中发起的、对目录中的伪文件进行的 write(2)操作予以初始化。

在 Unix-like 操作系统中,系统调用 mkdir 是用于创建目录的。系统调用的编号(通常用括号中的数字表示,例如 mkdir(2))是指该系统调用在系统调用表中的编号。在这个上下文中,(2) 表示系统调用表中的编号,而不是 mkdir 函数本身的参数。

sysfs是什么

sysfs 是 Linux 内核中的一种虚拟文件系统,用于向用户空间提供有关内核、设备和驱动程序的信息。它通常被挂载到 /sys 目录下。

以下是 sysfs 的主要特点和用途:

  1. 提供内核参数和配置信息: /sys 目录下的文件和目录包含有关内核运行时参数、配置选项和其他内核信息的数据。

  2. 设备和驱动程序信息: sysfs 提供了有关系统上的设备和驱动程序的信息。例如,你可以在 /sys/class/sys/bus 下找到有关不同设备类别和总线的信息。

  3. 动态生成: sysfs 中的文件和目录是在运行时动态生成的,以反映系统的当前状态。这使得用户空间能够动态地获取有关系统状态的信息。

  4. 与用户空间的接口: 用户空间的应用程序和工具可以通过读写 /sys 下的文件来与内核进行通信和配置。这提供了一种方便的用户接口,用于访问和配置系统信息。

  5. 用于设备文件:/sys/class/sys/devices 下,你可以找到关于系统中设备的信息,这对于设备管理和识别非常有用。

在使用 sysfs 时,一些常见的目录结构包括:

  • /sys/class: 包含有关设备类别的信息,例如网络设备、块设备等。
  • /sys/devices: 包含有关系统中所有设备的信息。
  • /sys/bus: 包含有关总线的信息,如 USB 总线、PCI 总线等。
  • /sys/module: 包含有关内核模块的信息。

用户和开发者可以通过查看和操作 sysfs 中的文件来获取关于系统和设备的详细信息,这对于调试、配置和监控系统非常有用。

procfs(/proc)

procfs 文件系统名副其实,它提供了一个基于目录的观察系统中运行的进程的方式。这个想法最初是出现在 Plan 9 操作系统上的,随后 Linux 马上吸收并改造了它,使之能提供大量关于进程、线程以及其他全方位的系统诊断信息。

不论在/proc 中提供太多东西到底是不是件好事,这都不妨碍它成为一个极为重要的文件系统。许多 Linux 实用程序(如 top、netstat、lsof和ifconfig)以及许多 Android 工具(如 procrank、librank) 都把它作为诊断信息的来源,没有它就不能运行。Linux 在 pro(5)的手册页中记录了相当详细的相关信息,并保持它不断更新。

pstore(/sys/fs/pstore)

pstore机制是 Linux 的一个内核特性(在3.5版时引入),它允许内核把部分物理内存(RAM)单独划为 persistent store 区。它在需要应用抓取内核崩溃(panic)时的数据非常有用。

内核崩溃是指内核中出现了内存破坏的情况。由于这类情况发生之后可能会影响到文件系统的执行逻辑。所以,这时任何向文件系统写入数据的操作,都可能使情况进一步恶化,甚至导致文件系统也被破坏掉。

UNIX 系统通常会把内核崩溃时的数据转储到 swap 分区里去,但这也不能保证重启之后数据一定都还在。而且 Android 是没有 swap 分区的,因此,剩下的唯一靠谱的解决方案是专门为此留出一部分物理内存,即一个专用的内存区域persistent store,让内核把它崩溃时的数据,至少是 bare minimum转储到这里来。

随后内核自动执行一次热重启(也就是中间不切断电源的重启),这也就意味着物理内存中的信息不会在重启的过程中而丢失。在重启的过程中,内核会去检查 persistent store 区,看看里面是不是留有上一次系统运行遗留下来的数据。如果有的话,它就会通过/sys/fs/pstore,让我们能在用户态中读取到这些数据。

在较旧版本的Android 系统中,这一功能是利用了一个被称为“RAM console”的 Android特有的特性(也算是某种 Android 内核技巧)提供的。追溯它的实现代码,我们发现它还是位于/init.rc 中。这段代码会从/proc/apanic console 和/proc/apanic threads 中获取数据,并把它们写到/data/dontpanic 中(这一大圈绕的,简直就是“银河系漫游指南”)。随着 pstore 功能的到来,这一实现方式已经被放弃,转而使用/sys/fs/pstore。

selinuxfs(/sys/fs/selinux)

和debugfs 一样,SELinuxFS 传统上也是 mount 在/sys 下,但却不是 sysfs 文件系统的一部分。这个文件系统是专供 SELinux 使用的,其中存储了与安装策略 (installed policy) 相关的文件。

这个文件系统中最重要的文件是 policy 和伪文件 enable。

其中,policy 提供了加载(编译,可以使用的二进制可执行文件的格式)安全策略。

enable 则用来切换这些策略是否要被强制执行。

sysfs(/sys)

从重要性上说,它的重要性仅次于procfs。sysfs 是在 Linux 内核版本 2.6 中作为对 procfs 的补充而被引入的,为了能把/proc 里的东西整理得井井有条些,把与硬件和模块相关的配置文件移到一个单独的目录中去,并让目录的层次也更清晰些。
你会发现,/sys 是个“整洁的”目录,伪文件被分门别类地放在各自所属的子目录中的地方。/sys的子目录如图:

在这里插入图片描述

不同的设备之间硬件配置的差异非常大,所以各种不同设备中的 sysfs 里存放的文件间的差别也非常大。Android 框架之所以能够免于受到因不同厂商选用不同的五花八门的硬件而带来的麻烦,完全要感谢硬件抽象层(HAL,Hardware Abstraction Layer),它是由/system/lib/libhardware.so及其插件构成的,因为硬件抽象层把对不同特定文件的调用封装成了更为统一的 API。

参考

《最强Android书:架构大剖析》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/643078.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java Web(二)--HTML

基本介绍 官网文档地址: HTML 教程 HTML(HyperText Mark-up Language)即超文本标签语言;HTML 文本是由 HTML 标签组成的文本,可以包括文字、图形、动画、声音、表格、链接等;HTML 的结构包括头部(Head&…

学校“数据结构”课程Project—扩展功能(自主设计)

目录 一、设想功能描述 想法缘起 目标功能 二、问题抽象 三、算法设计和优化 1. 易想的朴素搜索 / dp 搜索想法 动态规划(dp)想法 2. 思考与优化 四、算法实现 五、结果示例 附:使用的地图API 一、设想功能描述 想法缘起 OSM 导出…

汽车网络架构与常用总线汇总

汽车CAN总线简述 CAN 是控制器局域网Controller Area Network 的缩写,1986年,由德国Bosch公司为汽车开发的网络技术,主要用于汽车的监测与控制,目的为适应汽车“减少线束的数量”“通过多个网络进行大量数据的高速传输”的需求。…

TA百人计划学习笔记 3.1.1模板测试

资料 源视频 【技术美术百人计划】图形 3.1 深度与模板测试 传送门效果示例_哔哩哔哩_bilibili ppt 3100-模板测试与深度测试(1) 参考 Unity Shader: 理解Stencil buffer并将它用于一些实战案例(描边,多边形填充,反射区域限定,阴影…

c++学习笔记-STL案例-机房预约系统6-老师模块

前言 衔接上一篇“c学习笔记-STL案例-机房预约系统5-学生模块”,本文主要设计老师模块,从,老师登录和注销、查看所有预约、审核预约三个方面进行分析和实现。 目录 9 教师模块 9.1 教师登录和注销 9.1.1 构造函数 9.1.2 教师子菜单 ​编…

Linux7 安装 Oracle 19C RAC 详细图文教程

实战篇:Linux7 安装 Oracle 19C RAC 详细图文教程 本文是按照:https://www.modb.pro/db/154424的思路进行编写 一、安装前规划 安装RAC前,当然要先做好规划。具体包含以下几方面: 节点主机版本主机名实例名Grid/Oracle版本Publi…

鸿蒙原生开发-仿ChatGPT应用实战

运行环境 DAYU200:4.0.10.16 SDK:4.0.10.15 IDE:4.0.600 前言 在配置好环境之后,可以尝试这编写一个较为简单的应用程序练练手,这里选择使用一个免费的API接口网站 ALAPI来尝试编写一个可进行对话的GPT应用程序。 创建项目 …

SQL注入示例

例一、基础SQL注入:load_file读文件 CISP-PTE 认证考试 首先是有单引号和括号的,首要是要闭合,然后回显点是在-1的位置,读取文件上面的key的话使用的是load_file(/tmp/360/key) id-1)%09ununionion%09select%091,2,3,load_file…

【算法与数据结构】322、LeetCode零钱兑换

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题可以抽象成一个完全背包问题。 第一步, d p [ j ] dp[j] dp[j]的含义。 d p [ j ] dp…

Unity之Cinemachine教程

前言 Cinemachine是Unity引擎的一个高级相机系统,旨在简化和改善游戏中的相机管理。Cinemachine提供了一组强大而灵活的工具,可用于创建令人印象深刻的视觉效果,使开发人员能够更轻松地掌控游戏中的摄像机行为。 主要功能和特性包括&#x…

Springboot+vue的医院后台管理系统(有报告),Javaee项目,springboot vue前后端分离项目

演示视频: Springbootvue的医院后台管理系统(有报告),Javaee项目,springboot vue前后端分离项目 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的医院后台管理系统,采用M&#xff08…

LeetCode、875. 爱吃香蕉的珂珂【中等,最小速度二分】

文章目录 前言LeetCode、875. 爱吃香蕉的珂珂【中等,最小速度二分】题目及分类思路分析及代码实现代码优化 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Ja…

如何修改flutter的minSdkVersion版本?

在使用第三方插件的时候,插件对最低的 minSdkVersion版本是有要求的,你比如flutter 插件 webview_flutter 就会报一下错: minSdkVersion 16 cannot be smaller than version 19 declared in library 解决方法①: 这个时候我们需…

Python爬虫框架选择与使用:推荐几个常用的高效爬虫框架

目录 前言 一、Scrapy框架 1. 安装Scrapy 2. Scrapy示例代码 3. 运行Scrapy爬虫 二、Beautiful Soup库 1. 安装Beautiful Soup 2. Beautiful Soup示例代码 3. 运行Beautiful Soup代码 三、Requests库 1. 安装Requests库 2. Requests示例代码 3. 运行Requests代码 …

【蓝桥杯--图论】最小生成树prim、kruskal

今日语录&#xff1a;成功不是终点&#xff0c;失败不是致命&#xff0c;勇气才是取胜的关键。 文章目录 prim算法kruskal算法(稀疏图) prim算法 #include <cstring> #include <algorithm> #include <iostream>#define _CRT_SECURE_NO_WARNINGS using names…

8 种网络协议

什么是网络协议&#xff1f; 网络协议就是计算机之间沟通的语言&#xff0c;为了有效地交流&#xff0c;计算机之间需要一种共同的规则或协议&#xff0c;就像我们和老外沟通之前&#xff0c;要先商量好用哪种语言&#xff0c;要么大家都说中文&#xff0c;要么大家都说英语&a…

微信小程序实现长按 识别图片二维码

第一种方案&#xff08;只需要在image里面加一个属性就可以了&#xff09; show-menu-by-longpress“{{true}}” <image show-menu-by-longpress"{{true}}" src"{{sysset.dyqewm}}" />第二种方案 放大预览图片&#xff0c;长按识别二维码 wxml <…

数灵通实现抖音跳转企业微信啦

抖音是一款流行的短视频应用&#xff0c;用户可以通过简洁、有趣的短视频形式创作和分享内容。 对于企业而言&#xff0c;抖音拥有庞大的用户基础和广泛的影响力&#xff0c;因此企业希望能够利用抖音的平台来推广自己的企业微信账号&#xff0c;与用户建立更紧密的沟通和联系…

Xftp连接不上Linux虚拟机的原因解决方法

前言&#xff1a; 在当今数字化时代&#xff0c;远程连接到Linux虚拟机是许多开发者和系统管理员日常工作的一部分。然而&#xff0c;有时候&#xff0c;面对Xftp连接不上Linux虚拟机的问题&#xff0c;我们可能感到困惑和无措。这个看似小问题可能导致工作中断&#xff0c;因…

基于taro搭建小程序多项目框架

前言 为什么需要这样一个框架&#xff0c;以及这个框架带来的好处是什么&#xff1f; 从字面意思上理解&#xff1a;该框架可以用来同时管理多个小程序&#xff0c;并且可以抽离公用组件或业务逻辑供各个小程序使用。当你工作中面临这种同时维护多个小程序的业务场景时&#xf…