Android 系统的分区和文件系统(4)- Android 伪文件系统

news2024/12/23 5:37:30

声明

  • Android系统中有很多分区,每个分区内的文件系统一般都不同的,使用ADB进入系统/目录下可发现挂载这很多的目录,不同的目录中可来自不同的分区及文件系统;
  • 此篇参考了一些书籍及论文,仅供学习使用。只介绍大概理论,不深究,就足够用了。

1 概述

  “伪文件系统”:指的是这些文件系统没有一个会被存储到物理存储设备上去的,相反它们是直接由内核中的回调函数维护的。当要访问其中的一个文件或目录时,某个对应的内核级处理函数就会被调用。这也意味着,这些文件系统并不真正占用存储空间(在内核所用的内存中,用于存放对应的 inode 和目录数据结构的开销不算)。更进一步说,每次访问伪文件系统中的某个文件或目录都要去调用系统的回调函数,所以这些文件和目录反映出的总是最新的实时更新的数据。由此,讨论伪文件系统中文件的大小是没有意义的,这也就是为什么用 “ls -” 命令看到的这些文件都是空的(或者在旧版本的内核里,是 4KB(即一个内存页大小)的整数倍)的原因。
  注意,由于这些文件都是由内核代码(由整个内核,或者在某些情况下,由某些内核模块) 导出的,所以根据内核版本的不同,这些文件有时也会有所不同,而且文件中的内容(特别是 sysfs 中文件的内容) 也是和硬件紧密相关的。

  大多数伪文件系统中的文件都是以只读权限创建的,因为其用途是提供实时的诊断信息,向用户态程序提供一种使之能够查看一些内核态中原本是不可访问的变量和结构的机制。不过有些文件实际上是可写的,这提供了一种更有用的能力,使得我们在用户态中就能实时地对内核中的数据施加影响。不像在某些基于注册表的系统中,修改配置需要对各种隐藏的而且通常是不公开文档的注册表键和值进行操作那样,对伪文件系统中(允许修改的)文件进行的修改,会立即产生作用,而且还不需要系统重启。事实上这也就是Android 中的 init.rc 脚本的重要功能之一。

2. cgroupfs

  Linux 内核提供了一种重要的资源控制机制,它就是 cgroups。一个 cgroup 就是一个可容纳一个或多个线程的组容器 (container group),它能把组中的所有线程视为一个整体,统一进行操作和策略设置。在 Linux 内核文档中,提供了关于 groups 的相当详尽的文档。为了便于在用户态中能把各个线程放置到不同的组中,cgroups 通过伪文件系统把它们自己导出到用户态中——这使得只需对这些文件进行简单的“写”操作,就能把一个线程添加到某个组中。
  尽管 cgroups 用途广泛,可以以各种不同方式使用,但是在 Android 中却是以一种非常受限的方式使用它的——只用于 CPU 使用计时和线程调度(如下面所示):

hammerhead:/ # mount|grep cgroup
none on /acct type cgroup (rw,relatime,cpuacct)
none on /dev/cpuctl type cgroup (rw,relatime,cpu)

  Bionic 在每个进程启动时,通过/acct 为其设置了 CPU 使用计时器(因此它能应用到系统中所有的进程上)。/sys/fs/cgroup/memory 可以被 ActivityManager(通过 android.os.Process 及其JNI方法 setSwappiness)访问。最后,是 /dev/cpuctl 目录,尽管它位于 dev 目录下,但仍是个由 Android 调度策略安装的 cgroup 目录。在 /init 启动时,它会安装该目录并创建其下的各个子目录—— /dev/cpuctl/tasks 对应系统任务,/dev/cpuctl/apps/tasks 对应运行在前台的应用,/dev/cpuctl/apps/bg_non_interactive/tasks 对应运行在后台的应用,并以此对各个组进行调度。每个组都被分配到一个“共享” CPU 的数值,并被赋予了一个可以运行的时间上限。这样就能防止因有意或无意的错误操作,导致某个进程完全占据整个 CPU 运行时间的情况发生。/dev/cpuctl 的配置是在 /init.rc 中完成的,相关代码如下代码所示:

    # Create cgroup mount points for process groups
    mkdir /dev/cpuctl
    mount cgroup none /dev/cpuctl cpu
    chown system system /dev/cpuctl
    chown system system /dev/cpuctl/tasks
    chmod 0666 /dev/cpuctl/tasks
    write /dev/cpuctl/cpu.rt_period_us 1000000
    write /dev/cpuctl/cpu.rt_runtime_us 950000

