提交 2ad176e5 编写于 作者: P pcwlno1

fix: BBOX使用预留物理内存缓存故障日志

1、允许用户自己指定预留物理内存的起始地址和长度。
2、在适配层中增加对预留物理内存的映射。
3、在bbox的Kcondfig中增加有关预留物理内存的编译选项。
4、在bbox的Makefile增加有关内存函数头文件的引用。

Close #I41YIZ
Signed-off-by: Npcwlno1 <qidechun@huawei.com>
上级 0dc79479
......@@ -4,7 +4,31 @@ config BLACKBOX
help
Answer Y to enable LiteOS support blackbox
config LOG_ROOT_PATH
config BLACKBOX_LOG_PART_MOUNT_POINT
string "unknown"
default "/storage"
depends on BLACKBOX
help
define the default log path of blackbox
\ No newline at end of file
Define the default log part representative of blackbox
config BLACKBOX_LOG_ROOT_PATH
string "unknown"
default "/storage/data/log"
depends on BLACKBOX
help
Define the default log path of blackbox
config BLACKBOX_RESERVE_MEM_ADDR
int "The address of the reserve mem for blackbox in hex"
default 0
depends on BLACKBOX
help
Define the address of the reserve mem for blackbox in hex.
config BLACKBOX_LOG_SIZE
int "The size of log saved by blackbox in hex"
range 1024 1048576
default 65536
depends on BLACKBOX
help
Define the size of log saved by blackbox in decimal.
......@@ -7,7 +7,8 @@ LOCAL_SRCS := $(wildcard *.c)
LOCAL_INCLUDE := \
-I $(LITEOSTOPDIR)/kernel/common \
-I $(LITEOSTOPDIR)/kernel/common/blackbox \
-I $(LITEOSTOPDIR)/syscall
-I $(LITEOSTOPDIR)/syscall \
-I $(LITEOSTOPDIR)/kernel/base/include
LOCAL_FLAGS := $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS)
......
......@@ -44,11 +44,8 @@ extern "C" {
#define EVENT_MAX_LEN 32
#define MODULE_MAX_LEN 32
#define ERROR_DESC_MAX_LEN 512
#ifndef LOSCFG_LOG_ROOT_PATH
#define LOSCFG_LOG_ROOT_PATH "/storage/data/log"
#endif
#define KERNEL_FAULT_LOG_PATH LOSCFG_LOG_ROOT_PATH "/kernel_fault.log"
#define USER_FAULT_LOG_PATH LOSCFG_LOG_ROOT_PATH "/user_fault.log"
#define KERNEL_FAULT_LOG_PATH LOSCFG_BLACKBOX_LOG_ROOT_PATH "/kernel_fault.log"
#define USER_FAULT_LOG_PATH LOSCFG_BLACKBOX_LOG_ROOT_PATH "/user_fault.log"
#define MODULE_SYSTEM "SYSTEM"
#define EVENT_SYSREBOOT "SYSREBOOT"
......
......@@ -36,15 +36,22 @@
#endif
#ifdef LOSCFG_FS_VFS
#include "fs/fs.h"
#include "fs/mount.h"
#endif
#include "securec.h"
#include "los_memory.h"
/* ------------ local macroes ------------ */
#ifdef LOSCFG_FS_VFS
#define BBOX_DIR_MODE 0777
#endif
/* ------------ local prototypes ------------ */
/* ------------ local function declarations ------------ */
/* ------------ global function declarations ------------ */
/* ------------ local variables ------------ */
static bool g_isLogPartReady = FALSE;
/* ------------ function definitions ------------ */
int FullWriteFile(const char *filePath, const char *buf, size_t bufSize, int isAppend)
{
......@@ -59,7 +66,7 @@ int FullWriteFile(const char *filePath, const char *buf, size_t bufSize, int isA
}
if (!IsLogPartReady()) {
BBOX_PRINT_ERR("log path [%s] isn't ready to be written!\n", LOSCFG_LOG_ROOT_PATH);
BBOX_PRINT_ERR("log path [%s] isn't ready to be written!\n", LOSCFG_BLACKBOX_LOG_ROOT_PATH);
return -1;
}
fd = open(filePath, O_CREAT | O_RDWR | (isAppend ? O_APPEND : O_TRUNC), 0644);
......@@ -116,9 +123,25 @@ int SaveBasicErrorInfo(const char *filePath, struct ErrorInfo *info)
}
#ifdef LOSCFG_FS_VFS
static int IsLogPartMounted(const char *devPoint, const char *mountPoint, struct statfs *statBuf, void *arg)
{
(void)devPoint;
(void)statBuf;
(void)arg;
if (mountPoint != NULL && arg != NULL) {
if (strcmp(mountPoint, (char *)arg) == 0) {
g_isLogPartReady = TRUE;
}
}
return 0;
}
bool IsLogPartReady(void)
{
return access(LOSCFG_LOG_ROOT_PATH, W_OK) == 0;
if (!g_isLogPartReady) {
(void)foreach_mountpoint((foreach_mountpoint_t)IsLogPartMounted, LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT);
}
return g_isLogPartReady;
}
#else
bool IsLogPartReady(void)
......@@ -126,3 +149,67 @@ bool IsLogPartReady(void)
return TRUE;
}
#endif
#ifdef LOSCFG_FS_VFS
int CreateNewDir(const char *dirPath)
{
int ret;
if (dirPath == NULL) {
BBOX_PRINT_ERR("dirPath is NULL!\n");
return -1;
}
ret = access(dirPath, 0);
if (ret == 0) {
return 0;
}
ret = mkdir(dirPath, BBOX_DIR_MODE);
if (ret != 0) {
BBOX_PRINT_ERR("mkdir [%s] failed!\n", dirPath);
return -1;
}
return 0;
}
int CreateLogDir(const char *dirPath)
{
const char *temp = dirPath;
char curPath[PATH_MAX_LEN];
int idx = 0;
if (dirPath == NULL) {
BBOX_PRINT_ERR("dirPath is NULL!\n");
return -1;
}
if (*dirPath != '/') {
BBOX_PRINT_ERR("Invalid dirPath: %s\n", dirPath);
return -1;
}
(void)memset_s(curPath, sizeof(curPath), 0, sizeof(curPath));
curPath[idx++] = *dirPath++;
while (*dirPath != '\0' && idx < sizeof(curPath)) {
if (*dirPath == '/') {
if (CreateNewDir(curPath) != 0) {
return -1;
}
}
curPath[idx] = *dirPath;
dirPath++;
idx++;
}
if (*dirPath != '\0') {
BBOX_PRINT_ERR("dirPath [%s] is too long!\n", temp);
return -1;
}
return CreateNewDir(curPath);
}
#else
int CreateLogDir(const char *dirPath)
{
(void)dirPath;
return -1;
}
#endif
\ No newline at end of file
......@@ -50,6 +50,7 @@ extern "C" {
int FullWriteFile(const char *filePath, const char *buf, size_t bufSize, int isAppend);
int SaveBasicErrorInfo(const char *filePath, struct ErrorInfo *info);
int CreateLogDir(const char *dirPath);
bool IsLogPartReady(void);
#ifdef __cplusplus
......
......@@ -89,22 +89,22 @@ static void FormatErrorInfo(struct ErrorInfo *info,
#ifdef LOSCFG_FS_VFS
static void WaitForLogPart(void)
{
BBOX_PRINT_INFO("wait for log part [%s] begin!\n", LOSCFG_LOG_ROOT_PATH);
BBOX_PRINT_INFO("wait for log part [%s] begin!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT);
while (!IsLogPartReady()) {
LOS_Msleep(LOG_PART_WAIT_TIME);
}
BBOX_PRINT_INFO("wait for log part [%s] end!\n", LOSCFG_LOG_ROOT_PATH);
BBOX_PRINT_INFO("wait for log part [%s] end!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT);
}
#else
static void WaitForLogPart(void)
{
int i = 0;
BBOX_PRINT_INFO("wait for log part [%s] begin!\n", LOSCFG_LOG_ROOT_PATH);
BBOX_PRINT_INFO("wait for log part [%s] begin!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT);
while (i++ < LOG_WAIT_TIMES) {
LOS_Msleep(LOG_PART_WAIT_TIME);
}
BBOX_PRINT_INFO("wait for log part [%s] end!\n", LOSCFG_LOG_ROOT_PATH);
BBOX_PRINT_INFO("wait for log part [%s] end!\n", LOSCFG_BLACKBOX_LOG_PART_MOUNT_POINT);
}
#endif
......@@ -139,7 +139,7 @@ static void InvokeModuleOps(struct ErrorInfo *info, BBoxOps *ops)
if (ops->ops.Dump != NULL) {
BBOX_PRINT_INFO("[%s] starts dumping log!\n", ops->ops.module);
ops->ops.Dump(LOSCFG_LOG_ROOT_PATH, info);
ops->ops.Dump(LOSCFG_BLACKBOX_LOG_ROOT_PATH, info);
BBOX_PRINT_INFO("[%s] ends dumping log!\n", ops->ops.module);
}
if (ops->ops.Reset != NULL) {
......@@ -165,7 +165,12 @@ static void SaveLastLog(const char *logDir)
(void)LOS_MemFree(m_aucSysMem1, info);
return;
}
if (CreateLogDir(LOSCFG_BLACKBOX_LOG_ROOT_PATH) != 0) {
(void)LOS_SemPost(g_opsListSem);
(void)LOS_MemFree(m_aucSysMem1, info);
BBOX_PRINT_ERR("Create log dir [%s] failed!\n", LOSCFG_BLACKBOX_LOG_ROOT_PATH);
return;
}
LOS_DL_LIST_FOR_EACH_ENTRY(ops, &g_opsList, BBoxOps, opsList) {
if (ops == NULL) {
BBOX_PRINT_ERR("ops: NULL, please check it!\n");
......@@ -216,6 +221,11 @@ static void SaveLogWithoutReset(struct ErrorInfo *info)
(void)LOS_SemPost(g_opsListSem);
return;
}
if (CreateLogDir(LOSCFG_BLACKBOX_LOG_ROOT_PATH) != 0) {
(void)LOS_SemPost(g_opsListSem);
BBOX_PRINT_ERR("Create log dir [%s] failed!\n", LOSCFG_BLACKBOX_LOG_ROOT_PATH);
return;
}
if (ops->ops.Dump == NULL && ops->ops.Reset == NULL) {
(void)LOS_SemPost(g_opsListSem);
if (SaveBasicErrorInfo(USER_FAULT_LOG_PATH, info) == 0) {
......@@ -430,7 +440,7 @@ int OsBBoxDriverInit(void)
}
(void)memset_s(g_tempErrInfo, sizeof(*g_tempErrInfo), 0, sizeof(*g_tempErrInfo));
(void)memset_s(&taskParam, sizeof(taskParam), 0, sizeof(taskParam));
taskParam.auwArgs[0] = (UINTPTR)LOSCFG_LOG_ROOT_PATH;
taskParam.auwArgs[0] = (UINTPTR)LOSCFG_BLACKBOX_LOG_ROOT_PATH;
taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SaveErrorLog;
taskParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
taskParam.pcName = "SaveErrorLog";
......
......@@ -44,14 +44,13 @@
#include "los_hw.h"
#include "los_init.h"
#include "los_memory.h"
#include "los_vm_phys.h"
#include "los_vm_common.h"
#include "los_vm_phys.h"
#include "los_vm_zone.h"
#include "securec.h"
/* ------------ local macroes ------------ */
#define MEM_OVERLAP_COUNT 50
#define LOG_FLAG "GOODLOG"
#define FAULT_LOG_SIZE 0x4000 /* 16KB */
/* ------------ local prototypes ------------ */
struct FaultLogInfo {
......@@ -86,7 +85,7 @@ static void RegisterExcInfoHook(void)
{
if (g_logBuffer != NULL) {
#ifdef LOSCFG_SAVE_EXCINFO
LOS_ExcInfoRegHook(0, FAULT_LOG_SIZE - sizeof(struct FaultLogInfo),
LOS_ExcInfoRegHook(0, LOSCFG_BLACKBOX_LOG_SIZE - sizeof(struct FaultLogInfo),
g_logBuffer + sizeof(struct FaultLogInfo), WriteExcFile);
#endif
} else {
......@@ -96,18 +95,20 @@ static void RegisterExcInfoHook(void)
static int AllocLogBuffer(void)
{
int i = 0;
size_t nPages = ROUNDUP(FAULT_LOG_SIZE, PAGE_SIZE) >> PAGE_SHIFT;
void *tempBuffer[MEM_OVERLAP_COUNT] = { NULL };
for (i = 0; i < MEM_OVERLAP_COUNT; i++) {
tempBuffer[i] = LOS_PhysPagesAllocContiguous(nPages);
}
for (i = 0; i < (MEM_OVERLAP_COUNT - 1); i++) {
LOS_PhysPagesFreeContiguous(tempBuffer[i], nPages);
if (LOSCFG_BLACKBOX_LOG_SIZE < sizeof(struct FaultLogInfo)) {
BBOX_PRINT_ERR("LOSCFG_BLACKBOX_LOG_SIZE [%d] is too short, it must be >= %u\n",
LOSCFG_BLACKBOX_LOG_SIZE, sizeof(struct FaultLogInfo));
return -1;
}
g_logBuffer = tempBuffer[i];
BBOX_PRINT_INFO("g_logBuffer: %p for blackbox!\n", g_logBuffer);
/*
* The physical memory pointed to by LOSCFG_BLACKBOX_RESERVE_MEM_ADDR is
* exclusive to blackbox and cannot be occupied by other modules during
* system running and cannot overlap with the memory area of other systems
* during startup.
*/
g_logBuffer = (char *)MEM_CACHED_ADDR(LOSCFG_BLACKBOX_RESERVE_MEM_ADDR);
BBOX_PRINT_INFO("g_logBuffer: %p, len: 0x%x for blackbox!\n", g_logBuffer, (UINT32)LOSCFG_BLACKBOX_LOG_SIZE);
return (g_logBuffer != NULL) ? 0 : -1;
}
......@@ -135,11 +136,11 @@ static void Dump(const char *logDir, struct ErrorInfo *info)
#endif
(void)memcpy_s(&pLogInfo->flag, sizeof(pLogInfo->flag), LOG_FLAG, strlen(LOG_FLAG));
(void)memcpy_s(&pLogInfo->info, sizeof(pLogInfo->info), info, sizeof(*info));
DCacheFlushRange((UINTPTR)g_logBuffer, (UINTPTR)(g_logBuffer + FAULT_LOG_SIZE));
DCacheFlushRange((UINTPTR)g_logBuffer, (UINTPTR)(g_logBuffer + LOSCFG_BLACKBOX_LOG_SIZE));
} else {
#ifdef LOSCFG_SAVE_EXCINFO
SaveFaultLog(USER_FAULT_LOG_PATH, g_logBuffer + sizeof(struct FaultLogInfo),
Min(FAULT_LOG_SIZE - sizeof(struct FaultLogInfo), GetExcInfoIndex()), info);
Min(LOSCFG_BLACKBOX_LOG_SIZE - sizeof(struct FaultLogInfo), GetExcInfoIndex()), info);
#else
SaveFaultLog(USER_FAULT_LOG_PATH, g_logBuffer + sizeof(struct FaultLogInfo), 0, info);
#endif
......@@ -199,9 +200,9 @@ static int SaveLastLog(const char *logDir, struct ErrorInfo *info)
pLogInfo = (struct FaultLogInfo *)g_logBuffer;
if (memcmp(pLogInfo->flag, LOG_FLAG, strlen(LOG_FLAG)) == 0) {
SaveFaultLog(KERNEL_FAULT_LOG_PATH, g_logBuffer + sizeof(*pLogInfo),
Min(FAULT_LOG_SIZE - sizeof(*pLogInfo), pLogInfo->len), info);
Min(LOSCFG_BLACKBOX_LOG_SIZE - sizeof(*pLogInfo), pLogInfo->len), info);
}
(void)memset_s(g_logBuffer, FAULT_LOG_SIZE, 0, FAULT_LOG_SIZE);
(void)memset_s(g_logBuffer, LOSCFG_BLACKBOX_LOG_SIZE, 0, LOSCFG_BLACKBOX_LOG_SIZE);
BBOX_PRINT_INFO("[%s] starts uploading event [%s]\n", info->module, info->event);
(void)UploadEventByFile(KERNEL_FAULT_LOG_PATH);
BBOX_PRINT_INFO("[%s] ends uploading event [%s]\n", info->module, info->event);
......@@ -248,7 +249,6 @@ int OsBBoxSystemAdapterInit(void)
RegisterExcInfoHook();
if (BBoxRegisterModuleOps(&ops) != 0) {
BBOX_PRINT_ERR("BBoxRegisterModuleOps failed!\n");
LOS_PhysPagesFreeContiguous(g_logBuffer, ROUNDUP(FAULT_LOG_SIZE, PAGE_SIZE) >> PAGE_SHIFT);
g_logBuffer = NULL;
return LOS_NOK;
}
......@@ -262,4 +262,4 @@ int OsBBoxSystemAdapterInit(void)
return LOS_OK;
}
LOS_MODULE_INIT(OsBBoxSystemAdapterInit, LOS_INIT_LEVEL_PLATFORM);
\ No newline at end of file
LOS_MODULE_INIT(OsBBoxSystemAdapterInit, LOS_INIT_LEVEL_PLATFORM);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册