硬盘与文件系统

  • 硬盘物理结构
  • MBR分区
  • GPU分区
  • FAT
  • ROM Layout


硬盘物理结构

希捷硬盘的bios芯片型号 希捷硬盘bios芯片位置判别_希捷硬盘的bios芯片型号


以一个机械硬盘为例,内部包括磁片、主轴、速写磁头、传动手臂、传动轴、反力矩弹簧装置,SSD没有这样的结构,但都有一个相同的存储介质(主轴外一圈的部分)右边为存储介质的内部情况。

MBR分区

主引导记录MBR(Master Boot Record) Leagcy 启动最后就是通过读MBR做校验检测硬盘是否存在系统等

扇区0

扇区1

扇区2

扇区3



扇区N-2

扇区N-1

扇区N

MBR

通常磁盘512 Byte分为一个扇区(Logical Block Address 0)LBA0, MBR存放在磁盘的第一个扇区, 用4个字节(StartingLBA)表示该分区的起始扇区号,4个字节(SizelnLBA)表示该分区拥有的总扇区数,最大只能支持4个分区(每个分区最大是2T 4G扇区数x512B每扇区 =2TB)下图为MBR的组成:0X55 0xAA相当于标志符

希捷硬盘的bios芯片型号 希捷硬盘bios芯片位置判别_分区表_02


MBR最多有四个分区,下表为分区信息结构:

存储字节位

内容及含义

第1字节

引导标志,若值为80H表示活动分区,若值为00H表示非活动分区

第2、3、4字节

本分区的起始磁头号、扇区号、柱面号。其中:磁头号——第2字节、扇区号——第3字节的低6位、柱面号——第3字节高2位+第4字节8位

第5字节

分区类型符 00H——表示该分区未用(即没有指定)、06H——FAT16基本分区、0BH——FAT32基本分区、05H——扩展分区、07H——NTFS分区、0FH——(LBA模式)扩展分区(83H为Linux分区等)

第6、7、8字节

磁头号——第6字节、扇区号——第7字节的低6位、柱面号——第3字节高2位+第8字节

第9、10、11、12字节

本分区之前已用的扇区数

第13、14、15、16字节

本分区的总扇区数

GPU分区

GPT(GUID Partition table), 为了弥补MBR的不足, Intel设计了GPT分区。GPT分区支持更大容量, 更多分区(Windows最大支持128个), 更加安全(首尾部分分别保存了一份相同的分区表), 兼容MBR。
0号扇区称为保护性MBR,同MBR硬盘的0号扇区格式相同。其主要作用是兼容 MBR硬盘时代的工具,防止这些工具因不识别GPT格式而破坏硬盘。

扇区0

扇区1

扇区2

扇区3

扇区4



扇区N-2

扇区N-1

扇区N

MBR

GPT头

分区表项1、2、3、4

分区表项5

分区表项6

备份GPT头

希捷硬盘的bios芯片型号 希捷硬盘bios芯片位置判别_bios_03


硬盘的1号扇区称为G P T头,存储了硬盘的结构信息,主要包括:G P T头标志 “EFIPART”、表头字节数、表头CRC32校验码、GPT头和备份表头地址、可用于分区的扇区范围

// GPT分区表项结构体
typedef struct {
EFI_GUID PartitionTypeGUID;  //分区类型GUID, 0表示此项为空 
EFI_GUID UniquePartitionGUID;//分区标志GUID
EFI_LBA StartingLBA;         //分区的首扇区
EFI_LBA EndingLBA;           //分区的尾扇区
UINT64 Attributes;           //分区属性
CHARI6 PartitionName[36];    //分区名字符串,必须以0x0000结尾
} EFI_PARTITION_ENTRY;

FAT

每个UEFI系统至少有一个ESP(EFI System Partition)分区, 在这个分区上存放启动文件. EFI也要有读取文件的功能. UEFI内置的文件系统基于FAT开发.

文件配置表 (英文: File Allocation Table, 首字母缩略字: FAT)是一种由微软发明的并带有部分专利的文件系统, 供MS-DOS使用, 也是非NT内核的微软窗口使用的文件系统. FAT文件系统考虑当时计算机效能有限, 所以未被复杂化, 因而被几乎所有个人计算机的操作系统支持. 这特性使它成为理想的软盘和记忆卡文件系统, 也适合用作不同操作系统中的数据交流.

