作者:gzshun. 原创作品,转载请标明出处!
来源:http://blog.csdn.net/gzshun
本文开始讨论sd卡的格式化功能,平时使用windows操作系统,也经常格式化磁盘。涉及到的
操作有这几步:
1.将分区信息写到硬盘的第一个设备节点的MBR结构中的分区表;
2.格式化分区到指定的文件系统类型。
MBR中存放分区表的位置在446-509,占用了64字节,MBR结构只支持4个主分区,所以
格式化函数两个主要工作交给了initializeMbr和Fat::format函数:
1.initializeMbr函数负责初始化MBR;
2.Fat::format函数负责格式化分区。
先来看initializeMbr函数的初始化工作:
int Volume::initializeMbr(const char *deviceNode) { struct disk_info dinfo; memset(&dinfo, 0, sizeof(dinfo)); if (!(dinfo.part_lst = (struct part_info *) malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) { SLOGE("Failed to malloc prt_lst"); return -1; } memset(dinfo.part_lst, 0, MAX_NUM_PARTS * sizeof(struct part_info)); dinfo.device = strdup(deviceNode); dinfo.scheme = PART_SCHEME_MBR; dinfo.sect_size = 512; dinfo.skip_lba = 2048; dinfo.num_lba = 0; dinfo.num_parts = 1; struct part_info *pinfo = &dinfo.part_lst[0]; pinfo->name = strdup("android_sdcard"); pinfo->flags |= PART_ACTIVE_FLAG; pinfo->type = PC_PART_TYPE_FAT32; pinfo->len_kb = -1; int rc = apply_disk_config(&dinfo, 0); if (rc) { SLOGE("Failed to apply disk configuration (%d)", rc); goto out; } out: free(pinfo->name); free(dinfo.device); free(dinfo.part_lst); return rc; }
这里贴出一些重要的结构体:
struct part_info { char *name; uint8_t flags; uint8_t type; uint32_t len_kb; /* in 1K-bytes */ uint32_t start_lba; /* the LBA where this partition begins */ }; struct disk_info { char *device; uint8_t scheme; int sect_size; /* expected sector size in bytes. MUST BE POWER OF 2 */ uint32_t skip_lba; /* in sectors (1 unit of LBA) */ uint32_t num_lba; /* the size of the disk in LBA units */ struct part_info *part_lst; int num_parts; };
初始化完成后,将该结构体变量pinfo通过apply_disk_config函数进行设置:
int apply_disk_config(struct disk_info *dinfo, int test) { int fd; struct write_list *wr_lst = NULL; int rv; if (validate_and_config(dinfo, &fd, &wr_lst) != 0) { LOGE("Configuration is invalid."); goto fail; } if ((rv = wlist_commit(fd, wr_lst, test)) >= 0) rv = test ? 0 : sync_ptable(fd); close(fd); wlist_free(wr_lst); return rv; fail: close(fd); if (wr_lst) wlist_free(wr_lst); return 1; }
该函数先打开sd卡的设备节点,然后将MBR的初始化信息写到第一个block(512B)中,
这里涉及到非常多函数,不在vold的讨论范围。
写完MBR后,就要对分区进行格式化,要格式化成FAT32格式,Fat::format函数直接调用
系统命令newfs_msdos来格式化新分区,检测磁盘是,Fat::check函数直接调用系统命令
fsck_msdos来检测分区。
最后格式化完成功,通知Framework,sd卡处于空闲状态:
setState(Volume::State_Idle);
然后,Framework又要重复挂载和卸载的操作了。
下篇文章介绍Android系统与电脑的连接,OTG功能,全称on-the-go。
待续。。
来源:http://blog.csdn.net/gzshun
本文开始讨论sd卡的格式化功能,平时使用windows操作系统,也经常格式化磁盘。涉及到的
操作有这几步:
1.将分区信息写到硬盘的第一个设备节点的MBR结构中的分区表;
2.格式化分区到指定的文件系统类型。
MBR中存放分区表的位置在446-509,占用了64字节,MBR结构只支持4个主分区,所以
有4个16字节的区域,先简要说明一下MBR的分区表的结构:
从这个表格可以看出,相对于446-509的分区表区域,每个主分区的第5个字节存放的是文件
系统标志位,用来识别什么分区,用fdisk工具查看一下,有如下文件系统对应的十六进制标志:
若需要读取这些文件系统标志,只需读取MBR的450个位置,占用一个字节大小。
扯得太远了,回到正题,本文是要分析Android格式化sd卡的功能,在格式化部分,涉及到
了系统的一些函数,与vold无关,简单的说明一下即可。
Android系统在格式化sd卡的时候,首先会判断sd卡是否存在分区,如果sd卡不存在分区,
那么需要重新初始化MBR区域,所以上面简要的介绍了MBR结构中分区表的区域。
格式化函数两个主要工作交给了initializeMbr和Fat::format函数:
1.initializeMbr函数负责初始化MBR;
2.Fat::format函数负责格式化分区。
先来看initializeMbr函数的初始化工作:
int Volume::initializeMbr(const char *deviceNode) { struct disk_info dinfo; memset(&dinfo, 0, sizeof(dinfo)); if (!(dinfo.part_lst = (struct part_info *) malloc(MAX_NUM_PARTS * sizeof(struct part_info)))) { SLOGE("Failed to malloc prt_lst"); return -1; } memset(dinfo.part_lst, 0, MAX_NUM_PARTS * sizeof(struct part_info)); dinfo.device = strdup(deviceNode); dinfo.scheme = PART_SCHEME_MBR; dinfo.sect_size = 512; dinfo.skip_lba = 2048; dinfo.num_lba = 0; dinfo.num_parts = 1; struct part_info *pinfo = &dinfo.part_lst[0]; pinfo->name = strdup("android_sdcard"); pinfo->flags |= PART_ACTIVE_FLAG; pinfo->type = PC_PART_TYPE_FAT32; pinfo->len_kb = -1; int rc = apply_disk_config(&dinfo, 0); if (rc) { SLOGE("Failed to apply disk configuration (%d)", rc); goto out; } out: free(pinfo->name); free(dinfo.device); free(dinfo.part_lst); return rc; }
这里贴出一些重要的结构体:
struct part_info { char *name; uint8_t flags; uint8_t type; uint32_t len_kb; /* in 1K-bytes */ uint32_t start_lba; /* the LBA where this partition begins */ }; struct disk_info { char *device; uint8_t scheme; int sect_size; /* expected sector size in bytes. MUST BE POWER OF 2 */ uint32_t skip_lba; /* in sectors (1 unit of LBA) */ uint32_t num_lba; /* the size of the disk in LBA units */ struct part_info *part_lst; int num_parts; };
初始化完成后,将该结构体变量pinfo通过apply_disk_config函数进行设置:
int apply_disk_config(struct disk_info *dinfo, int test) { int fd; struct write_list *wr_lst = NULL; int rv; if (validate_and_config(dinfo, &fd, &wr_lst) != 0) { LOGE("Configuration is invalid."); goto fail; } if ((rv = wlist_commit(fd, wr_lst, test)) >= 0) rv = test ? 0 : sync_ptable(fd); close(fd); wlist_free(wr_lst); return rv; fail: close(fd); if (wr_lst) wlist_free(wr_lst); return 1; }
该函数先打开sd卡的设备节点,然后将MBR的初始化信息写到第一个block(512B)中,
这里涉及到非常多函数,不在vold的讨论范围。
写完MBR后,就要对分区进行格式化,要格式化成FAT32格式,Fat::format函数直接调用
系统命令newfs_msdos来格式化新分区,检测磁盘是,Fat::check函数直接调用系统命令
fsck_msdos来检测分区。
最后格式化完成功,通知Framework,sd卡处于空闲状态:
setState(Volume::State_Idle);
然后,Framework又要重复挂载和卸载的操作了。
下篇文章介绍Android系统与电脑的连接,OTG功能,全称on-the-go。
待续。。