uefi-ntfs文件系统支持的原理分析

uefi-ntfs文件系统支持的原理分析

本文的基本结构:
1.从问题出发
2.重点分析
3.总结,评论

1.从问题出发

load ntfs.efi之后,uefi就可以操作ntfs的分区.
一个基本的问题是:

  • uefi如何做到支持ntfs 文件系统?其机制是怎样的?

uefi的扩展性(extension)在此体现出现,我们可以添加新的文件系统支持,比如Linux ext2/3/4.扩展性是uefi的亮点所在!

2.重点分析

总结:
entry指定binding->uefi 使用binding协议supported找到匹配的设备,并获得设备的context接口,从而拿到设备信息->binding协议start 安装了filesystem协议来操作disk分区->filesystem协议 OpenVolume安装了文件系统的接口->之后文件系统用这些接口支持抽象的操作文件->over

2.1 入口

ENTRY_POINT = InitializeWinNtSimpleFileSystem
平凡的操作,安装binding协议(本质是指定binding接口),uefi首先会用到binding协议的BindingSupported,查找device的匹配driver.

EFI_STATUS
EFIAPI
InitializeWinNtSimpleFileSystem(
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  EFI_STATUS              Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &gWinNtSimpleFileSystemDriverBinding,
             ImageHandle,
             &gWinNtSimpleFileSystemComponentName,
             &gWinNtSimpleFileSystemComponentName2
             );
  ASSERT_EFI_ERROR (Status);


  return Status;
}
EFI_DRIVER_BINDING_PROTOCOL gWinNtSimpleFileSystemDriverBinding = {
  WinNtSimpleFileSystemDriverBindingSupported,
  WinNtSimpleFileSystemDriverBindingStart,
  WinNtSimpleFileSystemDriverBindingStop,
  0xa,
  NULL,
  NULL
};
2.2 binding协议BindingSupported
  • 原理上讲,就是比较GUID来识别支持性.
  • 值得注意的是OpenProtocol调用,查询ControllerHandle(也就是设备对象)对指定的WinNtIoProtocol是否支持,如果支持返回WinNtIo接口(也就是设备对象提供的context上下文).
EFI_STATUS
EFIAPI
WinNtSimpleFileSystemDriverBindingSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS              Status;
  EFI_WIN_NT_IO_PROTOCOL  *WinNtIo;
  // Open the IO Abstraction(s) needed to perform the supported test
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiWinNtIoProtocolGuid,
                  (VOID **) &WinNtIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Make sure GUID is for a File System handle.
  //
  Status = EFI_UNSUPPORTED;
  if (CompareGuid (WinNtIo->TypeGuid, &gEfiWinNtFileSystemGuid)) {
    Status = EFI_SUCCESS;
  }

  //
  // Close the I/O Abstraction(s) used to perform the supported test
  //
  gBS->CloseProtocol (
        ControllerHandle,
        &gEfiWinNtIoProtocolGuid,
        This->DriverBindingHandle,
        ControllerHandle
        );

  return Status;
}
2.3 binding协议BindingStart
  • 匹配成功后,开始启动的准备工作.
  • 在设备上安装新的EfiSimpleFileSystemProtocol协议
  • 创建了一个私有的对象以支持EfiSimpleFileSystemProtocol协议,
  • 这样后续的文件系统操作就有了足够的条件
     -1.uefi通过SimpleFileSystem来操作
     - 2.私有的对象提供访问disk分区的相关信息
EFI_STATUS
EFIAPI
WinNtSimpleFileSystemDriverBindingStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL   *This,
  IN  EFI_HANDLE                    ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL      *RemainingDevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_WIN_NT_IO_PROTOCOL            *WinNtIo;
  WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE *Private;

  Private = NULL;
  // Open the IO Abstraction(s) needed
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiWinNtIoProtocolGuid,
                  (VOID **) &WinNtIo,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

...
  Private = AllocatePool (sizeof (WIN_NT_SIMPLE_FILE_SYSTEM_PRIVATE));
  if (Private == NULL) {
    Status = EFI_OUT_OF_RESOURCES;

    goto Done;
  }

  Private->WinNtThunk = WinNtIo->WinNtThunk;

  Private->FilePath = WinNtIo->EnvString;
...
  Private->SimpleFileSystem.Revision    = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
  Private->SimpleFileSystem.OpenVolume  = WinNtSimpleFileSystemOpenVolume;
  ...
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &ControllerHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  &Private->SimpleFileSystem,
                  NULL
                  );
...
  return Status;
}
2.4 OpenVolume

访问文件系统时,先调用OpenVolume安装了文件系统的接口.之后的操作属于文件系统相关的定义.每种FS具体实现都不相同.

EFI_STATUS
EFIAPI
WinNtSimpleFileSystemOpenVolume (
  IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *This,
  OUT EFI_FILE_PROTOCOL               **Root
  )
{
  ...
PrivateFile->EfiFile.Open = WinNtSimpleFileSystemOpen;
PrivateFile->EfiFile.Close =WinNtSimpleFileSystemClose;
PrivateFile->EfiFile.Read = WinNtSimpleFileSystemRead;
PrivateFile->EfiFile.Write=WinNtSimpleFileSystemWrite;
...
}

3.总结,评论

-uefi的扩展能支持现有的FS,也能支持将来新FS.只需要实现相应的接口.
-实现支持的关键是GUID的匹配,handle的表式结构能灵活的扩展加入新的协议.
—TBD

猜你喜欢

转载自blog.csdn.net/pcj2007/article/details/78727724