如何在kext多次运行间存储参数?优先采用NVRAM方案
IOKit Kext 实现NVRAM参数持久化(启停时读写)
核心思路
利用IOKit框架的IORegistryEntry类读写NVRAM节点,在kext启动时读取参数初始化运行时变量,停止时将当前参数写入NVRAM。由于你的kext标记了OSBundleRequired=Root,根文件系统可用,需添加NVRAM读写失败时的文件存储降级方案,确保参数不丢失。
1. 启动时读取NVRAM参数
在kext的start方法中,通过NVRAM的注册表路径获取节点,读取自定义键值。若读取失败(首次启动或NVRAM不可用),使用默认参数。
代码示例(IOService子类)
#include <IOKit/IOService.h> #include <IOKit/registry/IORegistryEntry.h> #include <IOKit/OSNumber.h> #define DEFAULT_PARAM_VALUE 0x1000 #define NVRAM_PARAM_KEY "com.yourcompany.yourkext.customParam" class YourKext : public IOService { OSDeclareDefaultStructors(YourKext) private: uint64_t yourRuntimeParam; public: bool start(IOService* provider) override; void stop(IOService* provider) override; }; bool YourKext::start(IOService* provider) { if (!super::start(provider)) { return false; } // 获取NVRAM注册表节点 IORegistryEntry* nvram = IORegistryEntry::fromPath("/AppleACPIPlatformExpert/PCI0/_SB/NVRAM", gIOServicePlane); if (nvram) { OSObject* paramObj = nvram->readProperty(NVRAM_PARAM_KEY); if (paramObj) { // 转换为对应类型(此处以无符号64位整数为例) if (OSNumber* paramNum = OSDynamicCast(OSNumber, paramObj)) { yourRuntimeParam = paramNum->unsigned64BitValue(); } paramObj->release(); } else { // 无NVRAM参数,使用默认值 yourRuntimeParam = DEFAULT_PARAM_VALUE; } nvram->release(); } else { // 无法访问NVRAM,降级到默认值 yourRuntimeParam = DEFAULT_PARAM_VALUE; } // 其他初始化逻辑 return true; }
2. 停止时写入NVRAM参数
在kext的stop方法中,将当前运行时参数写入NVRAM。若NVRAM写入失败,降级到根文件系统的配置文件存储。
代码示例
void YourKext::stop(IOService* provider) { // 写入参数到NVRAM IORegistryEntry* nvram = IORegistryEntry::fromPath("/AppleACPIPlatformExpert/PCI0/_SB/NVRAM", gIOServicePlane); if (nvram) { OSNumber* paramNum = OSNumber::withNumber(yourRuntimeParam, sizeof(yourRuntimeParam)*8); if (paramNum) { nvram->setProperty(NVRAM_PARAM_KEY, paramNum); paramNum->release(); } nvram->release(); } else { // NVRAM不可用,降级到文件存储 FILE* fp = fopen("/var/db/yourkext_param.conf", "w"); if (fp) { fprintf(fp, "%llu\n", yourRuntimeParam); fclose(fp); } } super::stop(provider); } OSDefineMetaClassAndStructors(YourKext, IOService)
关键注意事项
- NVRAM键名规范:必须使用反向域名格式(如
com.yourcompany.yourkext.*),避免与系统或其他kext的NVRAM键冲突。 - 终端用户管理:用户可通过
nvram命令直接读写参数,无需修改kext:- 读取参数:
nvram com.yourcompany.yourkext.customParam - 修改参数:
sudo nvram com.yourcompany.yourkext.customParam=1234
- 读取参数:
- Apple Silicon机型兼容:部分Apple Silicon设备的NVRAM有安全限制,需确保kext在允许的权限范围内操作,测试时覆盖Intel和Apple Silicon平台。
- 性能优化:避免频繁写入NVRAM(如实时修改参数时),建议仅在kext停止或参数批量修改后执行写入操作。
- 降级方案可靠性:根文件系统可用时,文件存储可作为NVRAM的可靠降级选项,注意文件路径的权限(/var/db目录默认内核可读写)。
内容的提问来源于stack exchange,提问作者BUKTOP
相关产品推荐
相关产品推荐

