开源ext2read代码走读之-扩展分区与逻辑分区说明及如何读取扩展分区的分区表(EBR)

一个硬盘可以有很多分区,但MBR分区表只有四项,怎么能突破这个限制呢?答案是扩展引导记录(EBR - Extended Boot Record),通过把MBR分区表中一项设为扩展分区(系统ID为0x05或0x0F),其分区表项指定扩展分区的起始位置和长度,在其中最开始扇区 (EBR)和MBR相同位置(0x1BE)放置另外一个分区表,一般称为扩展分区表。扩展分区表的第一项指定扩展分区目前的逻辑分区信息,如果还有更多的 逻辑分区,扩展分区表的第二项指定下一个EBR的位置,否则为0。最后的两个分区表项总是为0。通过这种方式,一个硬盘上的分区数目就没有限制了。

以上的意思即是说,扩展分区是MBR表项中的4个分区表中的一个分区表,而扩展分区又通过一个链式的分区表将多个逻辑分区进行管理。即逻辑分区是扩展分区中的一部分,是子的位格。

注意:在逻辑分区中,每个分区只是前两个分区表的信息有用,后两个分区表未使用,所以以下程序并没有进行3 4个分区信息的读取。

那么如何读取扩展分区中的多个逻辑分区的分区表呢?

int Ext2Read::scan_ebr(FileHandle handle, lloff_t base, int sectsize, int disk)

{
    unsigned char sector[SECTOR_SIZE];
    struct MBRpartition *part, *part1;
    Ext2Partition *partition;
    int logical = 4, ret;
    lloff_t  ebrBase, nextPart, ebr2=0;
    //表示此扩展分区开始的首扇区的相对扇区号(应该是相对于上一个分区吧)
    ebrBase = base;
    nextPart = base;
    while(1)
    {
        //读取此逻辑分区的第一个扇区
        ret = read_disk(handle, sector, nextPart, 1, sectsize);
        if(ret < 0)
            return ret;

        if(ret < sectsize)
        {
            printf("Error Reading the EBR \n");
            return -1;
        }
        //得到当前逻辑分区的分区信息,偏移446字节
        part = pt_offset(sector, 0);
        printf("index %d ID %X size %Ld \n", logical, part->sys_ind, get_nr_sects(part));
        //若文件系统为EXT2则进行处理,记录此分区的总扇区数,当前分区相对扇区号,扇区大小,设备控制句柄。
        if(part->sys_ind == EXT2)
        {
            partition = new Ext2Partition(get_nr_sects(part), get_start_sect(part)+ ebrBase + ebr2, sectsize, handle, NULL);
            if(partition->is_valid)
            {
                //为什么logical的初值为4,因为逻辑分区的分区号是从5开始的,在set_linux_name函数中将进行变化为+1
                partition->set_linux_name("/dev/sd", disk, logical);
                //将ext2分区的对象存入到ext2有效分区列表中
                nparts.push_back(partition);
            }
            else
            {
                delete partition;
            }
        }
        //对分区为lvm的分区的处理
        if(part->sys_ind == LINUX_LVM)
        {
            printf("LVM Physical Volume found disk %d partition %d\n", disk, logical);
            LVM lvm(handle, get_start_sect(part)+ ebrBase + ebr2, this);
            lvm.scan_pv();
        }
        //得到下一个逻辑分区的分区信息,下一个逻辑分区信息是在当前逻辑分区表的第二个分区表中;
        part1 = pt_offset(sector, 1);
        //得到当前分区的开始扇区相对扇区号(应该是相对于上一个分区的)
        ebr2 = get_start_sect(part1);
        //累加得到当前分区的开始扇区的相对扇区号
        nextPart = (ebr2 + ebrBase);
        //累加得到分区的个数
        logical++;
        //如果逻辑分区表中的第二个表的文件系统为0,则表示已经没有逻辑分区了
        if(part1->sys_ind == 0)
            break;
    }
    return logical;
}

你可能感兴趣的:(开源ext2read代码走读之-扩展分区与逻辑分区说明及如何读取扩展分区的分区表(EBR))