声明
- Android系统中有很多分区,每个分区内的文件系统一般都不同的,使用ADB进入系统/目录下可发现挂载这很多的目录,不同的目录中可来自不同的分区及文件系统;
- 那么,就来分下这些目录里面的文件都是用来做什么的呢?
1 根目录 /
以我的Nexus5 cm-14.1系统启动后的根目录来说:
- hammerhead:/ $ ls -al
- total 1336
- drwxr-xr-x 18 root root 0 1970-04-29 10:11 .
- drwxr-xr-x 18 root root 0 1970-04-29 10:11 ..
- drwxr-xr-x 39 root root 0 1970-04-29 10:11 acct
- lrwxrwxrwx 1 root root 50 1969-12-31 13:00 bugreports -> /data/user_de/0/com.android.shell/files/bugreports
- drwxrwx--- 6 system cache 4096 1970-04-22 10:55 cache
- lrwxrwxrwx 1 root root 13 1969-12-31 13:00 charger -> /sbin/healthd
- dr-x------ 2 root root 0 1969-12-31 13:00 config
- lrwxrwxrwx 1 root root 17 1969-12-31 13:00 d -> /sys/kernel/debug
- drwxrwx--x 40 system system 4096 1970-04-29 10:11 data
- -rw-r--r-- 1 root root 1099 1969-12-31 13:00 default.prop
- drwxr-xr-x 16 root root 4660 2019-04-22 13:01 dev
- lrwxrwxrwx 1 root root 11 1969-12-31 13:00 etc -> /system/etc
- -rw-r--r-- 1 root root 105165 1969-12-31 13:00 file_contexts.bin
- dr-xr-x--- 3 system system 16384 1969-12-31 13:00 firmware
- -rw-r----- 1 root root 3177 1969-12-31 13:00 fstab.hammerhead
- -rwxr-x--- 1 root root 862244 1969-12-31 13:00 init
- -rwxr-x--- 1 root root 10216 1969-12-31 13:00 init.cm.rc
- -rwxr-x--- 1 root root 1054 1969-12-31 13:00 init.environ.rc
- -rwxr-x--- 1 root root 161 1969-12-31 13:00 init.hammerhead.diag.rc
- -rwxr-x--- 1 root root 14600 1969-12-31 13:00 init.hammerhead.rc
- -rwxr-x--- 1 root root 6534 1969-12-31 13:00 init.hammerhead.usb.rc
- -rwxr-x--- 1 root root 26066 1969-12-31 13:00 init.rc
- -rwxr-x--- 1 root root 12058 1969-12-31 13:00 init.usb.configfs.rc
- -rwxr-x--- 1 root root 5715 1969-12-31 13:00 init.usb.rc
- -rwxr-x--- 1 root root 411 1969-12-31 13:00 init.zygote32.rc
- drwxr-xr-x 10 root system 220 1970-04-29 10:11 mnt
- drwxr-xr-x 2 root root 0 1969-12-31 13:00 oem
- drwxr-xr-x 10 root root 4096 1969-12-31 13:19 persist
- dr-xr-xr-x 204 root root 0 1969-12-31 13:00 proc
- -rw-r--r-- 1 root root 5055 1969-12-31 13:00 property_contexts
- drwxr-xr-x 3 root root 0 1969-12-31 13:00 res
- drwx------ 2 root root 0 2019-02-25 20:47 root
- drwxr-x--- 2 root root 0 1969-12-31 13:00 sbin
- lrwxrwxrwx 1 root root 21 1969-12-31 13:00 sdcard -> /storage/self/primary
- -rw-r--r-- 1 root root 758 1969-12-31 13:00 seapp_contexts
- -rw-r--r-- 1 root root 80 1969-12-31 13:00 selinux_version
- -rw-r--r-- 1 root root 203329 1969-12-31 13:00 sepolicy
- -rw-r--r-- 1 root root 12206 1969-12-31 13:00 service_contexts
- drwxr-xr-x 4 root root 80 2019-04-22 10:11 storage
- dr-xr-xr-x 12 root root 0 1970-04-29 10:11 sys
- drwxr-xr-x 17 root root 4096 1969-12-31 13:00 system
- -rw-r--r-- 1 root root 2204 1969-12-31 13:00 ueventd.hammerhead.rc
- -rw-r--r-- 1 root root 4857 1969-12-31 13:00 ueventd.rc
- lrwxrwxrwx 1 root root 14 1969-12-31 13:00 vendor -> /system/vendor
Android的根文件系统/是mount自一个RAMDisk(initramfs)。每次启动时,启动加载器(fastboot)从boot分区中把这个文件系统的镜像加载到内存(RAM)中,井把它交给内核管理。
/中的目录或文件 | 作用 |
---|---|
default.prop | 其中记录的是编译时/build/core/main.mk 中ADDITIONAL_DEFAULT_PROPERTIES变量中的值,init将根据它去加载其他系统范围内的属性文件(property)。加载只读的属性文件有利于强制执行安全保护。 |
init | 内核启动后首先启动的1号进程 |
init.*.rc | /init的配置文件,一些设备或厂商还提供几个额外的配置文件 |
file_contexts | 记录SE-Linux中的文件context,用于限制非授权用户访问系统文件和目录 |
property_contexts | 记录SE-Linux中的系统属性的context,用于限制非授权用户访问系统属性 |
seapp_contexts | 记录SE-Linux中的应用的context,限制应用的操作域 |
sepolicy | SELinux 策略设置编译后的结果 |
sbin/ | 该目录中含有adbd、healthd以及recovery(即使不能mount /system,系统也需要recovery)等关键二进制可执行文件。该目录中可能还含有厂商提供的二进制可执行文件 |
verity_key | 含有认证/system分区时所需的DM_Verity RSA 密钥 |
2 /system分区
以只读模式mount上来的/system分区中存放的是Android重要组件,它们的所属的用户及组基本都是root,权限基本上也是0755。由于文件系统是以只读方式mount的,所以其中Android系统组件就不会受到破坏和修改。
- 127|hammerhead:/system $ ls -al
- total 88
- drwxr-xr-x 17 root root 4096 1969-12-31 13:00 .
- drwxr-xr-x 18 root root 0 1970-04-29 10:11 ..
- drwxr-xr-x 2 root root 4096 2019-02-25 21:18 addon.d
- drwxr-xr-x 43 root root 4096 2019-02-25 21:31 app
- drwxr-xr-x 2 root shell 8192 2019-04-14 20:49 bin
- -rw-r--r-- 1 root root 4768 2019-04-14 20:49 build.prop
- drwxr-xr-x 17 root root 4096 2019-04-14 20:49 etc
- drwxr-xr-x 2 root root 4096 2019-02-25 21:36 fake-libs
- drwxr-xr-x 2 root root 8192 2019-02-25 21:36 fonts
- drwxr-xr-x 2 root root 4096 2019-02-25 21:44 framework
- drwxr-xr-x 5 root root 12288 2019-02-25 21:44 lib
- drwx------ 2 root root 4096 1969-12-31 13:00 lost+found
- drwxr-xr-x 3 root root 4096 2019-02-25 21:44 media
- drwxr-xr-x 55 root root 4096 2019-02-25 21:43 priv-app
- drwxr-xr-x 3 root root 4096 2019-02-25 21:44 tts
- drwxr-xr-x 8 root root 4096 2019-02-25 21:44 usr
- drwxr-xr-x 6 root shell 4096 2019-02-25 21:44 vendor
- drwxr-xr-x 2 root shell 4096 2019-04-14 20:49 xbin
有些厂商用闪存分区写保护的方式来保证/system是readonly的。所以即使用mount -o remount命令重新mount /system分区,对它所做的任何修改也不会生效,它依然会是readonly的。从Android 5 开始/system分区采用Linux内核中的dm-verity特性保护/system分区的完整性。看下其中内容(网上盗图):
2.1 /system/bin目录
其中存放Android系统原生可执行文件及各种调试工具,被分为五类: 用于提供服务的二进制可执行文件、调试工具、UNIX 命令、调用Dalvik 的脚本、厂商定制的二进制可执行文件。
2.1.1 用于提供服务的elf文件(盗图一张)
2.1.2 调试工具(盗图一张)
2.1.3 UNIX命令
就是这个toolbox,因为在/system/bin中执行ls -al,就可以发现很多UNIX命令都是toolbox的软连接:
- hammerhead:/system/bin $ ls -al
- drwxr-xr-x 2 root shell 8192 2019-04-14 20:49 .
- drwxr-xr-x 17 root root 4096 1969-12-31 13:00 ..
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 bzcat -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 cal -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 cat -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 chattr -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 chcon -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 chgrp -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 chmod -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 chown -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 chroot -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 chrt -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 cksum -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 echo -> toybox
- lrwxr-xr-x 1 root shell 4 2019-02-25 21:34 egrep -> grep
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 env -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 expand -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 expr -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 fallocate -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 false -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 fdisk -> toybox
- lrwxr-xr-x 1 root shell 4 2019-02-25 21:34 fgrep -> grep
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 file -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 find -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 flock -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 free -> toybox
- lrwxr-xr-x 1 root shell 6 2019-04-14 20:49 freeramdisk -> toybox
- ...
2.1.4 调用Dalvik的脚本
这些调用Dalvik的脚本让用户通过shell与Dalvik运行时框架交互,这多半是为了进行调试。这些脚本调用/system/bin/app_process,用它们在/system/framework目录中的同名JAR框架,加载Dalvik类,并在使用时,脚本会把用户传给它的参数直接传递给Dalvik类。比如下面的am、pm命令:
- hammerhead:/system/bin $ cat am
- #!/system/bin/sh
- #
- # Script to start "am" on the device, which has a very rudimentary
- # shell.
- #
- base=/system
- export CLASSPATH=$base/framework/am.jar
- exec app_process $base/bin com.android.commands.am.Am "$@"
- hammerhead:/system/bin $ cat pm
- #!/system/bin/sh
- # Script to start "pm" on the device, which has a very rudimentary
- # shell.
- #
- base=/system
- export CLASSPATH=$base/framework/pm.jar
- exec app_process $base/bin com.android.commands.pm.Pm "$@"
再盗张图看下:
2.1.5 厂商定制的elf文件
厂商可以自己添加一些自己需要的elf文件(通常时闭源的),用于特殊的目的,我也经常在系统中内置一些守护进程的elf文件,用于系统启动时由init.rc启动。
2.2 /system/xbin
/system/xbin目录类似于UNIX中的/sbin目录,其中含有管理员会觉得非常有用的二进制可执行文件。这个目录中的二进制可执行文件是从AOSP的system/extras目录中编译得来的。因为这个目录不是普通操作所必须的,所以这个目录中的elf文件经常被厂商裁剪。再参考网上图:
2.3 /system/lib、/system/lib64
系统中所有的运行时库都在里面了。
2.4 /system/etc
/system/etc目录中也存放着各种配置文件,参考下网上一张图:
3 /data分区
/data 分区是所有用户个人数据的存放地点:
-
系统升级和恢复时会擦除或者重写整个/system分区,但不会以任何方式影响用户数据。通过格式化/data分区,可以快速重置设备,并擦除所有用户个人数据。
-
在用户需要时,/data可以被加密起来。加密,不论怎么优化,由于在读写过程中分别要进行解密和加密操作,所以总会在一定程度上增加系统延迟。在设计上,/system分区中没有敏感数据,所以也就没有必要加密这个分区。
-
/data也可以被设为不可执行(用noexec参数mount该分区,或者强制执行SELinux)。能加大恶意软件的攻击难度。因为,这样恶意软件就没有一个可写又可执行的分区,让它能把恶意的可执行文件写在该分区中然后再执行了。因为DEX和OAT是运行在虚拟机里的,所以这对正常的Dalvik/ART APP不会有任何影响。
-
/data目录下基本都是system system 0771的,意思是对所有的应用来说目录是可执行但不可读的,这样的话shell就无法使用ls这样的命令查看data下的内容。
继续盗图,看下/data分区中的目录:
3.1 /data/data目录
/data/data目录本身的权限设置为chmod 771 system system,这使得所有的应用都能列出其中的子目录,但却不能读取除了system拥有的应用外的其他数据。不过应用中,文件的安全防护措施的设置还是要交给每个应用自己来完成,因为尽管除了应用的拥有者外,其他人都不能读取各个应用目录中的内容,但是这些应用目录本身还是可执行的。/data/data下各个应用的子目录是各个应用在整个文件系统中唯一能写入数据的地方。
3.2 /data/misc目录
其中含有各个Android子系统的各种数据和配置目录:
3.3 /data/system目录
含有对维护设备状态非常重要的文件:
4 /cache分区
系统升级的过程中使用/cache分区的。系统升级包会被下载到这里,启动管理器(boot manager)特别是在recovery升级模式下启动时,会要使用这个分区。但除此之外,在正常情况下,这个分区是空的。如果你最近下载过OTA升级包, 在它被安装之前,你都能在这个分区里看到它。另外,recovery这个elf文件和系统(特别是android.os.RecoverySystem类)在启动到recovery(或系统升级)模式时,也会使用这个分区交换信息。
5 /vendor 目录
/vendor目录是用来存储厂商对Android系统的修改。这样做是为了在必要时能有效地进行系统的更新或升级操作(同时不至于把厂商对系统的修改一起擦除)。专门指定的系统组件在添加/system路径之前时,会先去检查事先被写死在程序中的/vendor中的路径,具体哪些组件会去检查哪些路径,如下表所示:
Enjoy it
Android文件系统中的目录/文件介绍大概就这些了。