前面介绍了最新的 MemTest86 ,美中不足的是这个版本需要制作启动盘,这次介绍一种将它打包为一个 EFI 的方法。
基本的思路是:将完整的 MemTest86 磁盘镜像按照资源打包到一个 EFI 文件中,然后再配合之前的RamDisk 知识将这个镜像加载到内存中。这样就相当于制作的镜像文件,跳进去就可以执行了。
代码要点:
1.将之前介绍的 MemTest86 制作成一个硬件镜像,然后将这个镜像命令为MemTest2023.png
2.MyRamDisk2.inf 中给出用到的文件如下
[Sources]
MyRamDisk2.c
MyRamDisk2.idf
MemTest2023.png
3. MyRamDisk2.idf 文件内容如下
#image IMG_LOGO MemTest2023.png
4.主程序
a.首先找到当前 EFI 中的资源
//
// Retrieve HII package list from ImageHandle
//
Status = gBS->OpenProtocol (
gImageHandle,
&gEfiHiiPackageListProtocolGuid,
(VOID **) &PackageListHeader,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
Print(L"HII Image Package with logo not found in PE/COFF resource section\n");
return Status;
}
b.取得资源
//Step2. Parser HII Image
ImageHeader=(EFI_HII_IMAGE_PACKAGE_HDR*)(PackageListHeader+1);
ImageData=(UINT8 *)(ImageHeader+1);
c.解析资源之后拷贝到分配的内存中
// Look for Ram Disk Protocol
Status = gBS->LocateProtocol (
&gEfiRamDiskProtocolGuid,
NULL,
&MyRamDisk
);
if (EFI_ERROR (Status)) {
Print(L"Couldn't find RamDiskProtocol\n");
return EFI_ALREADY_STARTED;
}
//Allocate a memory for Image
Status = gBS->AllocatePool (
EfiReservedMemoryType,
(UINTN)FileSize,
(VOID**)&StartingAddr
);
if(EFI_ERROR (Status)) {
Print(L"Allocate Memory failed!\n");
return EFI_SUCCESS;
}
CopyMem(StartingAddr,&ImageData[5],FileSize);
//
// Register the newly created RAM disk.
//
Status = MyRamDisk->Register (
((UINT64)(UINTN) StartingAddr),
FileSize,
&gEfiVirtualDiskGuid,
NULL,
&DevicePath
);
if (EFI_ERROR (Status)) {
Print(L"Can't create RAM Disk!\n");
return EFI_SUCCESS;
}
上述代码编译运行之后,会在当前系统中生成一个新的盘符,进入这个盘符之后就可以运行 MemTest86 进行内存测试了。
文本完整代码如下:
生成的 EFI 如下: