高通平台aboot通过shared memory保存uart log到kernel

该博客详细介绍了如何在高通平台上,通过共享内存机制将aboot阶段的uart日志保存,并最终写入内核进行持久化。首先,aboot阶段打印日志,然后保存这些日志,接着将日志数据写入共享内存区域,最后由内核读取并处理这些日志信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文档目的

shared memory即共享内存,在不同的进程之间通过一小段内存来共享信息,实现进程间通信。本文主要介绍高通aboot(lk) 和内核(kernel)间的信息传递。
在传统的lk-》kernel信息传递使用的是cmdline,但是这种方法只适合传递简短的信息,对于很大段的信息(比如aboot中的所有uart log)却无法传递。所以此处我们使用共享内存来传递,先把aboot中uart log全部保存在某一段内存中,然后无损传递到内核中,在内核中读出来。

具体实现

aboot打印log -> log保存 -> log写入内存 -> 启动内核 -> 读取log

1.aboot打印log

aboot中的log打印函数为dprintf,其原型定义在bootable/bootloader/lk/include/debug.h中:
#define dprintf(level, x...) do { if ((level) <= DEBUGLEVEL) { _dprintf(x); } } while (0)
其又调用 _dprintf(x),定义在 bootable/bootloader/lk/ lib/debug/debug.c中:
int _dprintf(const char *fmt, ...)
{
	char buf[256];
	char ts_buf[13];
	int err;

	snprintf(ts_buf, sizeof(ts_buf), "[%u] ",(unsigned int)current_time());  //串口log前面加上时间戳
	dputs(ALWAYS, ts_buf);

	va_list ap;
	va_start(ap, fmt);
	err = vsnprintf(buf, sizeof(buf), fmt, ap);  //解析格式
	va_end(ap);

	dputs(ALWAYS, buf);

	return err;
}
调用到dputs函数,
<think>我们正在处理高通平台的UEFI(通常称为XBL或ABL)中控制UART日志的问题。根据引用[3]中的代码片段,我们可以看到在高通SBL1(Secondary Boot Loader 1)的构建脚本中,有一个条件编译选项`FEATURE_BOOT_LOGGER_UART`,它被注释掉了。这暗示我们可以通过配置构建环境来开启或关闭UART日志。 在高通平台,UEFI阶段(包括XBL和ABL)的日志输出通常通过UART进行。控制UART日志的开启和关闭通常有以下几种方法: ### 方法一:通过构建配置(Build Configuration) 在高通平台的构建系统中,通常通过定义特定的宏(如`FEATURE_BOOT_LOGGER_UART`)来启用或禁用UART日志功能。具体步骤: 1. **修改构建配置文件**:在构建脚本(如`scons`)或配置文件(如`target.py`)中,设置或取消设置相关宏。 例如,在引用[3]的代码中,我们看到: ```python #if 'USES_BOOT_LOGGER_UART' in env: # env.Append(CPPDEFINES = [ # "FEATURE_BOOT_LOGGER_UART", # ]) ``` 要启用UART日志,需要取消注释并确保`USES_BOOT_LOGGER_UART`被定义。反之,注释掉则禁用。 2. **重新编译固件**:修改配置后,重新编译XBL或ABL镜像,并刷入设备。 ### 方法二:运行时控制(如果支持) 在某些情况下,高通平台可能支持通过环境变量或运行时参数动态控制日志输出。但是,在UEFI阶段,这种动态控制通常较为困难,因为此时系统尚未完全初始化。因此,更常见的是在编译时静态配置。 ### 方法三:通过EFI变量(如果支持) UEFI规范支持通过EFI变量来配置某些行为。但是,高通平台是否通过EFI变量控制UART日志,需要参考具体平台的文档。通常,这不是标准做法。 ### 具体操作步骤(以构建配置为例) 假设我们使用高通的构建系统(如scons),并且需要为某个目标(如mdm9x55)启用UART日志: 1. **定位构建配置文件**:找到负责目标设备配置的文件,如`mdm9x55.scons`(如引用[3]所示)。 2. **修改配置**:确保`USES_BOOT_LOGGER_UART`被定义,并且取消注释相关代码: ```python if 'USES_BOOT_LOGGER_UART' in env: env.Append(CPPDEFINES = [ "FEATURE_BOOT_LOGGER_UART", ]) ``` 3. **在构建环境中定义`USES_BOOT_LOGGER_UART`**:这可以通过在构建命令中传递参数或修改构建环境文件来实现。例如,在构建命令中: ```bash scons USES_BOOT_LOGGER_UART=1 ...其他参数... ``` 4. **重新编译并刷写**:重新编译XBL/SBL1镜像,并将新镜像刷入设备。 ### 验证 - 启用UART日志后,通过串口工具(如PuTTY)连接设备的调试串口,应能看到启动日志。 - 禁用后,则看不到日志(或者只有关键错误日志,取决于其他配置)。 ### 注意事项 - 开启UART日志可能会影响启动性能,因为输出日志需要时间。 - 在某些安全要求高的场景,可能会强制关闭日志以防止信息泄露。 > 引用[3]中的代码片段展示了如何通过条件编译控制UART日志的开启[^3]。在高通平台,UEFI阶段的日志控制通常通过类似的构建时宏实现。 --- ### §§相关问题§§ 1. 如何在高通平台的Android BootLoader(ABL)阶段启用UART日志? 2. 高通平台的QXDM工具是否可以捕获UEFI阶段的日志? 3. 在UEFI阶段启用UART日志对系统启动时间有何影响? 4. 如何通过QFIL工具刷写修改后的XBL镜像?</think>### 高通平台 UEFI 控制 UART 日志的方法 在高通平台的 UEFI 环境中(通常指 XBL/eXtensible Bootloader 或 ABL/Android Bootloader),控制 UART 日志的开启和关闭主要通过以下两种方式实现: #### 一、通过构建配置(编译时控制) 这是最常用的方法,通过修改构建系统的配置参数来控制 UART 日志功能: 1. **修改构建配置文件** ```python # 在 SCons 构建脚本中(如 mdm9x55.scons) # 启用 UART 日志 if 'USES_BOOT_LOGGER_UART' in env: env.Append(CPPDEFINES = [ "FEATURE_BOOT_LOGGER_UART", # 启用 UART 日志宏 ]) # 禁用 UART 日志(注释或删除相关配置) # if 'USES_BOOT_LOGGER_UART' in env: # env.Append(CPPDEFINES = [ # "FEATURE_BOOT_LOGGER_UART", # ]) ``` 参考引用[3]的代码片段,通过控制 `FEATURE_BOOT_LOGGER_UART` 宏的编译定义来开关功能[^3]。 2. **配置方法**: - **启用**:在构建命令中添加 `USES_BOOT_LOGGER_UART=1` 参数 ```bash scons USES_BOOT_LOGGER_UART=1 ...其他构建参数... ``` - **禁用**:移除该参数或设置为 `0` 3. **验证配置**: 在代码中检查宏定义: ```c #ifdef FEATURE_BOOT_LOGGER_UART // UART 日志初始化代码 UartInit(115200); #endif ``` #### 二、通过运行时配置(动态控制) 某些高通平台支持在 UEFI 阶段通过环境变量动态控制日志: 1. **设置 NVRAM 变量**: ```c // 在 UEFI 代码中设置变量 gRT->SetVariable( L"UartLogEnable", &gMyVendorGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(UINT8), &enable_flag // 1=启用, 0=禁用 ); ``` 2. **读取并应用配置**: ```c UINT8 log_enable = 0; UINTN size = sizeof(log_enable); if (EFI_ERROR(gRT->GetVariable( L"UartLogEnable", &gMyVendorGuid, NULL, &size, &log_enable))) { log_enable = 0; // 默认关闭 } if(log_enable) { ConfigureUartLogging(); } ``` 3. **通过 fastboot 动态修改**: ```bash # Android 设备上 fastboot oem uart-log enable # 启用 fastboot oem uart-log disable # 禁用 ``` #### 三、日志级别控制 在启用 UART 日志后,可进一步控制详细程度: ```c // 定义日志级别 #define LOG_LEVEL_ERROR 0x1 #define LOG_LEVEL_WARNING 0x2 #define LOG_LEVEL_INFO 0x4 #define LOG_LEVEL_DEBUG 0x8 // 设置当前日志级别 UINT32 current_log_level = LOG_LEVEL_ERROR | LOG_LEVEL_WARNING; void LogOutput(UINT32 level, const CHAR8* format, ...) { if(level & current_log_level) { // 输出日志到 UART } } ``` > **注意**: > 1. UART 日志会延长启动时间,生产版本建议关闭 > 2. 安全敏感场景应禁用日志防止信息泄露 > 3. 不同高通芯片平台(如 Snapdragon 8 系列与 7 系列)配置路径可能不同 > 4. 详细文档参考高通平台特定的 *Boot and CoreBSP Configuration Guide*[^1][^3] --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值