一、tegra2 SD卡挂载为只读解决
可能是由于底层或者硬件方面的原因使SD卡的是否为只读判断结果一直为只读,这样上层进行读写打开或者读写挂载时始终为只读。临时解决办法是把判断函数返回值改为始终可读写的。具体修改如下:
把文件/kernel/drivers/mmc/host/sdhci-tegra.c里面函数tegra_sdhci_get_ro改成直接返回0
static int tegra_sdhci_get_ro(struct sdhci_host *sdhost)
{
struct tegra_sdhci *host = sdhci_priv(sdhost);
BUG_ON(host->gpio_wp == -1);
// return (gpio_get_value(host->gpio_wp)==host->gpio_polarity_wp);//注释掉原来返回判断
printk("TCL static int tegra_sdhci_get_ro(struct sdhci_host *sdhost)/n");
return 0;//直接返回0
}
二、U盘挂载修改方案
1、磁盘自动挂/卸载过程
(1) vold服务启动-->创建VolumeManager用来管理Volume-->根据/system/etc/vold.fstab配置文件来创建Volume对象加入到VolumeManager-->NetlinkManager::start()创建socket监听线程监听来自sysfs的socket消息-->同时创建另外一个线程(CommandListener::start)来监听"vold"socket的消息以及通过"vold"socket来广播消息-->系统vold主线程sleep()
(2) 根据vold.fstab配置的sysfs_path,sysfs有消息通过socke向上报-->消息解析分发()-->VolumeManager-->DirectVolume处理handle(设置状态有的是进行umount等)-->并继续通过"vold"socket继续向上广播(主要是java层也能通过“vold“通信)-->(******************向上的通知,以及上面对下发指令操作,比喻要求(挂载)****以后再分析************)
(3) vold.fstab格式:
mount_dev <label> <mount_point> <part> <sysfs_path_list>
如果part=auto,会自动挂载第一个可用的设备或者分区
label 与 mount_point不可重复
2、tegra2修改以自动挂/卸载(例子)
(1) 修改vold.fstab支持多个USB设备,后面的sysfs_path根据具体设备而不同,但每个USB口是固定的
dev_mount usb1 /mnt/usb/usb1 auto /devices/platform/tegra-ehci.2/usb2/2-1/2-1.2
dev_mount usb2 /mnt/usb/usb2 auto /devices/platform/tegra-ehci.2/usb2/2-1/2-1.3
(2) 修改init.rc
# create mountpoints
mkdir /mnt 0775 root system
mkdir /mnt/sdcard 0000 system system
#加入
mkdir /mnt/usb 0000 system system
#加入
mkdir /mnt/usb/usb1 0000 system system
#加入
mkdir /mnt/usb/usb2 0000 system system
(3) U盘格式与分区问题及部分解决
a、U盘主体格式必须是带MBR(主引导记录的分区),不然文件系统格式检测会错误(Invalid signature in boot block),具体判断代码如下:
if (block[510] != 0x55 || block[511] != 0xaa) {
pfatal("Invalid signature in boot block: %02x%02x", block[511], block[510]);
exit(2);
}
b、只能识别fat格式的,具体代码见FAT::doMount(),现在只有FAT文件系统对象
mount(fsPath, mountPoint, "vfat", flags, mountData);
c、一个USB设备如果有多个分区,系统只自动挂载第一个能够挂载的分区
d、能够同时挂载多个设备,见上面vold.fstab配置文件的修改
e、一个设备如果格式化成<不分区类型>,同时把文件系统格式成FAT,也能自动挂载,但在拔出时不能自动卸载挂载点,主要原因是驱动下面认为设备没有分区,不向上发PartitionRemoved(分区移走)消息,只发DiskRemoved(磁盘移走),而上层对DiskRemoved消息只是更新下状态,没有做umount操作。作为临时解决方案可以如下:
在DirectVolume::handleDiskRemoved()函数里面的倒数第一句setState(Volume:State_NoMidie)前加入如下代码
if(mDiskNumParts <= 0){//判断此磁盘分区数,如果分区数为0,就umount.
if (getState() != Volume::State_Mounted) {//并判断是否挂载了
setState(Volume::State_NoMedia);
return;
}
if((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev) {//并且是当前挂载的那个移走了
if (mVm->cleanupAsec(this, true)) {
SLOGE("Failed to cleanup ASEC - unmount will probably fail!");
}
if (Volume::unmountVol(true)) {
SLOGE("Failed to unmount volume on bad removal (%s)",
strerror(errno));
} else {
SLOGD("Crisis averted");
}
}//end if((dev_t) MKDEV(major, minor) == mCurrentlyMountedKdev)
}//end if(mDiskNumParts <= 0)