fix bootlog crash at legacy boot

Signed-off-by: SergeySlice <sergey.slice@gmail.com>
This commit is contained in:
SergeySlice 2021-03-06 08:07:06 +03:00
parent 45801ef2da
commit 235f13a3db
3 changed files with 117 additions and 10 deletions

View File

@ -73,7 +73,7 @@ extern MESSAGE_LOG_PROTOCOL *Msg;
EFI_STATUS
EFIAPI
MsgLogEntrypoint (
IN EFI_HANDLE ImageHandle,
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{

View File

@ -15,9 +15,14 @@
#include "Self.h"
#include "guid.h"
//Slice - if I set NEW_LOG to 0 then I will work with debug.log as in 5103
// but it is not working somehow.
// my purpose is to make debug.log open and close every second to see crashes.
// currently it is not happen. debug.log is not created at crash.
#define NEW_LOG 1
#ifndef DEBUG_ALL
#define DEBUG_BOOTLOG 1
#define DEBUG_BOOTLOG 0
#else
#define DEBUG_BOOTLOG DEBUG_ALL
#endif
@ -94,6 +99,7 @@ public:
#if DEBUG_BOOTLOG == 0
#define DGB_nbCallback(...)
#else
//Slice - it crashes at legacy boot
#define DGB_nbCallback(...) do { SuspendMemLogCallback smc; DBG(__VA_ARGS__); } while (0)
#endif
@ -110,7 +116,7 @@ void closeDebugLog()
//DGB_nbCallback("closeDebugLog() -> %s\n", efiStrError(Status));
}
#if NEW_LOG
static UINTN GetDebugLogFile()
{
EFI_STATUS Status;
@ -142,12 +148,12 @@ static UINTN GetDebugLogFile()
if ( debugLogFileName.isEmpty() )
{
debugLogFileName = S8Printf("misc\\%d-%d-%d_%d-%d-%d_%ls.log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, Now.Second, self.getCloverEfiFileName().wc_str());
debugLogFileName = S8Printf("misc\\%d-%d-%d_%d-%d_%ls.log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, self.getCloverEfiFileName().wc_str());
Status = self.getCloverDir().Open(&self.getCloverDir(), &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ, 0);
if ( !EFI_ERROR(Status) ) LogFile->Close(LogFile); // DO NOT modify Status here.
INTN i=1;
while ( Status != EFI_NOT_FOUND && (i < MAX_INTN) ) {
debugLogFileName = S8Printf("misc\\%d-%d-%d_%d-%d-%d_%ls(%lld).log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, Now.Second, self.getCloverEfiFileName().wc_str(), i);
debugLogFileName = S8Printf("misc\\%d-%d-%d_%d-%d_%ls(%lld).log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, self.getCloverEfiFileName().wc_str(), i);
Status = self.getCloverDir().Open(&self.getCloverDir(), &LogFile, debugLogFileName.wc_str(), EFI_FILE_MODE_READ, 0);
if ( !EFI_ERROR(Status) ) LogFile->Close(LogFile); // DO NOT modify Status here.
}
@ -193,7 +199,65 @@ static UINTN GetDebugLogFile()
}
return 0;
}
}
#else
EFI_FILE_PROTOCOL* GetDebugLogFile()
{
EFI_STATUS Status;
EFI_LOADED_IMAGE *LoadedImage;
EFI_FILE_PROTOCOL *RootDir;
EFI_FILE_PROTOCOL *LogFile;
EFI_TIME Now;
Status = gRT->GetTime(&Now, NULL);
if ( debugLogFileName.isEmpty() ) {
debugLogFileName = S8Printf("misc\\%d-%d-%d_%d-%d_%ls.log", Now.Year, Now.Month, Now.Day, Now.Hour, Now.Minute, self.getCloverEfiFileName().wc_str());
}
// get RootDir from device we are loaded from
Status = gBS->HandleProtocol(gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage);
if (EFI_ERROR(Status)) {
return NULL;
}
RootDir = EfiLibOpenRoot(LoadedImage->DeviceHandle);
if (RootDir == NULL) {
return NULL;
}
// Open log file from current root
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
// If the log file is not found try to create it
if (Status == EFI_NOT_FOUND) {
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
}
RootDir->Close(RootDir);
RootDir = NULL;
if (EFI_ERROR(Status)) {
// try on first EFI partition
Status = egFindESP(&RootDir);
if (!EFI_ERROR(Status)) {
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, 0);
// If the log file is not found try to create it
if (Status == EFI_NOT_FOUND) {
Status = RootDir->Open(RootDir, &LogFile, debugLogFileName.wc_str(),
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
}
RootDir->Close(RootDir);
RootDir = NULL;
}
}
if (EFI_ERROR(Status)) {
LogFile = NULL;
}
return LogFile;
}
// Jief : do we need that ?
// if (EFI_ERROR(Status)) {
@ -211,8 +275,10 @@ static UINTN GetDebugLogFile()
// RootDir = NULL;
// }
// }
}
#endif
#if NEW_LOG
VOID SaveMessageToDebugLogFile(IN CHAR8 *LastMessage)
{
EFI_STATUS Status;
@ -248,6 +314,45 @@ VOID SaveMessageToDebugLogFile(IN CHAR8 *LastMessage)
// Not all Firmware implements Flush. So we have to close every time to force flush.
closeDebugLog();
}
#else
VOID SaveMessageToDebugLogFile(IN CHAR8 *LastMessage)
{
STATIC BOOLEAN FirstTimeSave = TRUE;
// STATIC UINTN Position = 0;
CHAR8 *MemLogBuffer;
UINTN MemLogLen;
CHAR8 *Text;
UINTN TextLen;
EFI_FILE_HANDLE LogFile;
MemLogBuffer = GetMemLogBuffer();
MemLogLen = GetMemLogLen();
Text = LastMessage;
TextLen = AsciiStrLen(LastMessage);
/*UINTN lastWrittenOffset = GetDebugLogFile();*/
LogFile = GetDebugLogFile();
// Write to the log file
if (LogFile != NULL) {
// Advance to the EOF so we append
EFI_FILE_INFO *Info = EfiLibFileInfo(LogFile);
if (Info) {
LogFile->SetPosition(LogFile, Info->FileSize);
// If we haven't had root before this write out whole log
if (FirstTimeSave) {
Text = MemLogBuffer;
TextLen = MemLogLen;
FirstTimeSave = FALSE;
}
// Write out this message
LogFile->Write(LogFile, &TextLen, Text);
}
LogFile->Close(LogFile);
}
}
#endif
void EFIAPI MemLogCallback(IN INTN DebugMode, IN CHAR8 *LastMessage)
{

View File

@ -576,13 +576,15 @@ static EFI_STATUS GopSetModeAndReconnectTextOut(IN UINT32 ModeNumber)
// UINTN Index;
EFI_HANDLE *HandleBuffer = NULL;
EFI_STATUS Status;
// return EFI_UNSUPPORTED;
if (GraphicsOutput == NULL) {
return EFI_UNSUPPORTED;
}
// MsgLog("test 1\n");
Status = GraphicsOutput->SetMode(GraphicsOutput, ModeNumber);
MsgLog("Video mode change to mode #%d: %s\n", ModeNumber, efiStrError(Status));
// MsgLog("test 2\n");
const char* strStatus = efiStrError(Status);
MsgLog("Video mode change to mode #%d: %s\n", ModeNumber, strStatus);
if (gFirmwareClover && !EFI_ERROR(Status)) {
// When we change mode on GOP, we need to reconnect the drivers which produce simple text out