標籤:android 磁碟 vold volume vold.fstab
這段時間為了把mmc的一個block當成sdcard內建,學習了下android的vold磁碟掛載模組,記錄一下(android 4.2.2)。
撰寫不易,轉載請註明出處:http://blog.csdn.net/jscese/article/details/38068441
一:Vold的編譯及啟動
vold的源碼位置在android根目錄 /system/vold檔案下,先看這下面的android.mk:
common_src_files := VolumeManager.cpp CommandListener.cpp VoldCommand.cpp NetlinkManager.cpp NetlinkHandler.cpp Volume.cpp DirectVolume.cpp logwrapper.c Process.cpp Ext4.cpp Fat.cpp Loop.cpp Devmapper.cpp ResponseCode.cpp Xwarp.cpp cryptfs.c...LOCAL_MODULE:= voldLOCAL_SRC_FILES := main.cpp $(common_src_files)LOCAL_C_INCLUDES := $(common_c_includes)LOCAL_CFLAGS := -Werror=formatLOCAL_SHARED_LIBRARIES := $(common_shared_libraries)LOCAL_STATIC_LIBRARIES := libfs_mgrinclude $(BUILD_EXECUTABLE)...
最終會在out 工程目錄下的system/bin 下產生一個android可執行檔vold!
關於編譯還有個地方需要注意,就是vold機制將會解析的設定檔vold.fstab 這個檔案的編譯配置在/system/core/rootdir/Android.mk中:
ifeq ($(TARGET_PRODUCT),full)copy_from += etc/vold.fstabendififeq ($(TARGET_PRODUCT),full_x86)copy_from += etc/vold.fstabendififeq ($(TARGET_PRODUCT),full_mips)copy_from += etc/vold.fstabendif
需要需要vold.fstab,或者想添加自己的設定檔,可以在這裡添加自己的TARGET_PRODUCT,編譯進系統,供vold解析使用。
在/system/core/rootdir/init.rc 中作為服務進程啟動,關於init.rc在android啟動的作用可參考Android——啟動過程詳析
service vold /system/bin/vold class core socket vold stream 0660 root mount ioprio be 2
關於init.rc的文法規則可參考
/system/core/init/readme.txt,其中:
class <name> Specify a class name for the service. All services in a named class may be started or stopped together. A service is in the class "default" if one is not specified via the class option....socket <name> <type> <perm> [ <user> [ <group> ] ] Create a unix domain socket named /dev/socket/<name> and pass its fd to the launched process. <type> must be "dgram", "stream" or "seqpacket". User and group default to 0.
二:Vold入口
在上面通過init啟動這個守護進程,入口為/system/vold/main.cpp中的main函數:
int main() {VolumeManager *vm;CommandListener *cl;NetlinkManager *nm;SLOGI("Vold 2.1 (the revenge) firing up");mkdir("/dev/block/vold", 0755);//存放裝置節點/* Create our singleton managers */if (!(vm = VolumeManager::Instance())) {SLOGE("Unable to create VolumeManager");exit(1);};if (!(nm = NetlinkManager::Instance())) {SLOGE("Unable to create NetlinkManager");exit(1);};cl = new CommandListener(); //構造 commandlistener 和其父類的執行個體,註冊commandvm->setBroadcaster((SocketListener *) cl);nm->setBroadcaster((SocketListener *) cl);//設定VolumeManager NetlinkManager 這兩個執行個體裡面 一個發送廣播的變數,通過隱式轉換,變數類型為指向 SocketListener類的指標if (vm->start()) {//沒實際操作SLOGE("Unable to start VolumeManager (%s)", strerror(errno));exit(1);}//解析上面說到過的 vold.fstab 這樣的設定檔,然後將解析到的內容建立抽象類別(DirectVolume)的執行個體,然後儲存到VolumeManager 中的一個容器中,後備使用if (process_config(vm)) {SLOGE("Error reading configuration (%s)... continuing anyways", strerror(errno));}if (nm->start()) {//建立用於接收kernel的socket,執行個體化NetlinkHandler以及父類執行個體,開啟socket檢測SLOGE("Unable to start NetlinkManager (%s)", strerror(errno));exit(1);}coldboot("/sys/block");//遍曆所有裝置資訊,全部發送一個add 的uevent// coldboot("/sys/class/switch");/** Now that we're up, we can respond to commands*/if (cl->startListener()) {//開啟vold 的socket以及檢測SLOGE("Unable to start CommandListener (%s)", strerror(errno));exit(1);}// Eventually we'll become the monitoring threadwhile(1) {sleep(1000);}SLOGI("Vold exiting");exit(0);}
VolumeManager 作為Volume的管理類,
CommandListener 作為命令註冊監聽執行相關的類,
NetlinkManager 作為接收kernel uevent事件的類
Vold的主體結構大體就是這樣,往後依次分析各個功能細節以及關聯!