Simple_Uefi_Log
version:1.0.0
UefiLog.h
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Protocol/SimpleFileSystem.h>
#define LOG_DEBUG(Format, ...) Log(DEBUG, __FILE__, __func__, __LINE__, Format, ##__VA_ARGS__)
#define LOG_TRACE(Format, ...) Log(TRACE, __FILE__, __func__, __LINE__, Format, ##__VA_ARGS__)
#define LOG_INFO(Format, ...) Log(INFO, __FILE__, __func__, __LINE__, Format, ##__VA_ARGS__)
#define LOG_WRAN(Format, ...) Log(WRAN, __FILE__, __func__, __LINE__, Format, ##__VA_ARGS__)
#define LOG_ERROR(Format, ...) Log(ERROR, __FILE__, __func__, __LINE__, Format, ##__VA_ARGS__)
typedef enum _LOG_LEVEL
{
DEBUG = 1,
TRACE,
INFO,
WRAN,
ERROR
}LOG_LEVEL;
// 使用前初始化日志庫(kù)
// Path 可以傳入NULL蚯根,則log文件和程序同目錄
// Path 非NULL時(shí)树绩,需保證上級(jí)目錄存在
EFI_STATUS
LogInit(
IN CHAR16 *Path
);
// 程序結(jié)束前調(diào)用训桶,用來(lái)關(guān)閉打開(kāi)的Log文件
VOID
LogClose(
VOID
);
VOID
SetShowLevel(
BOOLEAN Is // default 'true'
);
VOID
SetShowLine(
BOOLEAN Is // default 'true'
);
VOID
SetShowFuncName(
BOOLEAN Is // default 'true'
);
VOID
SetShowFileName(
BOOLEAN Is // default 'false'
);
VOID
SetShowTime(
BOOLEAN Is // default 'true'
);
VOID
Log(
LOG_LEVEL level,
CHAR8 *FileName,
CHAR8 *FuncName,
UINTN LineNum,
CHAR16 *Format,
...
);
UefiLog.c
#include "UefiLog.h"
#include <Library/BaseLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/DevicePathToText.h>
#include <Guid/FileInfo.h>
#define MAX_MSG_SIZE 0x200
EFI_FILE_PROTOCOL *gFileHandle = NULL;
STATIC BOOLEAN ShowLevel = TRUE;
STATIC BOOLEAN ShowLine = TRUE;
STATIC BOOLEAN ShowFuncName = TRUE;
STATIC BOOLEAN ShowFileName = FALSE;
STATIC BOOLEAN ShowTime = TRUE;
VOID
SetShowLevel(
BOOLEAN Is
)
{
ShowLevel = Is;
}
VOID
SetShowLine(
BOOLEAN Is
)
{
ShowLine = Is;
}
VOID
SetShowFuncName(
BOOLEAN Is
)
{
ShowFuncName = Is;
}
VOID
SetShowFileName(
BOOLEAN Is
)
{
ShowFileName = Is;
}
VOID
SetShowTime(
BOOLEAN Is
)
{
ShowTime = Is;
}
CHAR16 *
GetLevelString(
LOG_LEVEL Level
)
{
switch (Level)
{
case DEBUG:
return L"[ DEBUG ]";
case TRACE:
return L"[ TRACE ]";
case INFO:
return L"[ INFO ]";
case WRAN:
return L"[ WARN ]";
case ERROR:
return L"[ ERROR ]";
default:
return L"[ ]";
break;
}
}
CHAR16 *
GetEfiTime(
VOID
)
{
EFI_TIME Time;
EFI_STATUS Status;
CHAR16 *TimeStr = NULL;
Status = gRT->GetTime(
&Time,
NULL
);
if (EFI_ERROR(Status))
{
Print(L"Get Time Failed: %r\n", Status);
return L"1970-01-01 00:00:00";
}
TimeStr = CatSPrint(
TimeStr,
L"%d-%02d-%02d %02d:%02d:%02d",
Time.Year,
Time.Month,
Time.Day,
Time.Hour,
Time.Minute,
Time.Second
);
return TimeStr;
}
CHAR16 *
GetStrReplace(
IN CHAR16 *Str,
IN CHAR16 *OldStr,
IN CHAR16 *NewStr
)
{
UINTN LenStr;
UINTN OldStrLen;
UINTN Index = 0;
CHAR16 *BStr = NULL;
LenStr = StrLen(Str);
OldStrLen = StrLen(OldStr);
BStr = AllocatePool(LenStr);
gBS->SetMem(
BStr,
LenStr,
0
);
for (Index = 0; Index < LenStr; Index++)
{
if (!StrnCmp(
Str + Index,
OldStr,
OldStrLen
))
{
StrCat(
BStr,
NewStr
);
Index += OldStrLen - 1;
}
else
{
StrnCat(
BStr,
Str + Index,
1
);
}
}
StrCpy(
Str,
BStr
);
return Str;
}
EFI_STATUS
GetCurrentPath(
OUT CHAR16 **Path
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocol;
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToTextProtocol;
Status = gBS->LocateProtocol(
&gEfiDevicePathToTextProtocolGuid,
NULL,
(VOID **)&DevicePathToTextProtocol
);
if (EFI_ERROR(Status))
{
Print(L"Get DevicePathToTextProtocol Error: %r\n", Status);
return Status;
}
Status = gBS->HandleProtocol(
gImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **)&LoadedImageProtocol
);
if (EFI_ERROR(Status))
{
Print(L"Get LoadedImageProtocol Error: %r\n", Status);
return Status;
}
*Path = DevicePathToTextProtocol->ConvertDevicePathToText(
LoadedImageProtocol->FilePath,
TRUE,
TRUE
);
return EFI_SUCCESS;
}
EFI_STATUS
OpenLogFile(
OUT EFI_FILE_PROTOCOL **FileHandle,
IN CHAR16 *Path
)
{
EFI_STATUS Status;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystemProtocol;
EFI_FILE_PROTOCOL *Root = 0;
Status = gBS->LocateProtocol(
&gEfiSimpleFileSystemProtocolGuid,
NULL,
(VOID **)&SimpleFileSystemProtocol
);
if (EFI_ERROR(Status))
{
Print(L"Get SimpleFileSystemProtocol Error: %r\n", Status);
return Status;
}
Status = SimpleFileSystemProtocol->OpenVolume(
SimpleFileSystemProtocol,
&Root
);
if (EFI_ERROR(Status))
{
Print(L"OpenVolume Failed : %r\n", Status);
return Status;
}
Status = Root->Open(
Root,
FileHandle,
Path,
EFI_FILE_MODE_CREATE |
EFI_FILE_MODE_WRITE |
EFI_FILE_MODE_READ,
0
);
if (EFI_ERROR(Status))
{
Print(L"Open File Failed : %r\n", Status);
return Status;
}
return EFI_SUCCESS;
}
EFI_STATUS
LogInit(
IN CHAR16 *Path
)
{
EFI_STATUS Status;
if (Path == NULL)
{
Status = GetCurrentPath(&Path);
Path = GetStrReplace(Path, L".efi", L".log");
if (EFI_ERROR(Status))
{
Print(L"GetCurrentPathError: %r\n", Status);
return Status;
}
}
Status = OpenLogFile(
&gFileHandle,
Path
);
return Status;
}
EFI_STATUS
WriteData(
IN VOID *Buffer,
IN UINT64 BufferSize
)
{
if (gFileHandle == NULL)
{
Print(L"Unknow File!\n");
return EFI_UNSUPPORTED;
}
if (Buffer == NULL)
{
Print(L"Unknow Buffer!\n");
return EFI_UNSUPPORTED;
}
if (BufferSize == 0)
{
Print(L"Unknow BufferSize!\n");
return EFI_UNSUPPORTED;
}
EFI_STATUS Status;
UINTN InfoBufferSize;
EFI_FILE_INFO *FileInfo = NULL;
Status = gFileHandle->GetInfo(
gFileHandle,
&gEfiFileInfoGuid,
&InfoBufferSize,
(VOID *)FileInfo
);
if (Status == EFI_BUFFER_TOO_SMALL)
{
FileInfo = AllocatePool(InfoBufferSize);
Status = gFileHandle->GetInfo(
gFileHandle,
&gEfiFileInfoGuid,
&InfoBufferSize,
(VOID *)FileInfo
);
}
if (EFI_ERROR(Status))
{
Print(L"Get File Info Failed: %r\n", Status);
return Status;
}
Status = gFileHandle->SetPosition(
gFileHandle,
FileInfo->FileSize
);
if (EFI_ERROR(Status))
{
Print(L"Set Position Failed: %r\n", Status);
return Status;
}
Status = gFileHandle->Write(
gFileHandle,
&BufferSize,
Buffer
);
if (EFI_ERROR(Status))
{
Print(L"Write File Failed: %r\n", Status);
return Status;
}
Status = gFileHandle->Flush(gFileHandle);
if (EFI_ERROR(Status))
{
Print(L"Flush Data Failed: %r\n", Status);
return Status;
}
return Status;
}
VOID
LogClose(
VOID
)
{
gFileHandle->Flush(gFileHandle);
gFileHandle->Close(gFileHandle);
}
VOID
Log(
LOG_LEVEL level,
CHAR8 *FileName,
CHAR8 *FuncName,
UINTN LineNum,
CHAR16 *Format,
...
)
{
VA_LIST Marker;
CHAR16 Buffer[MAX_MSG_SIZE];
CHAR16 *Header = NULL;
CHAR16 *Data = NULL;
VA_START(
Marker,
Format
);
UnicodeVSPrint(
Buffer,
MAX_MSG_SIZE,
Format,
Marker
);
VA_END(Marker);
if (ShowLevel)
{
Header = CatSPrint(
Header,
L"%s ",
GetLevelString(level)
);
}
if (ShowTime)
{
Header = CatSPrint(
Header,
L"%s ",
GetEfiTime()
);
}
if (ShowFileName)
{
Header = CatSPrint(
Header,
L"%a ",
FileName
);
}
if (ShowFuncName)
{
Header = CatSPrint(
Header,
L"%a ",
FuncName
);
}
if (ShowLine)
{
Header = CatSPrint(
Header,
L"%d ",
LineNum
);
}
if (Header == NULL)
{
Header = L"";
}
Data = CatSPrint(
Data,
L"%s%s",
Header,
Buffer
);
Print(L"%s", Data);
WriteData((VOID *)Data, StrLen(Data) * 2);
}
UefiLog是在UEFI環(huán)境下輕量級(jí)日志系統(tǒng)
1.
在使用宏定義前調(diào)用LogInit()
進(jìn)行初始化日志庫(kù)
在程序退出前調(diào)用LogClose()
關(guān)閉日志庫(kù)
// 使用前初始化日志庫(kù)
// Path 可以傳入NULL匿刮,則log文件和程序同目錄
// Path 非NULL時(shí)典蜕,需保證上級(jí)目錄存在
EFI_STATUS
LogInit(
IN CHAR16 *Path
);
2.
可以調(diào)用SetShowLevel()
來(lái)選擇是否顯示日志級(jí)別
相關(guān)設(shè)置有 行數(shù)笤喳、函數(shù)名稱(chēng)间校、文件名、時(shí)間教寂、日志級(jí)別
默認(rèn)不顯示文件名捏鱼。
Test.c
//
// UefiLog
//
// test.c
//
// UefiLog test Application
//
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
#include <Library/BaseLib.h>
#include "UefiLog/UefiLog.h"
EFI_STATUS
EFIAPI
UefiMain(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE* SystemTable
)
{
LogInit(NULL);
LOG_DEBUG(L"Test:%r\n", EFI_SUCCESS);
SetShowFileName(TRUE);
LOG_ERROR(L"error:%r\n", EFI_LOAD_ERROR);
SetShowLevel(FALSE);
SetShowFileName(FALSE);
SetShowFuncName(FALSE);
SetShowLine(FALSE);
SetShowTime(FALSE);
CHAR8 Data[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
};
UINTN Index = 0;
for (Index = 0; Index < 512; Index++)
{
if (Index % 16 == 0)
{
LOG_DEBUG(L"%04X: ", Index);
}
LOG_DEBUG(L"%02X ", Data[Index]);
if (Index % 16 == 15)
{
LOG_DEBUG(L"\n");
}
}
LogClose();
return EFI_SUCCESS;
}
3.
才疏學(xué)淺,能力有限酪耕,望指正穷躁!
4.
關(guān)注GitHub or 簡(jiǎn)書(shū) 不斷更新中!