1. 主页
  2. 自己动手从0到1学写FAT32文件系统
  3. 第1章 驱动框架
  4. 解析主分区数量

解析主分区数量

内容纲要

本课时的主要详解了计算机对于磁盘进行主分区的划分管理。

主要内容

分区的必要性

课时中列举了三个原因,解释为什么要对磁盘进行分区:

  • 支持安装多种操作系统: 例如,只有一块硬盘,多个分区分别安装Windows, Linux等
  • 不同数据之间相互隔离:例如,为资源存放和应用程序安装分配不同分区
  • 利用不同文件系统的特点:例如,为需要加密安全的数据单独分区,并使用特定文件系统

简单点,从直观来说,通过分区可以使得我们在操作系统中将一块磁盘划分为多个不同的盘,如C:,D:, E盘等。各个盘可以分别安装操作系统,放置视频、软件等资料。

分区表

用于对磁盘进行分区的方式有多种方案,用得历史较久且较多的是基于MBR的分区表。另外,还有一种分区表GUID,请见GUID分区表

有篇文章介绍了MBR分区表和GUID分区表的比较,有兴趣可阅读GUID分区表简介

课程中所用虚拟磁盘上的分区表为MBR分区表,对于GUID等其它分区表,本课程不做涉及。

如图所求,MBR分区表使用磁盘的最开始512字节中的64字节作为分区表,分区表共4个表项,每个表项记录了分区的起始位置、结束位置、分区类型、分区大小等重要特性值。

课程中通过将第0块读取到内存中,然后将一个结构体指针指向相应位置,即可完成分区表的解析。

重点难点

结构体到内存的映射

课程中有一行有意思的代码,如下

mbr_part_t * part;
part = ((mbr_t *)disk_buffer)->part_info;

对于C语言掌握不太熟悉的同学,可能不太容易理解上述代码。这里补充说明一下。

首先,(mbr_t )disk_buffer 这个转换,是将disk_buffer的起始内存处,看作是放置了一个mbr_t的结构体变量。(mbr_t )disk_buffer这种转换,相当于获得一个结构体指针,其指向该结构体变量。

其次,通过 ->part_info,就可以访问该结构体中相应的字段。

特别注意,上述代码要工作正常,必须保证:用代码定义mbr_t结构体,由C编译器编译后,其所对应的各字段的内存布局,与实际disk_buffer中相应值在内存中的布局要完全一致。一旦发生不一致,就会导致解析出错。

由于从磁盘读取到disk_buffer后,内存中的各值的布局已经确定下来,我们只能在调整结构体的定义,使其与结构体中的一致。因此,有了如下代码:

在以下代码中,须注意以下两点:

  • 必须加pack(1),让编译器不要额外填充字节。这样所有字段对应的内存排列位置,就完全由我们自己通过代码控制;
  • 在定义各字段时,根据内存中的排列顺序以及所占位数多少,逐个的添加各字段定义。

注意事项

CHS地址

这个地址不用深究,这是早期磁盘采用的一种地址,这种地址是根据磁盘的物理结构去描述的,参见CHS

另一种对磁盘的块进行编址的方式是LBA,这种方式不用考虑磁盘的物理结构,直接认为磁盘是由一个个逻辑块组成,访问时直接用相应的块序号作为目标地址即可。

CHS地址能表示的磁盘容量有限,所以现在一般比较少用这种地址。课程中没有使用这种地址,而使用了分区表中的相对扇区号来获得该分区的起始地址。

此外,考虑到SD卡等非磁盘设备也是可以应用FAT32文件系统,所以课程中更加不用考虑CHS地址。

常见问题

这篇文章对您有用吗?

我们要如何帮助您?

发表评论

电子邮件地址不会被公开。 必填项已用*标注