按照android文檔,Android 4.3 及更高版本,init、vold和recovery所用到的都是/fstab.<device>
文件。可是在AndroidO 的中,彷佛發生了變化。node
在fsmgr
中,fstab 的來源有兩個,一個是device tree
中指定,另外一個則是從fstab.<device>
文件中加載。這兩個來源的中的fstab配置最終會被合併到一塊兒。android
fstab 文件c++
能夠看出,AndroidO中配置 fstab
文件的地方有三個: /odm/etc/
、/vendor/etc/
和/
,優先級由大變小。shell
fstab.
中的 device 值就是屬性 ro.boot.hardware 的值,若是沒有配置該屬性,就會去/proc/cmdline中讀取hardware的值,還讀不到就去查找 device tree。 app
在Rockchip平臺上,fstab.rk30board直接保存到了根目錄。不太清楚爲啥不按照安卓標準,放在
/vendor/etc
目錄下面額。函數
設備樹中的配置ui
經過查看RK339的設備樹文件,能夠看到system
和vendor
分區的配置是在設備樹中配置的。code
fstab的基本格式以下:ip
<src> <mnt_point> <type> <mnt_flags> <fs_mgr_flags>
src
: sysfs(/sys
)下能夠的設備的路徑。路徑必須以/
開頭,設備的實際路徑是/sys$(src)
。mnt_point
: 設備掛載路徑。type
: 該設備的上的卷的文件類型。mnt_flags
:Vold會忽略該字段,因此,對於由vold管理的設備,該字段能夠設置爲defaults
fs_mgr_flags
:fs_mgr_flags
:Vold
會忽略此字段中不包含 voldmanaged=
標記的統一的 fstab 中的任何行。該標記必須後跟描述卡的標籤,以及分區號或字詞 auto
。例如:voldmanaged=sdcard:auto
。fs_msg中,使用 struct fstab
來表示fstab文件中的數據,使用struct fstab_rec
來表示fstab中的每一條記錄。內存
struct fstab { int num_entries; // fstab中的記錄數 struct fstab_rec* recs; // fstab中的全部條目 char* fstab_filename; // fstab的文件路徑 }; struct fstab_rec { char* blk_device; // 對一個 <src> char* mount_point; // 對應 <mnt_point> char* fs_type; // 對應 <type> unsigned long flags; // 對應 <mnt_flags> char* fs_options; // <mnt_flags>中未記錄在struct flag_list mount_flags中的字段 int fs_mgr_flags; // 對應 <fs_mgr_flags> // ----------------------------------------------------- char* key_loc; char* key_dir; char* verity_loc; long long length; // length= char* label; // voldmanaged=sdcard:3 label=sdcard int partnum; // voldmanaged=sdcard:3 partnum = 3 auto partnum = 1 int swap_prio; // swapprio= int max_comp_streams; unsigned int zram_size; uint64_t reserved_size; unsigned int file_contents_mode; unsigned int file_names_mode; unsigned int erase_blk_size; unsigned int logical_blk_size; };
struct fstab_rec
的前6個,就分別對應fstab中記錄項。後面的就是記錄fs_mgr_flags
中的參數的值。
struct fstab_rec->fs_options
比較特殊,其記錄的是mnt_flags
中,未記錄的參數類型。當執行mount的時候,他將直接做爲參數傳遞過去。static struct flag_list mount_flags[] = { { "noatime", MS_NOATIME }, { "noexec", MS_NOEXEC }, { "nosuid", MS_NOSUID }, { "nodev", MS_NODEV }, { "nodiratime", MS_NODIRATIME }, { "ro", MS_RDONLY }, { "rw", 0 }, { "remount", MS_REMOUNT }, { "bind", MS_BIND }, { "rec", MS_REC }, { "unbindable", MS_UNBINDABLE }, { "private", MS_PRIVATE }, { "slave", MS_SLAVE }, { "shared", MS_SHARED }, { "defaults", 0 }, { 0, 0 }, };
實際解析過程就是逐行解析,而後分割字符串。沒啥好記錄的,代碼太長就不貼了。能夠看一下解析函數:
static struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file) { // [1] 統計行數 // [2] 分配 fstab 內存和 fstab_rec 內存 // [3] 逐行解析 }
內核DTS中的配置,最終都會在目錄/proc/device-tree
下體現,android也有一些自有配置,其目錄是/proc/device-tree/firmware/android
。其中fstab就記錄在該目錄下(完整目錄就是/proc/device-tree/firmware/android/fstab
)。
結合前面的 DTS截圖,最終fstab生成的目錄結構以下:
/proc/device-tree/firmware/android/fstab/ system status dev type mnt_flags fsmgr_flags vendor status dev type mnt_flags fsmgr_flags
fs_mgr對其的解析過程就是遍歷/proc/device-tree/firmware/android/fstab/
,一次讀取其每一個子目錄的全部節點數據,每一個目錄構建成一個<dev> <mnt_point> <type> <mnt_flags> <fsmgr_flags>\n
形式的字符串。而後拼接。
最後,將read_fstab_from_dt
返回的字符串轉換成FILE*
調用函數fs_mgr_read_fstab_file
完成解析。
前面提到fs_mgr會將fstab文件和DTS中的配置信息合併。合併過程也很簡單,就是建立一片內存,將兩個部分的數據拷貝過去。
若是 fstab文件和 DTS 中的 配置項存在重複,fs_mgr 是怎麼處理。