1.Vold (Volume Daemon)介紹
vold進程接收來自內核的外部設備消息,用於管理和控制Android平台外部存儲設備,包括SD插撥、掛載、卸載、格式化等;當外部設備發生變化時,內核通過Netlink發送uEvent格式的消息給用戶空間程序, Netlink是一種基於異步通信機制,在內核與用戶應用間進行雙向數據傳輸的特殊socket,用戶態應用使用標準的socket API就可以使用netlink提供的強大功能;
2.Vold 框架設計
Vold是native程序,用於管理和控制Android平台外部存儲設備的管控中心,是一個後台運行的進程。它與Java層的MountService交互,Vold接收來自kernel的uevent消息,然後向上層轉發,MountService接收來自vold的消息,同時也可以向vold發送控制命令。從以上Vold設計框架圖中可以看到,Vold有三個模塊,分別為NetlinkManager,VolumeManager,CommandListener。
NetlinkManager模塊專門接收來自Linux內核uevent消息,並將消息轉發給VolumeManager處理,VolumeManager模塊接著又把相關信息通過CommandListener發送給MountService,MountService根據收到的消息會發送相應的處理命令給VolumeManager,VolumeManager接收到命令後直接對外部存儲設備進行操作。
CommandListener模塊內部封裝良一個Socket用於跨進程通信,Java層的客戶端MountService就是通過該Socket和服務端Vold進行通信的。
1.Netlink介紹
Netlink是Linux系統中用戶空間進程和Kernel進行通信的一種機制,用戶空間進程可以接收來自Kernel的消息,同時也可以向Kernel發送一些控制命令。LINUX netlink機制一文中詳細介紹了Netlink的用法。
2.Uevent介紹
uevent和Linux的設備文件系統及設備模型有關,是sysfs向用戶空間發送的消息。消息格式實際上是一串字符串。當外部設備發生變化時,會引起Kernel發送Uevent消息;一般設備在/sys對應的目錄下有個叫uevent的文件,往該文件裡寫入指定數據,也會觸發Kernel發送和該設備相關的uevent消息,內核通過uevent告知外部存儲系統發生的變化。
3.Vold 源碼分析
\ SYSTEM \的vold \ main.cpp中
/etc/vold.fstab的內容如下:
4.Vold各模塊分析
前面介紹了Vold包含NetlinkManager,VolumeManager,CommandListener三大模塊,他們之間的關係如下:
接下來就分別針對每個模塊進行詳細分析。
1.NetlinkManager模塊
NetlinkManager模塊接收從Kernel發送的Uevent消息,解析轉換成NetlinkEvent對象;再將此NetlinkEvent對像傳遞給VolumeManager處理。
啟動流程
1)構造NetlinkManager實例:nm = NetlinkManager::Instance()
2)設置事件廣播監聽:nm->setBroadcaster((SocketListener *) cl)
3)啟動NetlinkManager:nm->start()
1)構造NetlinkManager實例:nm = NetlinkManager::Instance()
2)設置事件廣播監聽:nm->setBroadcaster((SocketListener *) cl)
3)啟動NetlinkManager:nm->start()
構造NetlinkManager實例
啟動NetlinkManager
在啟動NetlinkManager時,初始化socket用於創建NetlinkManager的屬性變量mHandle實例,並啟動NetlinkHandler,NetlinkHandler繼承於NetlinkListener,NetlinkListener又繼承於SocketListener,因此在構造NetlinkHandler實例時首先構造SocketListener及NetlinkListener,構造NetlinkListener對象的父類對象SocketListener:
NetlinkListener構造函數:
NetlinkHandler構造函數:
因此構造NetlinkHandler實例過程僅僅創建良一個socket客戶端連接。
NetlinkHandler開始:
SocketListener開始:
SocketListener 線程消息循環:
在消息循環中調用onDataAvailable處理消息,onDataAvailable是個虛函數,NetlinkListener重寫了此函數。
將接收的Uevent數據轉化成NetlinkEvent數據,調用onEvent處理,NetlinkListener子類NetlinkHandler重寫了此函數。
NetlinkManager 通過NetlinkHandler將接收到Kernel內核發送的Uenvet消息,轉化成了NetlinkEvent結構數據傳遞給VolumeManager處理,uevent消息的上傳流程:
2.VolumeManager模塊
啟動流程1)構造VolumeManager對象實例
2)設置事件廣播監聽
3)啟動VolumeManager
4)配置VolumeManager
VolumeManager類關係圖:
DirectVolume是一個實體存儲設備的抽象,通過系統調用直接操作存儲設備。VolumeManager的SocketListenner與NetlinkManager的SocketListenner有所不同的:
NetlinkManager構造的SocketListenner:Kernel與Vold通信;
VolumeManager構造的SocketListenner:Native Vold與Framework MountService 通信;
NetlinkManager與VolumeManager交互流程圖:1.構造VolumeManager對象
2.啟動VolumeManager
VolumeManager啟動過程什麼都沒有做。
3.uevent事件處理
前面NetlinkManager模塊中介紹到,NetlinkHandler在onEvent函數中,將NetlinkEvent事件轉交給VolumeManager處理:
每一個Volume可能對應多個Path;即一個掛載點對應多個物理設備,因此VolumeManager中的每一個Volume對像都需要處理SD狀態變換消息,當新增一個disk時:
1.構造CommandListener對象
父類FrameworkListener構造:
直接調用init函數;
SocketListener的構造函數:
同樣調用init函數進行初始化:
構造CommandListener對象過程中,首先註冊了各種命令,並創建良一個socket客戶端連接。命令註冊過程:
將各種命令存放到mCommand列表中。
沒有留言:
張貼留言