ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

EDK II Redfish 平台的 JSON 处理基石:JsonLib(Jansson 2.13.1)封装库深度解析

EDK II Redfish 平台的 JSON 处理基石:JsonLib(Jansson 2.13.1)封装库深度解析 固件操作系统驱动开发嵌入式【免费下载链接】edk2EDK II项目地址https://gitcode.com/gh_mirrors/ed/edk2点击查看免费下载本篇技术指南聚焦 edk2 仓库中RedfishPkg/Library/JsonLib这一关键基础设施它如何将业界成熟的开源 JSON 库 Jansson 移植进 UEFI/EDK II 环境并以JsonLib.h封装出一套面向 Redfish 应用的 EDKII JSON API。读完本文你将掌握 Jansson 的核心设计理念、JsonLib 在 EDK II 中的构建集成方式含配置头文件与编译选项、其 API 映射与编码/解码标志的对应关系以及仓库内针对上游load.c构建问题的本地修复细节。一、Jansson被选中的 JSON 处理引擎RedfishPkg/Library/JsonLib/Readme.rst开篇即明确了 JsonLib 的第三方依赖Jansson——一个用于 JSON 数据的编码、解码与操作的 C 语言库。其核心特性与设计原则包括简单直观的 API 与数据模型以json_t为统一句柄对象、数组、字符串、整数、实数、布尔与 null 均通过同一套引用计数机制管理全面的文档Jansson 2.13 提供完整 API 参考对应版本文档位于官方 readthedocs 站点的 2.13 分支零外部依赖可独立编译便于嵌入到 UEFI 固件这类受控环境中完整 UnicodeUTF-8支持词法层直接处理多字节 UTF-8 序列并提供\uXXXX转义与代理对surrogate pair解码广泛的测试套件上游持续以自动化测试保障 API 稳定性。在许可与适用性方面Readme.rst 明确指出 Jansson 采用MIT 许可证详见仓库根目录的 License.txtAPI 稳定且已用于生产环境可运行于众多类 Unix 系统与 Windows既适用于桌面、服务器也适用于小型嵌入式系统——这与固件场景的需求高度吻合。事实依据以上结论均出自 Readme.rst属项目文档明确声明的信息。二、JsonLib 在 EDK II / Redfish 项目中的定位Readme.rst 特别强调在 UEFI/EDK II 环境中Redfish 项目消费consumeJansson 来实现 JSON 操作。这意味着 JsonLib 不是孤立模块而是整个 Redfish 栈的数据平面基础。Redfish 协议本身以 JSON 作为资源表述格式包括 REST 请求/响应体、属性清单、事件负载等因此 JsonLib 提供的能力直接决定了 Redfish 驱动与库对配置数据的解析与序列化效率。版本信息同样来自 Readme.rstedk2 上的 Jansson 版本为 2.13.1API 行为以该版本的官方参考手册为准EDK II 的 jansson 封装层JsonLib.h中定义了一组映射到 Jansson 函数的 EDKII JSON API作为 EDK II 与上游库之间的稳定适配边界。从仓库结构看JsonLib 的封装遵循 EDK II 标准库封装惯例公开 API 头文件放在包级 Include 目录RedfishPkg/Include/Library/JsonLib.h并在 RedfishPkg.dec 中注册为JsonLib|Include/Library/JsonLib.h的库类映射同时该 .dec 文件还将Library/JsonLib私有头文件与Library/JsonLib/jansson/src供引用jansson.h登记为 include 路径RedfishPkg.dec。三、库封装与构建集成JsonLib 作为 EDK II 库模块其构建描述位于 JsonLib.inf。关键元数据如下字段值说明BASE_NAMEJsonLib库名MODULE_TYPEDXE_DRIVER模块类型LIBRARY_CLASSJsonLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER允许被三类模块链接CONSTRUCTORJsonLibConstructor构造函数负责库初始化见下文源码组成JsonLib.inf分三组第三方 jansson 源码jansson/src/下的dump.c、error.c、hashtable.c、hashtable_seed.c、memory.c、pack_unpack.c、strbuffer.c、strconv.c、utf.c、value.c、version.c——覆盖了序列化dump、哈希表hashtable、内存分配钩子memory、打包/解包pack_unpack、UTF-8 处理utf与核心值模型value等全部模块。jansson 目录本身以 git 子模块形式挂载submodule 指向上游提交e9ebfa7e。edk2 封装层JsonLib.c、jansson_config.h、jansson_private_config.h。本地修复覆盖文件load.c解决上游构建问题详见第六节。依赖的库类JsonLib.infBaseLib、BaseMemoryLib、Ucs2Utf8Lib、RedfishCrtLib、DebugLib、MemoryAllocationLib、PrintLib、UefiRuntimeServicesTableLib、UefiLib。其中RedfishCrtLib为 Redfish 包内的 C 运行时替代库RedfishPkg.dec 注释说明 CRT 库供 edk2 JsonLib 使用用于在固件环境补齐fopen、strtol、snprintf等标准 C 函数JsonLib 与 RedfishCrtLib 均被纳入 RedfishPkg.dsc 参与包级构建。3.1 编译选项与警告抑制由于 Jansson 是面向宿主系统的 C 代码直接编入 EDK II 需要专门处理工具链差异。JsonLib.inf 的[BuildOptions]给出了 MSFT 与 GCC 两套策略JsonLib.infMSFTVS/wd4204 /wd4244 /wd4090 /wd4334 /wd4706抑制 const 限定符不一致、类型转换截断、32 位移位隐式转 64 位、非标准非 const 聚合初始化、条件表达式内赋值等警告避免在/WX下构建失败同时-DHAVE_CONFIG_H1让 jansson 源码包含jansson_private_config.h并通过/U_WIN32 /UWIN64 /U_MSC_VER屏蔽 Windows 预定义宏防止 jansson 走 MSVC 专用分支。GCC-Wno-unused-function -Wno-unused-but-set-variable容忍未使用函数与变量警告同样定义HAVE_CONFIG_H1并取消WIN32/_WIN32/WIN64/_MSC_VERX64 额外追加-DNO_MSABI_VA_FUNCS关闭 MS ABI 可变参数函数约定适配 GCC 的 SysV ABI 实现。3.2 配置头文件UEFI 环境的裁剪开关Jansson 原生通过 autotools/CMake 生成jansson_config.h而 JsonLib 用两份手工维护的头文件完成等价配置jansson_config.h文件本体声明了 UEFI 下的关键能力取舍宏值含义JSON_INLINE定义使用内联而非static inline适配 EDK II 编译环境JSON_INTEGER_IS_LONG_LONG1整数类型采用 64 位 long long对应封装层EDKII_JSON_INT_T为INT64JSON_HAVE_LOCALECONV0不支持 locale 相关转换避免依赖宿主 localeJSON_HAVE_ATOMIC_BUILTINS0禁用 GCC 原子内建函数JSON_HAVE_SYNC_BUILTINS0禁用 GCC 同步内建函数UEFI 单任务环境无需原子同步JSON_PARSER_MAX_DEPTH2048解析器最大嵌套深度限制jansson_private_config.h文件本体补充宏值含义HAVE_SYS_TIME_H1声明存在sys/time.hHAVE_SYS_TYPES_H1声明存在sys/types.hINITIAL_HASHTABLE_ORDER3对象哈希表初始容量阶2^3 8 个桶控制小对象的内存开销HAVE_UNISTD_H未在此定义这一细节正是第六节所述构建问题的修复开关所在。四、EDKII JSON API 封装JsonLib.h公开接口定义在 RedfishPkg/Include/Library/JsonLib.h共 945 行是 EDK II 侧唯一需要包含的头文件。其核心设计是将 Jansson 的json_t*句柄抽象为不透明指针typedef VOID *EDKII_JSON_VALUE; typedef VOID *EDKII_JSON_ARRAY; typedef VOID *EDKII_JSON_OBJECT;同时以typedef INT64 EDKII_JSON_INT_T;映射 Jansson 的json_int_t头文件注释明确对应JSON_INTEGER_IS_LONG_LONG置 1 的配置JsonLib.h。4.1 类型与错误模型EDKII_JSON_TYPE枚举JsonLib.hObject、Array、String、Integer、Real、True、False、Null八种类型与json_type一一对应EDKII_JSON_ERROR结构JsonLib.h映射json_error_t字段包括Line、Column、Position、Source80 字节错误来源标识如string/buffer与Text160 字节错误消息文本可用于定位解析失败的具体行列位置。4.2 解码标志Decoding Flags对应 Jansson 2.13 的json_loads/loadb系列标志JsonLib.hEDKII 宏值对应行为EDKII_JSON_REJECT_DUPLICATES0x1拒绝重复对象键默认允许后者覆盖前者EDKII_JSON_DISABLE_EOF_CHECK0x2禁用 EOF 检查允许解析多个 JSON 值EDKII_JSON_DECODE_ANY0x4允许根节点为任意 JSON 类型否则必须是对象或数组EDKII_JSON_DECODE_INT_AS_REAL0x8将整数按实数解码EDKII_JSON_ALLOW_NUL0x10允许字符串中出现\u00004.3 编码标志Encoding Flags对应json_dumps/dumpf系列JsonLib.hEDKII 宏值对应行为EDKII_JSON_MAX_INDENT/EDKII_JSON_INDENT(n)0x1F /(n)0x1F缩进控制0 为压缩1~31 为空格缩进量EDKII_JSON_COMPACT0x20紧凑输出去掉多余空白EDKII_JSON_ENSURE_ASCII0x40非 ASCII 字符转义为\uXXXX输出EDKII_JSON_SORT_KEYS0x80按键排序输出EDKII_JSON_PRESERVE_ORDER0x100保持插入顺序需要哈希表支持有序遍历EDKII_JSON_ENCODE_ANY0x200允许编码任意根类型EDKII_JSON_ESCAPE_SLASH0x400转义/为\/EDKII_JSON_REAL_PRECISION(n)((n)0x1F)11实数打印精度控制EDKII_JSON_EMBED0x10000嵌入模式JsonLib 扩展4.4 便利宏头文件还提供两个遍历宏JsonLib.hEDKII_JSON_ARRAY_FOREACH(Array, Index, Value)按索引遍历数组元素EDKII_JSON_OBJECT_FOREACH_SAFE(Object, N, Key, Value)通过迭代器安全遍历对象键值对N保存迭代游标以支持遍历中安全操作。4.5 函数族概览JsonLib.c文件本体32 KB实现全部封装函数覆盖值创建与释放JsonValueInitArray/Object/String/Integer/Real/True/False/Null、JsonValueFree、类型判断与取值JsonValueGetType、JsonValueGetString/Integer/Real/Boolean、对象操作JsonObjectSetValue/GetValue/Remove/ContainsKey、迭代器系列、数组操作JsonArrayAppend/Insert/Set/Get/Remove/Count、序列化与反序列化JsonDumpString、JsonLoadString等以及深拷贝/比较工具。所有创建型 API 遵循引用计数策略新值引用计数为 1由调用方通过JsonValueFree()释放与 Jansson 的json_incref/decref语义保持一致参见 JsonLib.h 中JsonValueInitArray的接口注释。五、构造函数与内存管理JsonLib 定义了JsonLibConstructor构造函数JsonLib.inf在模块加载时完成库级初始化。结合 Jansson 的memory.c设计可知Jansson 支持通过json_set_alloc_funcs()注入自定义内存分配器——这正是 UEFI 环境的关键适配点JsonLib 在构造函数中为 jansson 挂接 EDK II 的AllocatePool/FreePool体系确保第三方库的内存分配纳入固件的内存管理域避免与 UEFI 内存模型冲突这一结论由 JsonLib 依赖MemoryAllocationLib以及 jansson 可配置分配器机制共同推断。六、已知问题与本地修复load.c 的 stdin 条件编译Readme.rst 记录了 JsonLib 在集成过程中遇到并解决的唯一已知问题构建失败出现在jansson/src/load.c。修复方式是在load.c中增加代码根据HAVE_UNISTD_H宏条件性地使用 stdin。该修复 PR 已提交至 Jansson 开源社区akheron/jansson#558。在仓库中这一修复以独立覆盖文件RedfishPkg/Library/JsonLib/load.c 的形式存在1424 行并在 JsonLib.inf 中显式标注为修复构建问题的源码覆盖编译时替换上游同名文件参与构建。从源码看修复的实际落点非常清晰头文件条件包含load.c 用#ifdef HAVE_UNISTD_H包裹#include unistd.h避免在无 POSIX 环境的固件工具链中因缺失头文件而编译失败json_loadf的 stdin 判定load.c 中只有定义了HAVE_UNISTD_H时才将input stdin映射为错误来源stdin否则统一归为stream——UEFI 环境没有标准stdin概念此判定可防止对全局stdin符号的隐式依赖json_loadfd的 STDIN_FILENO 判定load.c 同样以HAVE_UNISTD_H保护对STDIN_FILENO宏的引用并在 fd_get_func 中把read()调用整体置于该宏保护之下。由于 edk2 的 jansson_private_config.h 刻意不定义HAVE_UNISTD_H只定义HAVE_SYS_TIME_H/HAVE_SYS_TYPES_H上述 stdin/read 相关代码路径在固件构建中会被整体剔除从而实现既不破坏编译、又保留宿主平台完整功能的双重目标。七、解析器实现纵深从 JSON 文本到 json_t深入本地 load.c 可以还原 Jansson 解析器的完整工作流这对理解 JsonLib 行为与错误报告至关重要词法分析lexerstream_t结构load.c按字节流驱动stream_getload.c负责多字节 UTF-8 序列的切分与校验utf8_check_first/utf8_check_full任何非法字节都会以json_error_invalid_utf8终止解析lex_scan_stringload.c处理转义序列、\uXXXX及 UTF-16 代理对合成语法分析parserparse_jsonload.c要求根节点为[或{除非置位JSON_DECODE_ANY随后递归调用parse_object/parse_array/parse_value构建对象树parse_valueload.c以lex-depth与JSON_PARSER_MAX_DEPTHedk2 配置为 2048配合检测栈溢出超过即报json_error_stack_overflow错误上下文错误对象记录行/列/位置并附带出错位置附近的文本片段error_setload.c非标准错误码如文件提前结束会细化映射为json_error_premature_end_of_input多种输入源本地 load.c 实现了六种入口——json_loads以\0结尾的 C 字符串load.c、json_loadb定长缓冲区load.c、json_loadfFILE*、json_loadfd文件描述符、json_load_file路径打开文件与json_load_callback回调式增量读取内置 1024 字节缓冲load.c。其中json_loadb与json_loads最贴合固件场景——Redfish 消息通常以内存缓冲区形式到达无需文件系统支持。这也解释了为何 JsonLib 能在无文件系统的 UEFI 阶段正常工作JsonLib 封装层主要面向字符串/缓冲区输入文件与 fd 入口保留给宿主侧工具链或具备文件系统的运行阶段使用。八、如何在 EDK II 项目中启用 JsonLib若要在自定义平台中使用 JsonLib通常需要以下三步依据仓库现有配置整理包依赖确保平台 .dsc 的[Packages]包含MdePkg/MdePkg.dec、MdeModulePkg/MdeModulePkg.dec与RedfishPkg/RedfishPkg.dec参见 JsonLib.inf库引用在模块 .inf 的[LibraryClasses]声明JsonLib或在平台 .dsc 的[LibraryClasses.common]中指定JsonLib|RedfishPkg/Library/JsonLib/JsonLib.infJsonLib 支持被 DXE_DRIVER、UEFI_APPLICATION、UEFI_DRIVER 三类模块链接包含头文件源码中#include Library/JsonLib.h即可使用EDKII_JSON_VALUE等全部 API无需直接引用 jansson 头文件。包级构建时RedfishPkg.dsc 已默认编译 JsonLib 与 RedfishCrtLibRedfish 系驱动如 RedfishDiscoverDxe、RedfishRestExDxe均在此基础上获得统一的 JSON 处理能力。九、小结JsonLib 是 edk2 中 Redfish 功能栈与第三方 Jansson 之间的桥梁上游提供成熟稳定的 JSON 引擎MIT 许可、零依赖、UTF-8 完备、测试充分JsonLib 通过 JsonLib.inf 的精细化构建配置、jansson_config.h 与 jansson_private_config.h 的能力裁剪、JsonLib.h 的类型/标志映射以及 load.c 的本地修复将这一通用库无缝嵌入 UEFI 固件环境。理解这一层的设计无论是排查 Redfish 数据解析问题还是为其他固件场景引入 JSON 能力都能直接复用本文所述的移植方法论。赞分享固件操作系统驱动开发嵌入式【免费下载链接】edk2EDK II项目地址https://gitcode.com/gh_mirrors/ed/edk2点击查看免费下载相关推荐EDK II 平台项目教程EDK II 平台项目教程 1. 项目介绍 EDK II 平台项目EDK II Platforms是一个开源项目旨在提供基于 EDK II 的示例平台分支EDK II 平台项目教程EDK II 平台项目教程 1. 项目的目录结构及介绍 EDK II 平台项目 edk2 platforms 是一个开源项目主要用于开发和维护基于 EDK I探索EDK II平台开源UEFI固件的未来探索EDK II平台开源UEFI固件的未来 项目介绍 EDK II平台项目是一个开源的UEFI固件开发框架旨在为各种硬件平台提供统一的固件支持。该项目基于上一篇Melody你的私人音乐管理精灵下一篇Google Code Search 使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表