DrivIver Binding流程:

希捷硬盘的bios芯片型号 希捷硬盘bios芯片位置判别_文件系统_04


UEFI设计了一种简单的文件系统协议UEFI File System.

gEfiSimpleFileSystemProtocolGuid <MdePkg/include/Protocol/SimpleFileSystem.h>

struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {
  ///
  /// The version of the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. The version
  /// specified by this specification is 0x00010000. All future revisions
  /// must be backwards compatible.
  ///
  UINT64                                      Revision;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume;
};

OpenVolume 打开的protocol结构:

// EFI_FILE_PROTOCOL为支持的文件系统提供文件IO访问。  
// EFI_FILE_PROTOCOL提供对文件或目录内容的访问,也是对文件所在文件系统目录树中位置的引用。 
// 对于任何给定的文件句柄,可以相对于该文件的位置打开其他文件,从而产生新的文件句柄。 
struct _EFI_FILE_PROTOCOL {
  ///
  /// The version of the EFI_FILE_PROTOCOL interface. The version specified
  /// by this specification is EFI_FILE_PROTOCOL_LATEST_REVISION.
  /// Future versions are required to be backward compatible to version 1.0.
  ///
  UINT64                Revision;
  EFI_FILE_OPEN         Open;
  EFI_FILE_CLOSE        Close;
  EFI_FILE_DELETE       Delete;
  EFI_FILE_READ         Read;
  EFI_FILE_WRITE        Write;
  EFI_FILE_GET_POSITION GetPosition;
  EFI_FILE_SET_POSITION SetPosition;
  EFI_FILE_GET_INFO     GetInfo;
  EFI_FILE_SET_INFO     SetInfo;
  EFI_FILE_FLUSH        Flush;
  EFI_FILE_OPEN_EX      OpenEx;
  EFI_FILE_READ_EX      ReadEx;
  EFI_FILE_WRITE_EX     WriteEx;
  EFI_FILE_FLUSH_EX     FlushEx;
};

FAT驱动的核心函数 OpenVolume实体:

EFI_STATUS
EFIAPI
FatOpenVolume (
  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,
  OUT EFI_FILE_PROTOCOL                **File
  )
{
  EFI_STATUS  Status;
  FAT_VOLUME  *Volume;
  FAT_IFILE   *IFile;

  Volume = VOLUME_FROM_VOL_INTERFACE (This);
  FatAcquireLock ();

  //
  // Open Root file打开根目录
  //
  Status = FatOpenDirEnt (NULL, &Volume->RootDirEnt);
  if (EFI_ERROR (Status)) {
    goto Done;
  }
  //
  // Open a new instance to the root
  //
  Status = FatAllocateIFile (Volume->Root, &IFile);
  if (!EFI_ERROR (Status)) {
    *File = &IFile->Handle;
  }

Done:

  Status = FatCleanupVolume (Volume, Volume->Root, Status, NULL);
  FatReleaseLock ();

  return Status;
}

OpenVolume ——>Open ——>Read/Write ——>Close

EFI_STATUS
EFIAPI
FatOpen (
  IN  EFI_FILE_PROTOCOL   *FHand,
  OUT EFI_FILE_PROTOCOL   **NewHandle,
  IN  CHAR16              *FileName,
  IN  UINT64              OpenMode,
  IN  UINT64              Attributes
  )
{
  return FatOpenEx (FHand, NewHandle, FileName, OpenMode, Attributes, NULL);
}
;
EFI_STATUS
EFIAPI
FatRead (
  IN     EFI_FILE_PROTOCOL  *FHand,
  IN OUT UINTN              *BufferSize,
     OUT VOID               *Buffer
  )
{
  return FatIFileAccess (FHand, ReadData, BufferSize, Buffer, NULL);
}
;
EFI_STATUS
EFIAPI
FatWrite (
  IN     EFI_FILE_PROTOCOL  *FHand,
  IN OUT UINTN              *BufferSize,
  IN     VOID               *Buffer
  )
{
  return FatIFileAccess (FHand, WriteData, BufferSize, Buffer, NULL);
}

ROM Layout

BIOS ROM 文件主要由 FV(Firmware Volume)类型, Data类型和FILE类型构成每一种类型都要定义好Offset和Length, 以防冲突