【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书:架构大剖析》

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【GitHub项目推荐--Awesome-Go/Python/JavaScript/Java】【转载】

Awesome 译为令人惊叹的、极好的,GitHub 上有很多 Awesome 开头的开源项目。比如 Awesome-Go、Awesome-Python。 就像汇总常用的软件一样,GitHub上有大量的开源项目,开发者就会根据需要汇总一些常用的好用的资源,并且根据 Awesom…

oracle 19c rac集群管理 ------ 日志管理

oracle 19C rac 数据库的目录结构及日志路径 在Oracle 19c RAC(Real Application Clusters)集群中,有多个组件和层级生成的日志文件,记录着集群的活动、事件和错误信息,用于故障诊断、性能优化和集群管理。以下是常见…

nvm安装与使用教程

目录 nvm是什么 nvm安装 配置环境变量 更换淘宝镜像 安装node.js版本 nvm list available 显示可下载版本的部分列表 nvm install 版本号 ​编辑 nvm ls 查看已经安装的版本 ​编辑 nvm use 版本号(切换想使用的版本号) nvm是什么 nvm是node.js version management的…

社区公益培训系统功能说明

社区公益培训系统功能说明 本系统将用于社区面向居民开展的公益培训课程展示,在线报名,并按班级排课上课,上课时学员要扫码签到,经常旷课的学员将禁止再报名其他课程。 1. 用户注册与登录 - 提供用户注册和登录功能,…

【LeetCode】每日一题 2024_1_22 最大交换(模拟)

文章目录 LeetCode?启动!!!题目:最大交换题目描述:代码与解题思路 LeetCode?启动!!! 几百年没有见到题目描述这么短的题目了,泪目了 题目&#x…

LeetCode 48 旋转图像

题目描述 旋转图像 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1: 输入:matrix [[1,2,3],[4…

java.lang.IllegalArgumentException: When allowCredentials is true

1.遇到的错误 java.lang.IllegalArgumentException: When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a…

gif动图怎么快速生成?这一招快速生成

很多从事新媒体行业的小伙伴都知道在编写公众号的时候会插入一些gif动图来增加与读者的互动。很多时候我们使用的动图都是网上下载的。其实,我们是可以自己制作动图的,下面就来教大家一招如何制作gif动态图片(https://www.gif.cn/&#xff09…

C++大学教程(第九版)6.38汉诺塔问题

文章目录 题目代码运行截图 题目 (汉诺塔问题)在这一章中大家了解了既可以用递归方法又可以用迭代方法很容易实现的函数。不过,在这道练习题中,我们提出的问题若用递归来解决,则尽显递归之优雅:若用迭代来实现,恐怕没那么容易。 …

Gold-YOLO(NeurIPS 2023)论文与代码解析

paper:Gold-YOLO: Efficient Object Detector via Gather-and-Distribute Mechanism official implementation:https://github.com/huawei-noah/Efficient-Computing/tree/master/Detection/Gold-YOLO 存在的问题 在过去几年里,YOLO系列已经…

9个提高开发效率的 VS Code技巧

本文就来分享 10 个极大提高开发效率的 VS Code 技巧! 标签换行 在VS Code中,可以在设置中搜索"** Editor: Wrap Tabs**"来实现选项卡换行的功能。 这样,在大型项目中工作时,就不需要像在浏览器中一样滚动来查找选项卡…

springcloud Hystrix断路器

文章目录 代码下载简介写服务测试高并发测试写消费者端测试2 服务降级先修改cloud-provider-hystrix-payment8001修改cloud-consumer-feign-hystrix-order80 目前问题方法2:测试 服务熔断实操测试 服务监控hystrixDashboard建mudlue断路器演示(服务监控hystrixDashboard) 代码下…

Vivado开发FPGA使用流程、教程 verilog(建立工程、编译文件到最终烧录的全流程)

目录 一、概述 二、工程创建 三、添加设计文件并编译 四、线上仿真 五、布局布线 六、生成比特流文件 七、烧录 一、概述 vivado开发FPGA流程分为创建工程、添加设计文件、编译、线上仿真、布局布线(添加约束文件)、生成比特流文件、烧录等步骤&a…

亚马逊店铺的照片因侵权被移除的案例申诉分享

新店上上市公司时因图片侵权被禁售 亲爱的卖方绩效团队, 感谢您关于违反政策的通知,我们想为我们所犯的可怕错误真诚地道歉。我们是 一家专注于对外贸易的小公司,在亚马逊美国销售一直是我们的终极梦想之一。 为了在亚马逊推出我们的商店&…

每日一道算法题 15(2023-12-28)TLV解析Ⅰ

package com.tarena.test.B20; import java.util.ArrayList; import java.util.Scanner; import java.util.StringJoiner; /** * TLV解析Ⅰ * author Administrator * 输入: * 第一行 31 * 第二层 32 01 00 AE 90 02 00 21 02 30 03 00 AB 32 31 31 0…

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

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

CHS_04.2.2.3_2+调度器和闲逛进程

CHS_04.2.2.3_2调度器和闲逛进程 调度器/调度程序(scheduler)闲逛进程 调度器/调度程序(scheduler) 调度器 或者叫调度程序 很简单的一个概念 调度程序是操作系统内核的一个非常非常重要的一个程序模块 我们说一个进程会在就绪运…

Java毕业设计-基于ssm的学生社团活动管理系统-第82期

获取源码资料,请移步从戎源码网:从戎源码网_专业的计算机毕业设计网站 项目介绍 基于ssm的学生社团活动管理系统:前端 jsp、jquery、ajax,后端 springmvc、spring、mybaties,角色分为管理员、学生、社团、用户&#…

Python with Office 054 - Work with Word - 7-9 插入图像 (3)

近日详细学习了寒冰老师的很好的书《让Python遇上Office》,总结了系列视频。 这个是其中的一集:如何在Word中插入图像,我会陆续分享其他的视频并加上相应说明 https://www.ixigua.com/7319498175104942643?logTage9d15418663166a05d10

母线槽是什么?需要进行实时监测吗?

母线(bus line)的定义:指用高导电率的铜(铜排)、铝质材料制成的,用以传输电能,具有汇集并且分配电力的产品。 母线槽(busway/busduct)的定义:由铜、铝母线柱…