1. 程式人生 > >[日更-2019.5.22、23] Android 系統的分割槽和檔案系統(二)--Android 檔案系統中的檔案

[日更-2019.5.22、23] Android 系統的分割槽和檔案系統(二)--Android 檔案系統中的檔案

宣告

  • 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,限制應用的操作域
sepolicySELinux 策略設定編譯後的結果
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 分割槽是所有使用者個人資料的存放地點:

  1. 系統升級和恢復時會擦除或者重寫整個/system分割槽,但不會以任何方式影響使用者資料。通過格式化/data分割槽,可以快速重置裝置,並擦除所有使用者個人資料。

  2. 在使用者需要時,/data可以被加密起來。加密,不論怎麼優化,由於在讀寫過程中分別要進行解密和加密操作,所以總會在一定程度上增加系統延遲。在設計上,/system分割槽中沒有敏感資料,所以也就沒有必要加密這個分割槽。

  3. /data也可以被設為不可執行(用noexec引數mount該分割槽,或者強制執行SELinux)。能加大惡意軟體的攻擊難度。因為,這樣惡意軟體就沒有一個可寫又可執行的分割槽,讓它能把惡意的可執行檔案寫在該分割槽中然後再執行了。因為DEX和OAT是執行在虛擬機器裡的,所以這對正常的Dalvik/ART APP不會有任何影響。

  4. /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檔案系統中的目錄/檔案介紹