3. debugfs

  debugfs 文件系统是用于(输出)内核级的调试信息的。驱动以及类似的子系统可以自由地把驱动的调试信息转储到这个文件系统中。和其他伪文件系统一样,如果文件系统已经被 mount了,大量的调试信息就能像读取其他文件那样被读取出来。
  注意,debugfs 没有必要一定要被 mount 到系统中,而且内核也可以被编译成不支持debugfs 的形式。如果内核支持 debugfs,它就可以用下面这行简单的命令行命令 (通常是在/init.hardware.rc中执行) mount 上来:

mount -t debugfs none /sys/kernel/debug
hammerhead:/ # mount |grep debug
debugfs on /sys/kernel/debug type debugfs (rw,seclabel,relatime)

  尽管理论上可以把它 mount 到任意一个 mount 点上,但是因为它实在是太有用了,所以通常都能在“/”目录中找到它的符号链接。比如,在模拟器镜像中,就有一个“/d”符号链接指向 debugfs的mount 点。

hammerhead:/ # ls d -al
lrwxrwxrwx 1 root root 17 1970-01-01 08:00 d -> /sys/kernel/debug

  debugfs 中的内容是完全由内核的版本以及内核中实现了哪些 debug 特性决定的。下表给出的是在各个版本的 Android 内核中常见的几个文件/目录。

文件/目录用途
binder提供通过Android IPC(进程间通信)机制中的 binder 方式传递的大量数据
tracing提供由 Linux 内核的 ftrace 机制产生的海量的调试和跟踪信息
wakeup-sources内核级的定时器,用在Android 系统或驱动程序防止设备休眠

4. functionfs(/dev/usb-ffs/adb)

  在 Android 系统中,USB 的功能经常会需要根据用户的选择 (是以USB 调试、大容量存储介质、以其他方式连接设备,用户的这一选择将通过 init 传递进来) 动态地进行重新配置,它是由一个特定的 “gadget” 驱动进行控制的。
  传统的驱动程序(Android L之前的内核版本)需要通过 sysfs 出它的重新配置参数。这做法是它被认为非常臃肿,并需要改进的原因之一。
  functionfs 的引入:在2010 年某个时候,一个相对较新的特性被引入 Linux内核一一由 Linux内核提供一个通用的文件系统,使驱动能够获取用户态空间中发出的对配置修改的请求。这一文件系统可以被认为是对 sysfs 的一个补充,只不过设计后者的目的是向用户态输出一些内核中的变量和驱动信息,而前者的设计目的是从用户态获取输入。root 用户可以使用 mkdir(2)创建目录,这会引起内核创建相应的内核对象,这些对象可以在稍后由在用户态中发起的、对目录中的伪文件进行的 write(2) 操作予以初始化。

  我的Nexus 5 LineageOS 14.1手机中并未采用:

hammerhead:/ # mount|grep function
1

5. procfs(/proc)

  procfs 文件系统名副其实一一它提供了一个基于目录的观察系统中运行的进程的方式。Linux实现它,使之能提供大量关于进程、线程以及其他全方位的系统诊断信息。
  不论在 /proc 中提供太多东西到底是不是件好事,这都不妨碍它成为一个极为重要的文件系统。许多 Linux 实用程序(top、netstat、lsof 和 ifconfig)以及许多 Android 工具(procrank、librank)都把它作为诊断信息的来源,没有它就不能运行。

6. 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,让我们能在用户态中读取到这些数据。

  我的Nexus 5 LineageOS 14.1手机中并未采用:

hammerhead:/ # mount|grep pstore
1

7. selinuxfs(/sys/fs/selinux)

  和 debugfs 一样,SELinuxFS 传统上也是 mount 在/sys 下,但却不是 sysfs 文件系统的一部分。这个文件系统是专供 SELinux 使用的,其中存储了与安装策略 (installed policy) 相关的文件。关于SELinux可参考此篇:Android 系统的安全性分析(4)–Linux层面上的安全措施。
  这个文件系统中最重要的文件是 policy 和伪文件 enable。其中,policy 提供了加载(编译,可以使用的二进制可执行文件的格式)安全策略,enable 则用来切换这些策略是否要被强制执行(其实 getenforce/setenforce 工具集也是通过它来实现相关功能)

