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