AMI code 是如何实现显示Logo?一般我们修改logo只需要修改logo(对应的token)文件即可,具体实现流程却没有分析过,AMI的logo官方说明如下:
以Baytrail平台为例: 在ActivateApplication这个函数当中,执行了很多动作,关于logo post的过程,需要注意的就是DrawQuietBootLogoHook 函数:
VOID ActivateApplication( VOID )
{
CHAR16 *text=NULL,*newString=NULL, *text2=NULL;
UINTN length, TseMajor,TseMinor, TseBuild;
#if APTIO_4_00
UINTN ConCols,ConRows;
#endif
...
DrawQuietBootLogoHook();
...
}
在这个函数当中,GenericHook是通过hook数目来定位,HOOKID1就是所需要的number,所实现的功能是当你已经加载过了,就可以直接调用,如果没有,则返回defaultfn,defaultfn这个变量就是下面函数中红色部分:
VOID DrawQuietBootLogoHook(VOID)
{
GenericHook( HOOKID1, DrawQuietBootLogo );
}
如何实现从DrawQuietBootLogoHook 到logo图片的捕捉以及解码?下图是解码的整个流程 :
捕捉Logo的流程:
VOID DrawQuietBootLogo(VOID)
{
...
EFI_GUID LogoFile = EFI_DEFAULT_BMP_LOGO_GUID;
...
Status = GetGraphicsBitMapFromFV( &LogoFile, (VOID**)&ImageData, &ImageSize );
...
}
上面的LogoFile是一个GUID,整个GUID指向的就是我们所需要显示出来的Logo,GetGraphicsBitMapFromFV整个函数就是通过该GUID去捕捉FV当中的Logo图片,并将该Logo信息作为返回值以便后续解码使用,这支函数当中的GUID值定义为:0x7BB28B99,0x61BB,0x11d5,0x9A,0x5D,0x00,0x90,0x27,0x3F,0xC1,0x4D
下面是如何建立Logo的Guid,并与这支函数相对应:
我们的Logo路径通过Token保存:这儿的JPG格式后面提到的JPEG实际上是同一种格式,不要凌乱了 .
TOKEN
Name = "LOGO_FILE_NAME"
Value = "AmiTsePkg/Core/em/AMITSE/AMI_Logo.jpg"
Help = "logo file path"
TokenType = Expression
TargetMAK = Yes
TargetFDF = Yes
End
这个token定义了logo图片文件的文件名字以及存放路径 : 在TSE Binary这个module里面定义中用到了一只文件Logoffs.txt , 文件内容如下:
FILE FREEFORM = 7BB28B99-61BB-11D5-9A5D-0090273FC14D{
SECTION $(COMPRESSION_SECTION){
SECTION RAW = $(LOGO_FILE_NAME)
}
}
!if $(TSE_OEM_POSTLOGO_SUPPORT) == 1
FILE FREEFORM = 294B1CEF-9BEB-42D5-9971-0C8963CDAF02{
SECTION $(COMPRESSION_SECTION){
SECTION RAW = $(OEMLogo_FILE_PATH)
}
}
!endif
同样的在TSE Binary的module里的sdl文件里面定义了如下token:
FFS_FILE
Name = "AmiTseLogoFfsFdfFileStatement"
FD_AREA = "FV_LOGOROMHOLE"
FILE_Stmt = "AmiTsePkg\Core\em\AMITSE\Logoffs.txt"
Token = "TSE_ROMHOLE_SUPPORT" "=" "1"
End
以上流程就是将logo源路径逐步加载到了AmiTseLogoFfsFdfFileStatement token(FD_AREA:FV)当中,以上可知该Logo的GUID为7BB28B99-61BB-11D5-9A5D-0090273FC14D与之前函数当中GUID完全一致(废话,不一致怎么调用), 下面是Logo解码的过程,Logo并不是直接显示,需要根据实际情况解码后才能显示出来:
VOID DrawQuietBootLogo(VOID)
{
EFI_STATUS Status;
BOOLEAN LogoToDo = TRUE;
...
Status = DrawImage(
ImageData,
ImageSize,
(CO_ORD_ATTRIBUTE)Attribute,
CoordinateX,
CoordinateY,
AdjustSize,
&Width,
&Height
);
...
}
如上,同样在这支函数,在捕捉到logo之后,会调用DrawImage , 这个函数会将抓取的图片根据实际信息选择需要解码的方式 :
EFI_STATUS
DrawImage(
IN UINT8 *ImageData,
IN UINTN ImageSize,
...
switch(LogoType)
{
case BMP_Logo:
Status = ConvertBmpToUgaBltWrapper(
ImageData,
ImageSize,
(void**)&UgaBlt,
&UgaBltSize,
Height,
Width );
unBufferWidth = *Width;
break;
case Unsupported_Logo:
default:
Status = ConvertAdvancedImageToUgaBlt(
ImageData,
ImageSize,
(void**) &UgaBlt,
&UgaBltSize,
Height,
Width,
&Animate);
unBufferWidth = *Width;
break;
}
...
}
一般,我们使用的JPEG格式Logo,调用default里面函数:ConvertAdvancedImageToUgaBlt
如下 : 这个函数说明是Convert a advanced graphics image to a UGA blt buffer
传输图片信息到blt buffer里面 。
EFI_STATUS
ConvertAdvancedImageToUgaBlt (
IN VOID *ImageData,
IN UINTN ImageSize,
IN OUT VOID **UgaBlt,
IN OUT UINTN *UgaBltSize,
OUT UINTN *Height,
OUT UINTN *Width,
OUT BOOLEAN *Animate
)
{
...
switch(LogoType)
{
case GIF_Logo:
Status = ConvertGifToUgaBltWrapper(
ImageData,
(UINT32)ImageSize,
UgaBlt,
(UINTN*)UgaBltSize,
(UINTN*)Height,
(UINTN*)Width,
Animate
);
break;
case JPEG_Logo:
Status = ConvertJPEGToUgaBltWrapper(
ImageData,
(UINT32)ImageSize,
UgaBlt,
(UINT32*)UgaBltSize,
(UINT32*)Height,
(UINT32*)&Temp,
(UINT32*)Width
);
break;
case PCX_Logo:
Status = ConvertPCXToUgaBltWrapper(
ImageData,
(UINT32)ImageSize,
UgaBlt,
(UINT32*)UgaBltSize,
(UINT32*)Height,
(UINT32*)Width
);
break;
case PNG_Logo:
...
}
调用下面的函数:
EFI_STATUS ConvertJPEGToUgaBltWrapper (
IN VOID *JPEGImage,
IN UINT32 JPEGImageSize,
IN OUT VOID **UgaBlt,
IN OUT UINT32 *UgaBltSize,
OUT UINT32 *PixelHeight,
OUT UINT32 *PixelWidth,
OUT UINT32 *pun32BufferWidth)
{
EFI_STATUS Status = EFI_UNSUPPORTED;
#if SETUP_JPEG_LOGO_SUPPORT
Status = ConvertJPEGToUgaBlt(
JPEGImage,
(UINT32)JPEGImageSize,
UgaBlt,
(UINT32*)UgaBltSize,
(UINT32*)PixelHeight,
(UINT32*)PixelWidth,
(UINT32*)pun32BufferWidth
);
#endif
return Status;
}
上面这支函数解码JPEG格式图片,并且将其装载为UGA格式并输出(show Logo),
整个流程基本如此,如果是其他格式图片,仅仅是调用不同的函数,但实际流程还是一样的,功能也是完全相同 ,
原文链接:https://blog.csdn.net/vito_bin/article/details/78408131