hammerhead:/ # getenforce
Enforcing
hammerhead:/ # echo 0 > /sys/fs/selinux/enforce
hammerhead:/ # getenforce
Permissive

8. sysfs

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

  不同的设备之间硬件配置的差异非常大,所以各种不同设备中的 sysfs 里存放的文件间的差别也非常大。Android 框架之所以能够免于受到因不同厂商选用不同的五花八门的硬件而带来的麻烦,完全要感谢硬件抽象层(HAL,Hardware Abstraction Layer,它是由/system/lib/libhardware.so及其插件构成的),因为硬件抽象层把对不同特定文件的调用封装成了更为统一的 API。
  其他一些设备的标准化程度要更高一些,比如,位于/sys/devices/system/cpu/cpu#/cpufireq目录中的 CPU 主频调节器(用来调整主频) 数据,以及供震动器器使用的/sys/class/timed output/vibrator 目录。

  执行如下命令,手机震动器会持续震动3秒。

hammerhead:/ # echo 3000 > /sys/class/timed_output/vibrator/enable
hammerhead:/ #

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

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

相关文章

Valarrays

C标准库提供了一个class valarray用以进行数值数组的运算。 它声明于头文件<valarray> namespace std{template<class T> class valarray; //numeric array of type Tclass slice;template<class T> class slice_array; //slice out of a valarrayclass gs…

Java经典笔试题—day03

Java经典笔试题—day03 &#x1f50e;选择题&#x1f50e;编程题&#x1f95d;字符串中找出连续最长的数字串&#x1f95d;数组中出现次数超过一半的数字 &#x1f50e;结尾 &#x1f50e;选择题 (1)以下代码运行输出的是 public class Person{private String name "Pe…

怎么洗稿容易过稿-在线洗稿软件

自媒体洗稿软件 即使您是一位优秀的自媒体写作人员&#xff0c;也难免遇到让人头疼的撰写问题&#xff0c;例如无法处理大量原始文本、需要手动删除冗余信息、缺少时间针对每篇文章进行深入修改等问题。但是&#xff0c;现在有了我们的一款自媒体洗稿软件&#xff0c;您再也不需…

Android System crash DeadSystemException(Service/Activity/终极解决方案)

DeadSystemException&#xff1a; The core Android system has died and is going through a runtime restart. All running apps will be promptly killed. Android 核心系统服务已经死亡&#xff0c;正在重启中。全部正在运行的app即将被kill杀死。 更多请阅读&#xff0c;D…

Lecture 11:How versatile are self-supervised models

目录 Story 1: Cross-lingual Story 2: Cross-discipline Story 3: Pre-training with artificial data &#xff08;story1和story2的内容在前面课程中有讲过&#xff0c;这里笔记部分不再详述&#xff09; Story 1: Cross-lingual 多语言BERT具有跨语言的能力&#xff0…

Linux-Day01

Linux-Day01 课程内容 Linux简介Linux安装Linux常用命令 1. 前言 1.1 什么是Linux Linux是一套免费使用和自由传播的操作系统。说到操作系统&#xff0c;大家比较熟知的应该就是Windows和MacOS操作系统&#xff0c;我们今天所学习的Linux也是一款操作系统。 1.2 为什么要学…

12.IO流

1.字符流 1.1为什么会出现字符流【理解】 字符流的介绍 由于字节流操作中文不是特别的方便&#xff0c;所以Java就提供字符流 字符流 字节流 编码表 中文的字节存储方式 用字节流复制文本文件时&#xff0c;文本文件也会有中文&#xff0c;但是没有问题&#xff0c;原因是最…

消息队列中的事务消息

大家好&#xff0c;我是易安&#xff01;今天我们谈一谈消息队列中的事务消息这个话题。 一说起事务&#xff0c;你可能自然会联想到数据库。我们日常使用事务的场景&#xff0c;绝大部分都是在操作数据库的时候。像MySQL、Oracle这些主流的关系型数据库&#xff0c;也都提供了…

Java --- springboot2之异常处理

仅供参考 目录 一、异常处理 二、异常处理自动配置原理 三、异常处理流程 四、定制错误处理逻辑 4.1、自定义错误页 4.2、ControllerAdviceExceptionHandler处理全局异常 4.3、ResponseStatus自定义异常 4.4、Spring底层的异常&#xff0c;如 参数类型转换异常 4.5、自定义…

7种常见网络并发模型介绍

概述 对于网络服务器后端开发&#xff0c;为满足不同并发场景的需要&#xff0c;一般来说&#xff0c;不外乎几种常见的并发模型&#xff0c;除了一些教学场景常用的单线程、多进程&#xff08;线程&#xff09;的服务器实现外&#xff0c;生产用的服务器&#xff0c;一般都会…

Linux多路IO复用:epoll

1. epoll epoll是为克服select、poll每次监听都需要在用户、内核空间反复拷贝&#xff0c;以及需要用户程序自己遍历发现有变化的文件描述符的缺点的多路IO复用技术。 epoll原理 创建内核空间的红黑树&#xff1b; 将需要监听的文件描述符上树&#xff1b; 内核监听红黑树上…

实验室设备管理系统

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 应用背景 为方便实验室进行设备管理&#xff0c;某大学拟开发实验室设备管理系统 来管理所有实验室里的各种设备。系统可实现管理员登录&#xff0c;查看现有的所有设备&#xff0c; 增加设备等功能。 开发环境 Mac OS PyCha…

JAVA:Springboot 装配数据库Hikari和Druid连接池

1、JDBC Java数据库连接&#xff08;Java Database Connectivity&#xff0c;简称JDBC&#xff09;是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口&#xff0c;提供了诸如查询和更新数据库中数据的方法。 JDBC API主要位于JDK中的java.sql包中&#xff08;之后…

出现小红书点赞多粉丝少的情况,原因在哪里

刚开始运营自己账号的小伙伴们有时发现明明笔记点赞数量不少&#xff0c;但偏偏账号粉丝数量就是一直不怎么涨&#xff0c;像这样小红书点赞多粉丝少是怎么回事呢?今天就来说说&#xff0c;小红书该如何吸引用户关注。 一、小红书点赞多粉丝少是怎么回事 一般来说&#xff0c;…

从MIMIC学习组织自己的数据

从MIMIC学习组织自己的数据 相对于SEER数据库&#xff08;我们得到的是几乎可以直接进行分析的数据&#xff09;&#xff0c;MIMIC 数据库在数据采集后虽然经过了一定的处理&#xff0c;但是保留了数据库原始的样貌&#xff0c;所以我们除了对MIMIC数据进行分析外&#xff0c;…

推荐算法之DeepFM

论文&#xff1a;DeepFM: A Factorization-Machine based Neural Network for CTR Prediction Github&#xff1a;https://github.com/ChenglongChen/tensorflow-DeepFM https://github.com/shenweichen/DeepCTR IJCAI2017 本文将深度神经网络dnn和因式分解机Factorization-M…

程序中各种异常报错,对于JVM调优记录

一&#xff1a;GC overhead limit exceeded 数据量过大&#xff1a;当应用程序处理大量的数据时&#xff0c;会占用大量的内存和计算资源。如果内存资源不足&#xff0c;则可能会在垃圾回收过程中出现 GC overhead limit exceeded 错误 程序代码有问题&#xff1a;如果 应用程…

Vmware虚拟机问题解决方案

Vmware虚拟机问题解决方案 1. 运行虚拟机系统蓝屏 可能的原因有两个: 1). 虚拟机所在磁盘的空间不足 ; -------> 清理磁盘空间 。 2). 操作系统版本高, 需要适配新版本的Vmware ; ------> 卸载Vmware15版本, 安装Vmware16版本 。 2. 卸载Vmware步骤 1). 卸载已经安…

商用密码产品认证中的随机数(一)

1 商密认证中的随机数介绍 如果说密钥的安全是密码产品的基石&#xff0c;那随机数的安全就是密钥安全的基石。密码产品设计和商用密码产品认证中&#xff0c;随机数的合规性也是需要重点关注的环节。 随机数的合规性主要包括&#xff1a; 随机数的来源合规。如果是自行设计的…

一点通路由模拟实验8

首先先设置hostA和hostB和hostC的ip 其次设置路由接口的各个ip 路由A 像这样的&#xff0c;再设置路由B 唯一要记住的是&#xff0c;时钟只要设置一个就行 就是clock rate 6400&#xff0c;之后开启路由&#xff1a;ip routing 然后就是查看路由表了&#xff08;路由A&#…