既然电脑上可以通过虚拟化安装多个Windows/Linux操作系统,那么手机是不是也可以安装多个安卓呢?现在有人在做这件事情。

 

虚拟化显然不适合,实际上arm的虚拟化,能商用的解决方案似乎只有OKL4等几个闭源的东西。所以,自然而然的,就有人想用容器来达到这个目的。这个东西叫Cells,作者叫Oren Laadan,哥伦比亚大学博士毕业,之前他做过一个叫CKPT的项目,实现容器的热迁移,CKPT由于对内核太过intrusive而被拒绝,现在由openvz实现的CRIU所代替了。

 

那在一个手机上装几个安卓有什么样呢?最容易想到的就是安全性了,一个安卓系统用于娱乐,而另一个用在工作上,娱乐时下载App、连接WIFI、浏览风页等的安全风险不会导致你工作上的东西信息泄露。

 

这样,你可以创建多个安卓系统,在各个安卓之间切换就跟切屏一样容易快捷,并且每个安卓也都可以有自己的屏保、密码保护。使用一个安卓时,其他的安卓也在运行中,只不过前者是在前台,可以接受用户输入可以显示屏幕内容,而后者的进程都在后台运行着。而且,每个安卓都有自己的手机号码!那么,这一切是怎么做到的呢?

 

这是Cells的架构图:

android 同时启动两个app 手机有两个android_嵌入式

Linux内核的namespace提供了大部分的隔离/虚拟化功能,例如对pid的隔离、网络的隔离、文件系统的隔离。名字空间是将全局的系统资源进行分离和虚拟,因此,通过PID名字空间,一个容器只能看到自己的进程,通过MNT名字空间,只能看到挂载在自己容器里的文件系统,而通过网络名字空间则不同的容器拥有各自的网络栈。

 

但内核缺乏对设备的隔离,所以Cells自己实现了Device Namespace。设备名字空间跟其他名字空间有一个非常不同的地方,它有active和inactive的状态。有一个设备名字空间是active的,其他的都只能是inactive。这样是为了实现之前说的一个安卓在前台其他安卓在后台。前台的安卓处在active namespace里,从而可以往frame buffer写数据,实现屏幕的显示。

 

不同的设备在名字空间上的处理可能是不同的,对于这些设备,都要修改驱动程序,让驱动namespace-aware。这点跟网络命名空间类似,各个网络协议栈也都要修改代码支持名字空间。

例如对于frame buffer,只有前台的安卓可以往frame buffer上写数据。那么,其他的安卓往frame buffer写数据会怎么样呢?会被设备名字空间指引到一个后备缓存里。一旦一个后台安卓被切换到前台去,后备缓存的数据也就立刻被写到真正的frame buffer上了。

android 同时启动两个app 手机有两个android_虚拟化_02

内核的改动只是一部分工作,用户态的工作更少不了,例如Root名字空间要对多个安卓的管理,通过unionfs实现多个安卓对代码和只读数据的共享,使用KSM对多份相同内存的节省,防止后台安卓将系统设成Low Power模式以及阻挠前台安卓这样做,等等。

 

另外还有一点,要实现不同安卓有不同的手机号码。从Cells的论文来看,这是通过VoIP实现的,通过在VoIP里建立好的映射关系,Cells确定一个打进来的电话号码应该属于哪个虚拟安卓。SIM卡只有一个,那打进来的电话到底会由哪个安卓响应呢?对VoIP不了解,具体情况怎么样不太清楚。

 

这个技术看来至少在2011年的时候就已经研究了并且写成了论文发表了出来,而且在Google Nexus 1和Nexus S等智能手机上验证了,现在已经成立了一家公司Cellrox来卖他们这个解决方案。作者通过往开源邮件列表发送邮件、公开内核代码、参与LinuxCon等,努力的推销Cells。

 

另外,有一家叫Enterpriod的移动解决方案提供商,有一款叫Divide的旗舰App,这款产品允许用户在手机上按照工作信息和私人信息不同分类来配置不同的档案,并一键完成档案切换。而商务档案就可包括企业版的邮件,浏览器,即时通讯以及短信等常用功能,保证跟用户的私人信息划清界限。Enterpriod最近得到了Google Venture领投的1200万美元风投,所以这东西看来是挺有前景的。

 

android 同时启动两个app 手机有两个android_android 同时启动两个app_03