您的位置:首页 > 理论基础 > 计算机网络

Android手机虚拟CD-ROM流程 && 使用网络同步时间(NITZ和NTP)&& Android VOLD

2012-03-07 15:12 966 查看
        很多时候,我们将手机接入电脑后,会发现一个CR-ROM光驱类似的盘符,里面有手机附带的内容。做法是这样的:

(1)增加手机分区

通过调整bootloader(传参给kernel)或kernel的mtd partition table。增加一个分区,专门存放CDROM镜像。

(2)制作CDROM镜像并烧写到该分区

将光驱的内容拷贝入一个linux目录,用mkisofs -r -o cdrom.iso /your-cdrom-dir创建镜像,通过厂家提供的烧写工具进行烧写手机。

(3)开发usb gadget支持

a,源码支持

kernel默认提供了drivers/usb/gadget/f_mass_storage.c以支持mass storage(磁盘或CDROM),android修改了f_mass_storage.c来支持其挂载sdcard为mass storage,其中f_mass_storage.c注册了一堆虚拟卷lun0-lunX,每个虚拟卷都设置为了普通的DISK。android只使用lun0来挂载sdcard到PC,比较直接的将mass storage初始化直接添加到了这个文件里。如要要支持CDROM,需要手工为其中某个lun设置cdrom
flag(比如lun1),参考该文件中的fsg_probe函数设置lun属性的行。

#ifdef SUPPORT_CDROM_BLOCK
if(i == 1)
fsg_cfg.luns[i].cdrom = 1;
#endif


b,用户层控制

在system\vold目录下的VolumeManager.cpp,android通过vold来控制mass storage的mount到设备和share到PC,原理就是操作mass storage gadget运行起来后的控制节点/sys/devices/platform/usb_mass_storage。需要设置其中的enable为1,然后lun0下的file指向需要share的设备节点。假设增加的分区为/dev/block/mtdblock14,则直接填写该节点到file文件中即可。

if( mUsbConnected ) {
char nodepath[255];
memset(nodepath,0 ,255);
snprintf(nodepath,
sizeof(nodepath), "/dev/block/mtdblock14");
LOGD(" name = usb_configuration");

int fd2;
if ((fd2 = open("/sys/devices/platform/usb_mass_storage/lun1/file",
O_WRONLY)) < 0) {
LOGE("Unable to open ums lunfile (%s)", strerror(errno));
return ;
}

if (write(fd2, nodepath, strlen(nodepath)) < 0) {
LOGE("Unable to write to ums lunfile (%s)", strerror(errno));
close(fd2);
return ;
}

close(fd2);
}
else{
int fd2;
char ch = 0;
LOGD(" name = usb_configuration remove ");
if ((fd2 = open("/sys/devices/platform/usb_mass_storage/lun1/file",
O_WRONLY)) < 0) {
SLOGE("Unable to open ums lunfile (%s)", strerror(errno));
return ;
}

if (write(fd2, &ch, 1) < 0) {
SLOGE("Unable to write to ums lunfile (%s)", strerror(errno));
close(fd2);
return ;
}

close(fd2);
}

 

(4)之后,就可以直接在XP中看到挂载的CD-ROM了。基本流程如此,其他还有很多细节,比如光盘要有aurorun来运行默认执行文件,如何同时兼容adb支持但又可以默认弹出光驱等等。

=============================================使用网络同步时间(NITZ和NTP)==================================

        在android 4.0版本上,通过网络同步时间有两种方式:NITZ和NTP,它们使用的条件不同,可以获取的信息也不一样;勾选这个功能后,手机首先会尝试NITZ方式,若获取时间失败,则使用NTP方式

(1)NITZ(network identity and time zone)同步时间

        NITZ是一种GSM/WCDMA基地台方式,必须插入SIM卡,且需要operator支持;可以提供时间和时区信息。中国大陆运营商基本是不支持的。

(3)NTP(network time protocol)同步时间

        NTP在无SIM卡或operator不支持NITZ时使用,单纯通过网络(GPRS/WIFI)获取时间,只提供时间信息,没有时区信息(因此在不支持NITZ的地区,自动获取时区功能实际上是无效的)。NTP还有一种缓存机制:当前成功获取的时间会保存下来,当用户下次开启自动更新时间功能时会结合手机clock来进行时间更新。这也是没有任何网络时手机却能自动更新时间的原因。此外,因为NTP是通过对时的server获取时间,当同步时间失败时,可以检查一下对时的server是否有效,并替换为其他server试一下。

=============================================Android VOLD==================================

(1)背景

        udev是 Linux2.6内核里的一个功能,它替代了原来的 devfs,成为当前 Linux 预设的设备管理工具。udev以守护进程的形式运行,通过侦听内核发出来的 uevent来管理 /dev目录下的设备文件。不像之前的设备管理工具,udev在用户空间 (user space)运行,而不在内核空间 (kernel space)运行。

(2)Vold的产生

        Vold的全称是Volume Daemon。在android中,取代udev的是vold, android一出生就没有遵守传统linux的许多标准,所以udev也不能很好的服务于android。android的的做法是定做一套udev,这就是vold。无论是udev还是vold,都是基于sysfs的。kernel层能检测到有新的设备接入,并能为之加载相应的驱动,sysfs用于通知用户层,内核中的sysfs机制要求当有新的驱动加载时给用户层发送相应的event。首先,我们要知道如何接收来自内核的event。这里就要用到Netlink
socket,socket不仅能用于网络间的通讯, 也用能用于进程间的通讯,而这种内核态与用户沟通的活,也需要使用socket。

        Vold是存储类的守护进程,是Android系统处理磁盘的核心部分。Vold服务由volumeManager统一管控,它将具体任务分别分派给netlinkManager,commandListener, directVolume, Volume去完成。Vold服务向下通过socket机制与底层驱动交互,向上通过JNI,intent, socket, doCommand等机制与Java Framework交互。Android的volume服务主要是用来管理usb/sd卡等外部存储设备。平台可以对外部存储设备进行操作和轮询状态,当外部存储设备状态发生变化时,volume服务也会实时报告平台。

(3)Vold 内部架构

        Vold作为一个守护进程,一方面接受驱动的信息,并把信息传给应用层;另一方面接受上层的命令并完成相应。所以这里的连结一共有两条:

1) vold socket:负责vold与framework层的信息传递;

2)接受sysfs uevent的socket:负责接受kernel的信息; 

        Vold socket是在init进程启动VolumeDaemon时创建的,这是一个用于和framework层通信的socket,在android系统中叫做Localsocket,framework层通过JNI机制调用C/C++空间函数与之通讯。

        而与内核通信的socket是在vold main函数中创建的。在main函数中,vold将创建两个单例,VolumeManager和NetLinkManager,与内核通信的socket就在其中创建。这样Volume Daemon与Kernel、framework层的通信框架就建立。

参考原文:http://blog.csdn.net/kc58236582/article/details/49618445
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息