实际上,在做鸿蒙设备开发过程中,面对庞大的源码目录结构,很多开发者都会像我一样,一时半会儿摸不着头脑,或者陷入到对庞大的子系统/模块无尽的源码的阅读和分析中而耗费了大量的精力。但是这往往适得其反,耗费了很久的时间却总是感觉对很多概念一知半解,遇到实际的需求或问题,总是习惯于询问AI,但是对于AI给出的答案并不能很好地验证真伪。 作为一个进入鸿蒙开发领域接近两年的新人,尤其是许多和我一样从应用开发转向系统开发的开发者,一开始很容易晕头转向。所以我希望自己就像一个拼拼图或者搭积木的小孩,一点一点完善知识图谱,日拱一卒。
这期先来讲讲关于OpenHarmony(下面一律简称OH)操作系统,庞大工程当中最为关键的一个文件,也就是config.json这个文件,以下是摘自oh6.0-release分支的源码:
"product_name": "rk3568",
"device_company": "rockchip",
"device_build_path": "device/board/hihope/rk3568",
"target_cpu": "arm",
"type": "standard",
"version": "3.0",
"board": "rk3568",
"api_version": 8,
"enable_ramdisk": true,
"enable_absystem": false,
"build_selinux": true,
"build_seccomp": true,
"inherit": [ "productdefine/common/inherit/rich.json", "productdefine/common/inherit/chipset_common.json" ],
"subsystems": [
{
"subsystem": "security",
"components": [
{
"component": "selinux_adapter",
"features": []
}
]
},
{
"subsystem": "rockchip_products",
"components": [
{
"component": "rockchip_products",
"features": []
}
]
},
{
"subsystem": "arkui",
"components": [
{
"component": "ace_engine",
"features": [
"ace_engine_feature_enable_accessibility = true",
"ace_engine_feature_enable_web = true",
"ace_engine_feature_enable_upgrade_skia = true"
]
},
{
"component": "ui_appearance",
"features": []
}
]
},
{
"subsystem": "hdf",
"components": [
{
"component": "drivers_interface_lpplayer",
"features":[]
},
{
"component": "drivers_interface_ril",
"features": []
},
{
"component": "drivers_peripheral_ril",
"features":[]
},
{
"component": "drivers_interface_bluetooth",
"features": []
},
{
"component": "drivers_interface_audio",
"features": []
},
{
"component": "drivers_peripheral_audio",
"features": [
"drivers_peripheral_audio_feature_full_test_suite = true",
"drivers_peripheral_audio_feature_alsa_lib = false",
"drivers_peripheral_audio_feature_effect = true"
]
},
{
"component": "drivers_peripheral_codec",
"features": [
"drivers_peripheral_codec_feature_support_omx_extend_test = true",
"drivers_peripheral_codec_feature_support_hdi_v1 = true"
]
},
{
"component": "drivers_peripheral_display",
"features": [
"drivers_peripheral_display_community = true",
"drivers_peripheral_display_vdi_default = true"
]
},
{
"component": "drivers_peripheral_wlan",
"features": [
"drivers_peripheral_wlan_feature_enable_HDF_NL80211 = true",
"drivers_peripheral_wlan_feature_enable_HDF_UT = false",
"drivers_peripheral_wlan_feature_vendor = default",
"drivers_peripheral_wlan_p2p_name = p2p-dev-wlan0"
]
},
{
"component": "hdf_core",
"features": [
"hdf_core_platform_test_support = false",
"hdf_core_default_peripheral_config = false"
]
}
]
},
{
"subsystem": "startup",
"components": [
{
"component": "init",
"features": [
"init_feature_ab_partition = true"
]
}
]
},
{
"subsystem": "ai",
"components": [
{
"component": "mindspore",
"features": []
}
]
},
{
"subsystem": "msdp",
"components": [
{
"component": "device_status",
"features": [
"device_status_interaction_coordination = false"
]
}
]
},
{
"subsystem": "communication",
"components": [
{
"component": "netmanager_ext",
"features": [],
"syscap": [
"SystemCapability.Communication.NetManager.NetFirewall = false"
]
},
{
"component": "bluetooth_service",
"features": []
},
{
"component": "wifi",
"features": [
"wifi_feature_non_seperate_p2p = true",
"wifi_feature_non_hdf_driver = true",
"wifi_feature_p2p_random_mac_addr = true"
]
}
]
},
{
"subsystem": "multimedia",
"components": [
{
"component": "audio_framework",
"features": [
"audio_framework_feature_dtmf_tone = true",
"audio_framework_feature_opensl_es = true",
"audio_framework_feature_support_os_account = false"
]
},
{
"component": "video_processing_engine",
"features": []
},
{
"component": "image_framework",
"features": [
"image_framework_feature_upgrade_skia = true"
]
}
]
},
{
"subsystem": "castplus",
"components": [
{
"component": "sharing_framework",
"features": []
},
{
"component": "cast_engine",
"features": []
}
]
},
{
"subsystem": "thirdparty",
"components": [
{
"component": "rust_libc",
"features": []
},
{
"component": "libuv",
"features": [
"libuv_use_ffrt = true"
]
},
{
"component": "wpa_supplicant",
"features": [
"wpa_supplicant_driver_nl80211 = true"
]
},
{
"component": "pcre2",
"features": []
},
{
"component": "noto-cjk",
"features": []
},
{
"component": "notofonts",
"features": []
},
{
"component": "tex-hyphen",
"features": []
},
{
"component": "qrcodegen",
"features": [
"qrcodegen_feature_ace_engine_qrcode_able = true"
]
},
{
"component": "alsa-lib",
"features": [
"alsa_lib_feature_config_enable = true"
]
},
{
"component": "protobuf",
"features": []
},
{
"component": "abseil-cpp",
"features": []
},
{
"component": "libusb",
"features": []
},
{
"component": "skia",
"features": [
"skia_feature_upgrade = true"
]
},
{
"component": "optimized_routines",
"features": []
},
{
"component": "typescript",
"features": []
}
]
},
{
"subsystem": "tee",
"components": [
{
"component": "tee_client",
"features": []
}
]
},
{
"subsystem": "usb",
"components": [
{
"component": "usb_manager",
"features": [
"usb_manager_feature_pop_up_func_switch_model = false",
"usb_manager_feature_host = true",
"usb_manager_feature_device = true",
"usb_manager_feature_port = true"
]
}
]
},
{
"subsystem": "graphic",
"components": [
{
"component": "graphic_2d",
"features": [
"graphic_2d_feature_rs_enable_eglimage = true",
"graphic_2d_feature_use_texgine = true",
"graphic_2d_feature_upgrade_skia = true"
]
},
{
"component": "graphics_effect",
"features": []
},
{
"component": "graphic_surface",
"features": []
},
{
"component": "graphic_3d",
"features": []
},
{
"component": "graphic_utils_lite",
"features": []
},
{
"component": "vulkan-loader",
"features": []
},
{
"component": "vulkan-headers",
"features": []
}
]
},
{
"subsystem":"hiviewdfx",
"components": [
{
"component": "hiview",
"features": [
"hiview_feature_bbox_userspace = true",
"hiview_enable_leak_detector = true",
"hiview_enable_performance_monitor = true"
]
}
]
},
{
"subsystem": "ability",
"components": [
{
"component": "idl_tool",
"features": []
}
]
},
{
"subsystem": "telephony",
"components": [
{
"component": "core_service",
"syscap": [
"SystemCapability.Telephony.CoreService.Esim = false"
]
}
]
},
{
"subsystem": "sdk",
"components": [
{
"component": "sdk",
"features": []
}
]
},
{
"subsystem": "global",
"components": [
{
"component": "font_manager",
"features": []
}
]
},
{
"subsystem": "developtools",
"components": [
{
"component": "ace_ets2bundle",
"features": []
}
]
}
]
}
```js
这个配置文件非常重要,它决定了我们编译出来的镜像是如何被构建的,哪些子系统,被如何构建,这会涉及到将来一个很重要的概念,就是裁剪和定制,尤其是在设备开发领域,针对不同的开发板和硬件外设特性以及不同业务领域/行业的特点,都会非常普遍。在 OpenHarmony/HarmonyOS 的构建系统中,config.json 被称为产品定义件 (Product Definition File)。
它定义了“rk3568”这个产品具体包含哪些功能、使用什么硬件架构、以及由哪些软件子系统(Subsystems)和组件(Components)组成。
一、 总体来讲
文件内容分为基础信息配置和子系统配置两部分:
1. 基础信息配置
这些字段定义了产品的全局属性,直接影响编译系统的初始化。
"product_name": "rk3568"
作用:产品的唯一标识符。
影响:编译命令 ./build.sh --product-name rk3568 就是通过这个名字找到这个配置文件的。它决定了输出目录的名字(如 rk3568)。
"device_company": "rockchip"
作用:芯片或设备厂商名称。
影响:通常用于目录结构的查找,例如 device/rockchip 或 vendor/rockchip。
"device_build_path": "device/board/hihope/rk3568"
作用:指定该产品对应的板级(Board)配置路径。
影响:编译系统会去这个目录下找 BUILD.gn 或 ohos.build,加载板级特有的驱动和配置。
"target_cpu": "arm"
作用:目标 CPU 架构。
影响:决定了交叉编译器的选择(如使用 arm-linux-ohos-clang),以及生成的二进制文件格式(32位 ARM)。如果是 64 位通常是 arm64。
"type": "standard"
作用:系统类型。
影响:OpenHarmony 分为 mini (轻量系统), small (小型系统), standard (标准系统)。这里指定为标准系统,意味着支持完整的 ArkUI、多进程、多媒体等能力。
"version": "3.0"
作用:配置文件的版本,非系统版本。
"board": "rk3568"
作用:板型名称。
影响:用于内核编译时匹配设备树(DTS)和内核配置(Defconfig)。
"api_version": 8
作用:目标 API 版本。
"enable_ramdisk": true
作用:是否启用 Ramdisk(内存盘)。
影响:如果为 true,启动时会先加载 ramdisk.img,通常用于挂载 system 分区或进行早期初始化。
"enable_absystem": false
作用:是否启用 A/B 分区升级。
影响:如果为 true,分区表中会有 system_a, system_b 等,用于无缝 OTA 升级。
"build_selinux": true
作用:是否编译 SELinux(安全增强 Linux)。
影响:决定了是否生成 SELinux 策略文件,以及系统运行时是否进行强制访问控制。
"inherit": [ "productdefine/common/inherit/rich.json", "productdefine/common/inherit/chipset_common.json" ]
作用:继承机制。
影响:rich.json 包含了标准系统通用的组件列表(如电话、多媒体、窗口管理等),chipset_common.json 包含了芯片通用的配置。这非常重要,因为它意味着 config.json 不需要列出所有组件,只需要列出特有的或需要覆盖配置的组件。
2. 子系统配置 (subsystems 数组)
这部分定义了该产品具体包含哪些业务模块。
具体示例解释:
security (安全子系统):
selinux_adapter: 适配层组件。
arkui (UI 框架子系统):
ace_engine: ArkUI 的核心引擎。
features:
ace_engine_feature_enable_accessibility = true: 开启无障碍功能支持。
ace_engine_feature_enable_web = true: 开启 WebView 支持。
hdf (硬件驱动框架子系统):
这里列出了大量的驱动组件,如 audio (音频), display (显示), wlan (无线网)。
drivers_peripheral_audio: 音频外设驱动。
drivers_peripheral_audio_feature_alsa_lib = false: 表示不使用 ALSA 库,可能直接操作硬件或使用其他接口。
理解这部分内容,主要需要结合定制目标系统的具体业务要求。
**二、 配置细项对哪些模块生效? **
配置项主要通过以下两种方式生效:
组件裁剪 (Component Selection)————
生效范围:整个构建系统。
原理:如果 config.json (包括继承的 rich.json) 中没有列出某个组件,那么该组件的源码完全不会被编译。
例子:如果你把 drivers_peripheral_wlan 删掉,生成的镜像里就完全没有 Wi-Fi 驱动相关的库和可执行文件。
特性开关 (Features)————
生效范围:具体的组件源码 (BUILD.gn)。
原理:features 列表中的键值对会被转化为 GN (Generate Ninja) 构建参数。
例子:
在 config.json 中,在 ace_engine 的 BUILD.gn 源码中,会有类似这样的判断:
**三、 在什么地方发挥作用? **
这个文件在 编译构建阶段 (Build Time) 发挥核心作用。
hb set / build.sh 阶段:
当运行构建命令时,构建工具(hb 或 build.sh)首先读取此文件。
生成构建图 (GN Gen): 工具将 config.json 解析为全局的构建参数,它告诉 GN 编译器:“我要编译 rk3568,架构是 arm,包含 A、B、C 组件,其中 A 组件开启了 X 特性”。
编译链接:
Ninja 根据 GN 生成的构建图,调用编译器(Clang/GCC)编译具体的 .c/.cpp 文件。
**四、 如何理解它和整个项目的关系? **
你可以把 OpenHarmony 源码看作一个巨大的乐高积木仓库(包含成千上万个组件)。
而 config.json 就是一张拼装图纸。
仓库 (Source Code):foundation, drivers, applications 等目录下的所有代码。
图纸 (config.json):
它决定了从仓库里拿哪些积木(Components)。
它决定了积木怎么拼(Features,比如是拼成红色的车还是蓝色的车)。
它决定了底座是什么(Target CPU, Board)。
总结关系:
它是连接硬件(Board)与软件(Subsystems)的桥梁。如果你想为 rk3568 开发板增加一个系统功能(比如 NFC),或者裁剪掉一个功能(比如蓝牙),或者修改内核启动参数,你都需要修改这个文件或它引用的文件。
好了,下期准备讲讲具体的子系统;