开机SD卡加载过程

本文详细介绍了Android系统中SD卡的开机加载、热插拔和关机卸载过程。涉及关键组件如Vold、MountService、NetlinkManager及其交互。开机时,Vold作为守护进程接收底层信息并处理,MountService负责SD卡状态的通知与挂载。关机时,通过ShutdownThread协调MountService完成SD卡的卸载。此外,NetlinkManager监听Linux内核事件,处理热插拔操作。整个过程中,Android系统借助IPC Binder和线程消息传递实现各模块间的协同工作。
摘要由CSDN通过智能技术生成

本文基于android 早期版本 可能是4.4

1. 相关代码目录:

android \system\core\init

android\system\core\libsysutils\src\FrameworkListener.cpp

android \system\vold

android \frameworks\base\services\java\com\android\server

 

2. SD卡开机加载方法和简易流程图

总结起来SD卡加载大概有3种方式:

1.      开机自动加载;

2.      热插拔;

如果手机支持热插拔,底层驱动会将SD卡驱动信息发送给VOLD,VolumeManager 或者Volume类会将处理状态发送给MountService,MountService最后发送状态给APP;

 

3.      通过setting菜单安装

  /*卸载该分区挂载的所有挂载点,这里为什么用所有来形容了,因为Android 系统挂载一个分区的期间,重复挂载在好几个目录,将分区挂载在/mnt/asec目录,也挂载 

   在/mnt/secure/asec目录,也挂载在/mnt/sdcard目录下,总共三次挂载,谷歌不知为什么搞这么复杂? 

   待深究。。*/  

 

这里介绍下开机自动加载的过程,以下是一个简单流程图:



源代码分析:

1.      开机

 

Vold为一守护进程,初始化时,会创建classNetlinkManager和VolumeManager,

Class  NetlinkManager接收来自底层的信息,然后转交给VolumeManager处理;

class VolumeManager 单例模式,它主要负责vold的管理操作

class DirectVolume封装了很多的方法和属性;

class  CommandListener内部封装了一个socket 用来跨进程通信,它在vold 进程中属于监听类,即服务器端,主要收到上层 MountService发来的命令,分析后,转交给VolumeManager处理;VolumeManager处理信息后,或报告给上层MountService

 

关于vold 的其他介绍请参考之前的《SD卡基本功能的原理实现和流程分析》。

 

system\core\init\init.c

Init .c通过加载Init.rc文件初始化Vold 模块和app_process模块,找到主函数main开始执行

 

service vold /system/bin/vold

   class core

   socket vold stream 0660 root mount

ioprio be 2

 

service zygote /system/bin/app_process-Xzygote /system/bin --zygote --start-system-server

   class main

   socket zygote stream 660 root system

   onrestart write /sys/android_power/request_state wake

   onrestart write /sys/power/state on

   onrestart restart media

   onrestart restart netd

 

找到主函数main开始执行,vold模块main 函数:

int main() {

 

   VolumeManager *vm;

   CommandListener *cl;

   NetlinkManager *nm;

 

   SLOGI("Vold 2.1 (the revenge) firing up");

 

   mkdir("/dev/block/vold", 0755);

 

   /* For when cryptfs checks and mounts an encrypted filesystem */

   klog_set_level(6);

 

   /* 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();

   vm->setBroadcaster((SocketListener *) cl);

   nm->setBroadcaster((SocketListener *) cl);

 

   if (vm->start()) {

       SLOGE("Unable to start VolumeManager (%s)", strerror(errno));

       exit(1);

    }

 

   if (process_config(vm)) {

       SLOGE("Error reading configuration (%s)... continuing anyways",strerror(errno));

    }

 

   if (nm->start()) {

       SLOGE("Unable to start NetlinkManager (%s)", strerror(errno));

       exit(1);

    }

 

   coldboot("/sys/block");

//   coldboot("/sys/class/switch");

 

   /*

    * Now that we're up, we can respond to commands

    */

   if (cl->startListener()) {

       SLOGE("Unable to start CommandListener (%s)",strerror(errno));

       exit(1);

    }

 

   // Eventually we'll become the monitoring thread

   while(1) {

       sleep(1000);

    }

 

   SLOGI("Vold exiting");

   exit(0);

}

app_main.cpp 主函数:

int main(int argc, char* const argv[])

{

#ifdef __arm__

   /*

    * b/7188322 - Temporarily revert to the compat memory layout

    * to avoid breaking third party apps.

    *

    * THIS WILL GO AWAY IN A FUTURE ANDROID RELEASE.

    *

    *http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7dbaa466

    * changes the kernel mapping from bottom up to top-down.

    * This breaks some programs which improperly embed

    * an out of date copy of Android's linker.

    */

   char value[PROPERTY_VALUE_MAX];

   property_get("ro.kernel.qemu", value, "");

   bool is_qemu = (strcmp(value, "1") == 0);

   if ((getenv("NO_ADDR_COMPAT_LAYOUT_FIXUP") == NULL) &&!is_qemu) {

       int current = personality(0xFFFFFFFF);

       if ((current & ADDR_COMPAT_LAYOUT) == 0) {

           personality(current | ADDR_COMPAT_LAYOUT);

           setenv("NO_ADDR_COMPAT_LAYOUT_FIXUP", "1", 1);

           execv("/system/bin/app_process", argv);

           return -1;

       }

    }

   unsetenv("NO_ADDR_COMPAT_LAYOUT_FIXUP");

#endif

 

   // ADDED BY MARS BEGIN

   setconnecthook(android::hook_connect);

   // ADDED BY MARS END

 

    //These are global variables in ProcessState.cpp

   mArgC = argc;

   mArgV = argv;

 

   mArgLen = 0;

   for (int i=0; i<argc; i++) {

       mArgLen += strlen(argv[i]) + 1;

    }

   mArgLen--;

 

   AppRuntime runtime;

   const char* argv0 = argv[0];

 

   // Process command line arguments

   // ignore argv[0]

   argc--;

   argv++;

 

   // Everything up to '--' or first non '-' arg goes to the vm

 

   int i = runtime.addVmArguments(argc, argv);

 

   // Parse runtime arguments.  Stopat first unrecognized option.

   bool zygote = false;

   bool startSystemServer = false;

   bool application = false;

   const char* parentDir = NULL;

   const char* niceName = NULL;

   const char* className = NULL;

   while (i < argc) {

       const char* arg = argv[i++];

       if (!parentDir) {

           parentDir = arg;

       } else if (strcmp(arg, "--zygote") == 0) {

           zygote = true;

           niceName = "zygote";

       } else if (strcmp(arg, "--start-system-server") == 0) {

           startSystemServer = true;

       } else if (strcmp(arg, "--application") == 0) {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值