有4个16字节的区域,先简要说明一下MBR的分区表的结构:

从这个表格可以看出,相对于446-509的分区表区域,每个主分区的第5个字节存放的是文件
系统标志位,用来识别什么分区,用fdisk工具查看一下,有如下文件系统对应的十六进制标志:
若需要读取这些文件系统标志,只需读取MBR的450个位置,占用一个字节大小。
扯得太远了,回到正题,本文是要分析Android格式化sd卡的功能,在格式化部分,涉及到
了系统的一些函数,与vold无关,简单的说明一下即可。
Android系统在格式化sd卡的时候,首先会判断sd卡是否存在分区,如果sd卡不存在分区,
那么需要重新初始化MBR区域,所以上面简要的介绍了MBR结构中分区表的区域。
int Volume::formatVol() {
if (getState() == Volume::State_NoMedia) {
errno = ENODEV;
return -1;
} else if (getState() != Volume::State_Idle) {
errno = EBUSY;
return -1;
}
/*如果该分区为卸载,那么格式化失败,返回错误*/
if (isMountpointMounted(getMountpoint())) {
SLOGW("Volume is idle but appears to be mounted - fixing");
setState(Volume::State_Mounted);
// mCurrentlyMountedKdev = XXX
errno = EBUSY;
return -1;
}
char devicePath[255];
dev_t diskNode = getDiskDevice();
dev_t partNode;
if (mDebug) {
SLOGI("Formatting volume %s (%s)", getLabel(), devicePath);
}
setState(Volume::State_Formatting);
if (!mLastMountedKdev) {
dev_t deviceNodes[2];
int n = getDeviceNodes(deviceNodes, 2);
// initialize MBR if no partition, or has multiple partitions
// but none is selected
if ((diskNode == deviceNodes[0]) || (n > 1)) {
sprintf(devicePath, "/dev/block/vold/%d:%d",
MAJOR(diskNode), MINOR(diskNode));
if (initializeMbr(devicePath)) {
SLOGE("Failed to initialize MBR (%s)", strerror(errno));
partNode = diskNode; // try to use whole disk
} else {
partNode = MKDEV(MAJOR(diskNode), MINOR(diskNode) + 1);
}
} else {
partNode = deviceNodes[0];
}
} else {
partNode = mLastMountedKdev;
}
sprintf(devicePath, "/dev/block/vold/%d:%d",
MAJOR(partNode), MINOR(partNode));
int ret = Fat::format(devicePath, 0);
SLOGE_IF(ret, "Failed to format (%s)", strerror(errno));
setState(Volume::State_Idle);
return ret;
}
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;
};
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;
}
setState(Volume::State_Idle);