From 8cdbbc612c832849b9849157b91732e62bb52f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E9=B9=8F=E5=8A=9F?= <1071996491@qq.com> Date: Thu, 20 Jan 2022 12:03:35 +0000 Subject: [PATCH] =?UTF-8?q?update=20zh-cn/readme/=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E5=AD=90=E7=B3=BB=E7=BB=9F.md.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...15\345\255\220\347\263\273\347\273\237.md" | 1676 ++++++++++++++--- 1 file changed, 1405 insertions(+), 271 deletions(-) diff --git "a/zh-cn/readme/\345\220\257\345\212\250\346\201\242\345\244\215\345\255\220\347\263\273\347\273\237.md" "b/zh-cn/readme/\345\220\257\345\212\250\346\201\242\345\244\215\345\255\220\347\263\273\347\273\237.md" index 7a48733cb1d..d2e76ff4aaa 100755 --- "a/zh-cn/readme/\345\220\257\345\212\250\346\201\242\345\244\215\345\255\220\347\263\273\347\273\237.md" +++ "b/zh-cn/readme/\345\220\257\345\212\250\346\201\242\345\244\215\345\255\220\347\263\273\347\273\237.md" @@ -1,305 +1,1439 @@ -# 启动恢复子系统 - -- [简介](#section11660541593) -- [目录](#section161941989596) -- [约束](#section1718733212019) -- [使用说明](#section8533192617117) -- [相关仓](#section1371113476307) - -## 简介 - -启动恢复负责在内核启动之后到应用启动之前的系统关键进程和服务的启动过程以及设备恢复出厂设置的功能。涉及以下组件: - -- init组件 - - 支持使用LiteOS-A内核的平台,当前包括:Hi3516DV300平台和Hi3518EV300平台。 - - 负责处理从内核加载第一个用户态进程开始,到第一个应用程序启动之间的系统服务进程启动过程。启动恢复子系统除负责加载各系统关键进程之外,还需在启动的同时设置其对应权限,并在子进程启动后对指定进程实行保活(若进程意外退出要重新启动),对于特殊进程意外退出时,启动恢复子系统还要执行系统复位操作。 - - -- appspawn应用孵化器组件 - - 支持使用LiteOS-A内核的平台,当前包括:Hi3516DV300平台和Hi3518EV300平台。 - - 负责接受应用程序框架的命令孵化应用进程,设置其对应权限,并调用应用程序框架的入口。 - -- bootstrap启动引导组件 - - 支持使用LiteOS-M内核的平台,当前包括:Hi3861平台。 - - 提供了各服务和功能的启动入口标识。在SAMGR启动时,会调用boostrap标识的入口函数,并启动系统服务。 +1.前言 -- syspara系统属性组件 +2. openharmony-sig规划目录 - 负责提供获取与设置操作系统相关的系统属性。 +3. 鸿蒙框架文件说明 - LiteOS-M内核和LiteOS-A内核的平台,包括:Hi3861平台,Hi3516DV300平台,Hi3518EV300平台。支持的系统属性包括:默认系统属性、OEM厂商系统属性和自定义系统属性。OEM厂商部分仅提供默认值,具体值需OEM产品方按需进行调整,详见“[使用说明](#section8533192617117)”部分。 +3.1. config.gni文件解析 +3.1.1. 目录结构 -## 目录 +3.1.2. 配置项解析 -**表 1** 启动恢复源代码目录结构 +3.1.3. 参考案例 - - - - - - - - - - - - - - - - - - - - - - - -

名称

-

描述

-

适配平台

-

base/startup/appspawn_lite

-

应用孵化器组件,appspawn进程,负责通过IPC机制接收Ability Manager Service消息,然后根据消息解析结果启动应用进程并赋予其对应权限。

-

Hi3516DV300

-

Hi3518EV300

-

base/startup/bootstrap_lite

-

启动引导组件,启动系统核心服务外的其他服务。

-

Hi3861

-

base/startup/init_lite

-

init组件,init进程,内核完成初始化后加载的第一个用户态进程,启动后解析/etc/init.cfg配置文件,并根据解析结果拉起其他系统关键进程,同时分别赋予其对应权限。

-

Hi3516DV300

-

Hi3518EV300

-

base/startup/syspara_lite

-

系统属性组件。提供获取设备信息接口,如:产品名、品牌名、品类名、厂家名等。

-

Hi3861

-

Hi3516DV300

-

Hi3518EV300

-
+3.2. config.json文件解析 + +3.2.1. 目录结构 + +3.2.2. 配置项解析 + +3.2.3. 参考案例 + +3.3. fs.yml文件解析 + +3.3.1. 目录结构 + +3.3.2. 配置项解析 + +3.3.3. 参考案例 + +4. 内核和文件系统适配范例 + +4.1. 内核适配 + +4.1.1. Hilog + +4.1.2. Hievent + +4.1.3. Binder IPC支持 + +4.1.4. 新增加模块Hilog/Hievent内核编译 + +4.1.5. 内核移植验证 + +4.2. 文件系统适配 + +4.2.1. 编译工具链替换 + +4.2.2. fs.yml + +4.2.3. config.json + +4.2.4. 驱动节点创建 + +4.2.5. Busybox集成与startup启动子系统 + +4.3. 启动文件init_linux_5\_10_x2000.cfg + +5. Small鸿蒙最小子系统列表 + +6. xts测试 + +7. 南向服务包接口 + +### 前言 + + +本文以X2000为例旨在帮助芯片商快速接入OpenHarmony small系统,芯片产品实现从鸿蒙框架搭建,编译工具链替换,内核接入,rootfs文件子系统,shell以及启动子系统。 + +- 1. X2000系统环境:uboot.img + bootload.img + Linux5.1 + rootfs.img +- 1. 鸿蒙适配修改限制:Linux5.1 + rootfs.img + +编译工具链:当前时刻(20220105)使用芯片厂工具链,主要考虑三方sdk编译以及工具链厂商可能做定制 + +目前已有多款芯片适配,修改记录可以参考: + +(1) openharmony-sig社区项目 + +[https://gitee.com/openharmony-sig/device_ingenic](https://gitee.com/openharmony-sig/device_ingenic) + +(2) 其他支撑项目提交记录 + +[https://gitee.com/flyingfishercn/support-rockchip-rk3326](https://gitee.com/flyingfishercn/support-rockchip-rk3326) + +[https://gitee.com/flyingfishercn/support-ingenic-t31](https://gitee.com/flyingfishercn/support-ingenic-t31)(Todo此款亟待涂鑫鑫在外网上库) + +# openharmony-sig规划目录 + +OH Dev-Board-SIG介绍 + +[https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md](https://gitee.com/openharmony/community/blob/master/sig/sig-devboard/sig_devboard_cn.md) + +社区规划目录 + +- LTS3.0以下 + +Device:放置芯片厂家相关适配 + +vendor:放置终端厂家相关适配 + +manifest:放置拼仓相关信息,组合LTS基线+device仓+vendor仓 + +- Master或者LTS3.1版本后 + +Todo:龙海涛出于IDE能力中心的考虑,结合Soc/Board分离,服务包对此处目录有新的规划,此部分新的可能要随时保持更新。目前正在做打样 + +# 鸿蒙框架文件说明 + +## config.gni文件解析 + +### 目录结构 + +config.gni目录结构大致如下: + +``` + device + └──MyCompany #芯片解决方案厂商 + └──MyBoard #开发板名称 + ├──BUILD.gn #编译脚本 + └──linux #内核类型,也可以是liteos_a等 + └──config.gni #linux版本编译配置 +``` + +### 配置项解析 + +构建系统默认使用ohos-clang编译工具链,也支持芯片解决方案厂商按开发板自定义配置。开发板编译配置文件编译相关的变量,如下: + +- kernel_type: 开发板使用的内核类型,例如:\"liteos_a\", \"liteos_m\",\"linux\"。 +- kernel_version: 开发使用的内核版本,例如:\"4.19\"。 +- board_cpu: 开发板CPU类型,例如:\"cortex-a7\", \"riscv32\"。 +- board_arch: 开发芯片arch, 例如: \"armv7-a\", \"rv32imac\"。 +- board_toolchain: + 开发板自定义的编译工具链名称,例如:\"gcc-arm-none-eabi\"。若为空,则使用默认为ohos-clang。 +- board_toolchain_prefix: + 编译工具链前缀,例如:\"gcc-arm-none-eabi\"。 +- board_toolchain_type: + 编译工具链类型,目前支持gcc和clang。例如:\"gcc\" ,\"clang\"。 +- board_cflags: 开发板配置的c文件编译选项。 +- board_cxx_flags: 开发板配置的cpp文件编译选项。 +- board_ld_flags: 开发板配置的链接选项。 + +编译构建会按产品选择的开发板,加载对应的config.gni,该文件中变量对系统组件全局可见。 + +### 参考案例 + +具体可参考 + +## config.json文件解析 + +### 目录结构 + +``` +vendor +└──MyCompany #产品解决方案厂商名称 +└──MyProduct #产品名称 +├──BUILD.gn #产品编译脚本 +└──config.json #产品配置文件 +``` + +### 配置项解析 + +编写产品配置信息: +在上述新建的产品配置文件config.json为编译构建的主入口,包含了开发板、OS组件和内核等配置信息。以demo为例,若只添加一个内核子系统, + +``` +{ + "product_name": "My_Product_demo", + "ohos_version": "OpenHarmony 1.0", + "device_company": "MyCompany", + "board": "MyBoard", + "kernel_type": "linux", + "kernel_version": "5.10", + "subsystems":[ + { + "subsystem": "kernel", + "compnonents": [ + { "component": "linux_5_10", "features":[]} + ] + } + ], + "vendor_adapter_dir": "//device/MyCompany/hardware", + "third_party_dir": "//third_party", + "product_adapter_dir": "//vendor/MyCompany/MyProduct/hals", + "ohos_product_type": "", + "ohos_manufacture": "", + "ohos_brand": "", + "ohos_market_name": "", + "ohos_product_series": "", + "ohos_product_model": "", + "ohos_software_model": "", + "ohos_hardware_profile": "", + "ohos_serial": "", + "ohos_bootloader_version": "", + "ohos_secure_patch_level": "", + "ohos_abi_list": "" +} +``` + +- product_name:产品名称,支持自定义; +- ohos_version:OpenHarmony版本号,应与实际下载的版本一致; +- device_company:芯片解决方案厂商名称,与device的二级目录名称一致; +- board:开发板名称,与device的三级目录名称一致; +- kernel_type:内核类型,应与开发板支持的内核类型匹配; +- board_version:内核版本号,应与开发板支持的内核版本匹配; +- subsystem:产品选择的子系统,应为OS支持的子系统。OS支持的子系统请见build/lite/components目录下的各子系统描述文件; +- components:产品选择的某个子系统下的组件,应为某个子系统支持的组件。子系统支持的组件请见build/lite/components/子系统.json文件; +- features:产品配置的某个组件的特性,组件支持的特性请见build/lite/components/子系统.json中对应组件的feature字段。 + +注意:编译构建系统编译前会对device_company,board,kernel_type,kernel_version,subsystem,component字段进行有效性检查,其中 +device_company,board,kernel_type,kernel_version应与已知的芯片解决方案匹配,subsystem,component应与build/lite/components下的组件描述匹配。 + +### 参考案例 + +具体可参考 + +## fs.yml文件解析 + +### 目录结构 + +vendor +└──MyCompany +└──MyProduct +└──BUILD.gn +└──config.json +└──fs.yml + +### 配置项解析 + +\- + + fs_dir_name: rootfs + + fs_dirs: + + - + + source_dir: bin + + target_dir: bin + + ignore_files: + + - query.bin + + - cve + + - checksum + + is_strip: TRUE + + - + + source_dir: libs/lib + + target_dir: lib + + ignore_files: + + - .a + + is_strip: TRUE + + dir_mode: 755 + + file_mode: 644 + + - + + source_dir: usr/sbin + + target_dir: usr/sbin + + - + + source_dir: usr/bin + + target_dir: usr/bin + + - + + source_dir: usr/lib + + target_dir: usr/lib + + ignore_files: + + - .a + + is_strip: TRUE + + dir_mode: 755 + + file_mode: 644 + + - + + source_dir: vendor + + target_dir: vendor + + - + + source_dir: config + + target_dir: etc + + - + + source_dir: system + + target_dir: system + + - + + source_dir: etc + + target_dir: etc + + - + + source_dir: sbin + + target_dir: sbin + + - + + source_dir: obj/foundation/distributedschedule/samgr_lite/config + + target_dir: etc + + - + + source_dir: + +\${root_path}/prebuilts/gcc/linux-x86/mips/mips-gcc720-glibc226/mips-linux-gnu/libc/mfp64/lib + + target_dir: lib + + ignore_files: + + - .a + + is_strip: TRUE + + dir_mode: 755 + + file_mode: 644 + + - + + target_dir: storage + + - + + target_dir: dev/root + + - + + target_dir: proc + + - + + target_dir: dev/pts + + - + + target_dir: dev/shm + + - + + target_dir: tmp + + - + + target_dir: run + + - + + target_dir: sys + + fs_filemode: + + - + + file_dir: \"lib/ld-2.26.so\" + + file_mode: 500 + + - + + file_dir: \"bin/shell\" + + file_mode: 500 + + fs_symlink: + + - + + source: mksh + + link_name: \${fs_dir}/bin/shell + + - + + source: mksh + + link_name: \${fs_dir}/bin/sh + + - + + source: libstdc++.so.6.0.24 + + link_name: \${fs_dir}/lib/libstdc++.so.6 + + - + + source: libstdc++.so.6.0.24 + + link_name: \${fs_dir}/lib/libstdc++.so + + - + + source: libgomp.so.1.0.0 + + link_name: \${fs_dir}/lib/libgomp.so.1 + + - + + source: libgomp.so.1.0.0 + + link_name: \${fs_dir}/lib/libgomp.so + + fs_make_cmd: + + - \${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh \${fs_dir} + +ubifs + +\- + + fs_dir_name: userfs + + fs_dirs: + + - + + source_dir: obj/base/security/services/app_verify/config + + target_dir: data/verify + + - + + source_dir: storage/etc + + target_dir: etc + + - + + source_dir: data + + target_dir: data + + - + + target_dir: app + + - + + target_dir: data/system/param + + fs_make_cmd: + + - \${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh \${fs_dir} + +ubifs 52428800 + + fs_attr: + + tee_enable: + + fs_dirs: + + - + + target_dir: data/sec_storage_data + + - + + target_dir: sec_storage + +fs.yml中重点字段解释: fs.yml由多列表组成,每个列表对应一个文件系统镜像 + +fs_dir_name:必填,声明文件系统名(如rootfs、userfs) + +fs_dir:选填,配置out下文件目录与文件系统文件目录的映射关系,每个文件目录对应一个列表 + +source_dir:选填,out下目标文件目录,若缺失则将根据target_dir在文件系统下创建空目录 + +target_dir:必填,文件系统下对应文件目录 + +ignore_files:选填,声明拷贝忽略文件 + +dir_mode:选填,文件目录权限,默认755 + +file_mode:选填,该文件目录下所有文件的权限,默认555 + +fs_filemode:选填,配置需要特殊声明权限的文件,每个文件对应一个列表 + +file_dir:必填,文件系统下具体文件路径 + +file_mode:必填,文件权限权限声明 + +fs_symlink:选填,配置文件系统软连接 + +fs_make_cmd:选填,配置需要执行命令,每条命令对应一个列表 + +这里是列表文本fs_attr:选填,根据配置项动态调整文件系统 + +此文件中,主要进行rootfs内容的拷贝,然后制作文件系统; + +注:如果涉及更改编译器,可以在此文件中拷贝libc库到rootfs +lib中,构建运行环境 + +◈由于demo中设置生成的是ubifs类型的文件系统,不是OpenHarmony默认支持的文件系统类型,因此需要在build/lite/make_rootfs/rootfsimg_linux.sh中添加一下内容: + +elif \[ \"\${FSTYPE}\" = \"ubifs\" \]; then + + if \[ \"\${system}\" != \"Linux\" \]; then + + echo \"Unsupported fs type!\" \>&2 + + else + + if \[ \$# -eq 3 \]; then + + EMMC_ROOTFS_SIZE=\$3 + + else + + if \[\[ \"\${ROOTFS_DIR}\" = \*\"rootfs\" \]\]; then + + EMMC_ROOTFS_SIZE=50 + + else + + EMMC_ROOTFS_SIZE=50 + + fi + + fi + + mkfs.ubifs -d \${ROOTFS_DIR} -e 0x1f000 -c 2048 -m 0x800 -x lzo + +-o \${ROOTFS_IMG} + + fi + +◈编译出内核镜像和文件系统镜像,如下所示: + +rootfs_ubi + +fs.imguImageuser + +fs_ubifs.img + +### 参考案例 + +具体可参考 + +# 内核和文件系统适配范例 + +根据实际项目来看,内核和文件系统可以采用不同的编译器单独编译。如果内核需要单独编译,config.json可以直接剔除kernel子系统,然后内核单独自行编译即可。 + +鉴于x2000芯片已上库社区,因此本文档以x2000作例来说明。本款芯片适配的Linux5.10内核,内核文件比较大,社区上传中移除了内核源码适配。 + +备注:本款芯片内核和文件系统采用同一款编译器。 + +x2000地址: + +## 内核适配 + +规则1:目前社区已支持4.19和5.10版本,请客户内核优先升级到此版本 + +规则2:客户内核代码包含原有驱动以及优化,所以建议直接复用客户内核,做侵入式修改 + +如下为内核修改参考 + +### Hilog + +作用:鸿蒙日志记录,占用静态节点245。存在和三方芯片节点冲突的可能性 + +新增目录: + +[kernel/linux-4.19.172/drivers/staging/hilog/](https://gitee.com/flyingfishercn/support-rockchip-rk3326/blob/7dba713df7a332ce5ebf12b1ecf03fbda6a2f56e/kernel/linux-4.19.172/drivers/staging/hilog/hilog.c) + +修改上级目录如下文件,添加模块 + +[kernel/linux-4.19.172/drivers/staging/Kconfig](https://gitee.com/flyingfishercn/support-rockchip-rk3326/blob/7dba713df7a332ce5ebf12b1ecf03fbda6a2f56e/kernel/linux-4.19.172/drivers/staging/hilog/hilog.c) + +kernel/linux-4.19.172/drivers/staging/Makefile + +### Hievent + +作用:占用静态节点241。存在和三方芯片节点冲突的可能性 + +新增目录 + +[kernel/linux-4.19.172/drivers/staging/hievent](https://gitee.com/flyingfishercn/support-rockchip-rk3326/blob/7dba713df7a332ce5ebf12b1ecf03fbda6a2f56e/kernel/linux-4.19.172/drivers/staging/hievent/Kconfig) + +修改上级目录如下文件,添加模块 + +[kernel/linux-4.19.172/drivers/staging/Kconfig](https://gitee.com/flyingfishercn/support-rockchip-rk3326/blob/7dba713df7a332ce5ebf12b1ecf03fbda6a2f56e/kernel/linux-4.19.172/drivers/staging/hilog/hilog.c) + +kernel/linux-4.19.172/drivers/staging/Makefile + +备注:Hilog/Hievent采用静态节点,存在和驱动文件节点冲动的可能性。 + +社区已提单: + +### Binder IPC支持 + +作用:鸿蒙系统中存在跨进程调用 + +修改路径 + +kernel/linux-4.19.172/drivers/android/binder.c + +kernel/linux-4.19.172/include/uapi/linux/android/binder.h + +### 新增加模块Hilog/Hievent内核编译 + +每个厂家对新增模块的处理各不相同,具体咨询对应的厂商 + +- 样例1 + +#瑞芯微 + +make ARCH=arm64 rockchip_linux_defconfig + +make ARCH=arm64 menuconfig + +make ARCH=arm64 savedefconfig + +cp .defconfig arch/arm64/configs/rockchip_linux_defconfig + +- 样例2 + +#x2000 + +make halley5_v20_linux_hdf_defconfig + +make menuconfig + +cp .config arch/arm64/configs/halley5_v20_linux_hdf_defconfig + +其中make menuconfig后,勾选hilog和hievent + +确保新增模块已编译进内核。 + +### 内核移植验证 + +Binder移植成功后,可以看到/dev/binder节点 + +Hilog/Hievent后续在4.2文件系统章节需要做更多的操作。 + +## 文件系统适配 + +### 编译工具链替换 + +源码:device/ingenic/x2000/linux/config.gni + +``` + kernel_type = \"linux\" + + + + \# Kernel version. + + kernel_version = \"5.10\" + + + + \# Board CPU type, e.g. \"cortex-a7\", \"riscv32\". + + board_cpu = \"\" + + + + \# Board arch, e.g. \"armv7-a\", \"rv32imac\". + + board_arch = \"mips32r2\" + + + + \# Toolchain name used for system compiling. + + \# E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, +riscv32-unknown-elf. + + \# Note: The default toolchain is \"ohos-clang\". It\'s not mandatory +if you use the default toochain. + + board_toolchain = \"mips-linux-gnu-gcc\" + + + + \# The toolchain path instatlled, it\'s not mandatory if you have +added toolchian path to your \~/.bashrc. + + board_toolchain_path = + + +rebase_path(\"../prebuilt/gcc/linux-x86/mips/mips-gcc720-glibc226/bin\") + + + + \# Compiler prefix. + + board_toolchain_prefix = \"mips-linux-gnu-\" + + + + \# Compiler type, \"gcc\" or \"clang\". + board_toolchain_type = \"gcc\" + + + \# Board related common compile flags. + board_cflags = \[ + \"-mips32r2\", + \"-mfp64\", + +\"-fpic\", + \"-D_GNU_SOURCE\" + \] + board_cxx_flags = \[ + + \"-mips32r2\", + + \"-mfp64\", + + \"-fpic\" + + \] + + board_rpath = rebase_path(root_out_dir) + + board_ld_flags = \[ + + \"-Wl,-rpath-link=\${board_rpath}/libs/lib +,-rpath-link=\${board_rpath}\", + + \"-latomic\", + + \"-lpthread\", + + \"-ldl\", + + \"-lrt\", + +\] + + + + \# Board related headfiles search path. + board_include_dirs = \[\] + + board_include_dirs += \[ +rebase_path(\"../prebuilt/gcc/linux-x86/mips/mips-gcc720-glibc226/mips-linux-gnu/libc/usr/include\") +\] + + \# Board adapter dir for OHOS components. + board_adapter_dir = \"\" + + \# Sysroot path. + board_configed_sysroot = \"\" +``` + + + +在升级LTS基线时,经常会遇到库找不到的问题。使用rpath-link解决 + +### fs.yml + +fs.yml由./build/lite/hb/build/fs_process.py操作生成img动作。其中主要有拷贝动作,以及编译打包等 + +摘取x2000关键源码说明如下 + +``` +- + +fs_dir_name: rootfs //rootfs img +fs_dirs: + - + source_dir: buildroot-intermediate/target +//芯片厂sdk编译出的二进制文件 + + target_dir: ../rootfs //将source_dir拷贝到rootfs目录下 + + - + + source_dir: bin + + target_dir: bin + + fs_make_cmd: //打包命令 + + - \${root_path}/vendor/ingenic/smartpen/system/rootfsimg_linux.sh +\${fs_dir} ext4 400 + + fs_dir_name: userfs //userfs img + + fs_make_cmd: //打包命令 + + - \${root_path}/vendor/ingenic/smartpen/system/rootfsimg_linux.sh +\${fs_dir} ext4 100 +``` + + + +### config.json + +调试开机阶段config.json仅仅保留startup子系统即可。其他子系统可以待开机能shell交互后再添加。 + +### 驱动节点创建 + +前述内核添加了模块Hilog/Hievent,在文件系统/etc/init.d/rcS中需要添加相应的启动项 + +源码:vendor/ingenic/smartpen/rootfs-overlay/etc/init.d/S82ohos + +``` + copy(\"rootfs-overlay\") { + + sources = \[ \"etc\" \] + + outputs = \[ \"\$root_out_dir/\" \] + + } +``` + + + +源码:./vendor/ingenic/smartpen/rootfs-overlay/etc/init.d/rcS + +```c + /etc/init.d/S13swap start + + /etc/init.d/S12storage start + + /etc/init.d/S21data start + + /etc/init.d/S23resource start + + /etc/init.d/S82ohos start +``` + +源码:vendor/ingenic/smartpen/rootfs-overlay/etc/init.d/S82ohos + +```c + #!/bin/sh + + echo \"S82 ohos start\" + + mknod /dev/hilog c 245 1 + + chmod 666 /dev/hilog + + mknod /dev/hwlog_exception c 241 1 + + chmod 666 /dev/hwlog_exception + + chmod 777 /dev/sys + + chmod 777 /dev/mem +``` + +### Busybox集成与startup启动子系统 + +鸿蒙目前的命令行采用toybox。实际调查多家客户得知客户多采用busybox来做系统引导,以及命令行。和鸿蒙认证沟通得知toybox为系统认证需要。所以在系统中busybox和toybox均需要集成。 + +源码:linux-5.10/init/main.c + +//如下为内核的启动init的搜索路径,任意一个启动成功即返回 + +```c + if (!try_to_run_init_process(\"/sbin/init\") \|\| + !try_to_run_init_process(\"/etc/init\") \|\| +!try_to_run_init_process(\"/bin/init\") \|\| + !try_to_run_init_process(\"/bin/sh\")) + return 0; + + panic(\"No working init found. Try passing init= option to kernel. +\" + \"See Linux Documentation/admin-guide/init.rst for guidance.\"); +init组件负责处理从内核加载第一个用户态进程开始,到第一个应用程序启动之间的系统服务进程启动过程。启动恢复子系统除负责加载各系统关键进程之外,还需在启动的同时设置其对应权限,并>在子进程启动后对指定进程实行保活(若进程意外退出要重新启动),对于特殊进程意外退出时,启动恢复子系统还要执行系统复位操作。 +``` + +init中的流程 + +**一、“pre-init”阶段:启动系统服务之前需要先执行的操作,例如挂载文件系统、创建文件夹、修改权限等** + + **1.打印系统信息** + +```c + // 1. print system info + PrintSysInfo(); + +``` + +```c +static void PrintSysInfo() +{ +#ifdef OHOS_LITE + const char* sysInfo = GetVersionId(); + if (sysInfo != NULL) { + INIT_LOGE("%s", sysInfo); + return; + } + INIT_LOGE("main, GetVersionId failed!"); +#endif +} + +``` + + **2.挂载文件系统,并且创建device节点** + +```c + // 2. Mount basic filesystem and create common device node. + MountBasicFs(); + CreateDeviceNode(); + MakeSocketDir("/dev/unix/socket/", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); + +``` + +```c +void MountBasicFs() +{ + if (mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755") != 0) { + INIT_LOGE("Mount tmpfs failed. %s", strerror(errno)); + } +#ifndef __LITEOS__ + if (mkdir("/dev/pts", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { + INIT_LOGE("mkdir /dev/pts failed. %s", strerror(errno)); + } + if (mount("devpts", "/dev/pts", "devpts", 0, NULL) != 0) { + INIT_LOGE("Mount devpts failed. %s", strerror(errno)); + } +#endif + if (mount("proc", "/proc", "proc", 0, "hidepid=2") != 0) { + INIT_LOGE("Mount procfs failed. %s", strerror(errno)); + } + if (mount("sysfs", "/sys", "sysfs", 0, NULL) != 0) { + INIT_LOGE("Mount sysfs failed. %s", strerror(errno)); + } +#ifndef __LITEOS__ + if (mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL) != 0) { + INIT_LOGE("Mount selinuxfs failed. %s", strerror(errno)); + } +#endif +} +void CreateDeviceNode() +{ + if (mknod("/dev/kmsg", S_IFCHR | DEFAULT_NO_AUTHORITY_MODE, makedev(1, DEVICE_ID_ELEVNTH)) != 0) { + INIT_LOGE("Create /dev/kmsg device node failed. %s", strerror(errno)); + } + if (mknod("/dev/null", S_IFCHR | DEFAULT_RW_MODE, makedev(1, DEVICE_ID_THIRD)) != 0) { + INIT_LOGE("Create /dev/null device node failed. %s", strerror(errno)); + } + if (mknod("/dev/random", S_IFCHR | DEFAULT_RW_MODE, makedev(1, DEVICE_ID_EIGHTH)) != 0) { + INIT_LOGE("Create /dev/random device node failed. %s", strerror(errno)); + } + + if (mknod("/dev/urandom", S_IFCHR | DEFAULT_RW_MODE, makedev(1, DEVICE_ID_NINTH)) != 0) { + INIT_LOGE("Create /dev/urandom device node failed. %s", strerror(errno)); + } +} +int MakeSocketDir(const char *path, mode_t mode) +{ + int rc = mkdir("/dev/unix/", mode); + if (rc < 0 && errno != EEXIST) { + INIT_LOGE("Create %s failed. %d", path, errno); + return -1; + } + rc = mkdir("/dev/unix/socket/", mode); + if (rc < 0 && errno != EEXIST) { + INIT_LOGE("Create %s failed. %d", path, errno); + return -1; + } + return rc; +} + + +``` + + **3.信号注册** + +```c + // 3. signal register + SignalInitModule(); + +``` + +```c +#ifdef OHOS_LITE +void SignalInitModule() +{ + struct sigaction act; + act.sa_handler = SigHandler; + act.sa_flags = SA_RESTART; + (void)sigfillset(&act.sa_mask); + + sigaction(SIGCHLD, &act, NULL); + sigaction(SIGTERM, &act, NULL); +} + +``` + + **4**.执行rcs + +```c + // 4. execute rcs + ExecuteRcs(); + +``` + +```c +void ExecuteRcs() +{ +#if (defined __LINUX__) && (defined NEED_EXEC_RCS_LINUX) + pid_t retPid = fork(); + if (retPid < 0) { + INIT_LOGE("ExecuteRcs, fork failed! err %d.", errno); + return; + } + + // child process + if (retPid == 0) { + INIT_LOGI("ExecuteRcs, child process id %d.", getpid()); + if (execle("/bin/sh", "sh", "/etc/init.d/rcS", NULL, NULL) != 0) { + INIT_LOGE("ExecuteRcs, execle failed! err %d.", errno); + } + _exit(0x7f); // 0x7f: user specified + } + + // init process + sem_t sem; + if (sem_init(&sem, 0, 0) != 0) { + INIT_LOGE("ExecuteRcs, sem_init failed, err %d.", errno); + return; + } + SignalRegWaitSem(retPid, &sem); + + // wait until rcs process exited + if (sem_wait(&sem) != 0) { + INIT_LOGE("ExecuteRcs, sem_wait failed, err %d.", errno); + } +#endif +} + + +``` + +二、“init”阶段:系统服务启动阶段 + + 5.**读取配置文件** + +```c +// 5. read configuration file and do jobs + InitReadCfg(); + +``` + +```c +void InitReadCfg() +{ +#ifndef OHOS_LITE + InitParamService(); + LoadDefaultParams("/system/etc/prop.default"); + LoadDefaultParams("/system/build.prop"); + LoadDefaultParams("/system/buildz.prop"); + LoadDefaultParams("/product/build.prop"); +#endif + ParseInitCfg(INIT_CONFIGURATION_FILE); + ParseOtherCfgs(); + INIT_LOGI("Parse init config file done."); + + DumpAllServices(); + // DumpAllJobs(); +#ifdef OHOS_LITE + // do jobs + DoJob("pre-init"); +#ifndef __LINUX__ + TriggerStage(EVENT1, EVENT1_WAITTIME, QS_STAGE1); +#endif + + DoJob("init"); +#ifndef __LINUX__ + TriggerStage(EVENT2, EVENT2_WAITTIME, QS_STAGE2); +#endif + + DoJob("post-init"); +#ifndef __LINUX__ + TriggerStage(EVENT3, EVENT3_WAITTIME, QS_STAGE3); + + InitStageFinished(); +#endif + ReleaseAllJobs(); +#else + PostTrigger(EVENT_BOOT, "pre-init", strlen("pre-init")); + + PostTrigger(EVENT_BOOT, "init", strlen("init")); + + PostTrigger(EVENT_BOOT, "post-init", strlen("post-init")); +#endif +} + +``` + + 6.**保持线程活跃** + + + +```C + // 6. keep process alive + StartParamService(); +``` + +```c +int StartParamService() +{ + PARAM_LOGI("StartParamService."); + uv_fs_t req; + uv_fs_unlink(uv_default_loop(), &req, PIPE_NAME, NULL); + + uv_pipe_t pipeServer; + int ret = uv_pipe_init(uv_default_loop(), &pipeServer, 0); + PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_init %d", ret); + ret = uv_pipe_bind(&pipeServer, PIPE_NAME); + PARAM_CHECK(ret == 0, return ret, "Failed to uv_pipe_bind %d %s", ret, uv_err_name(ret)); + ret = chmod(PIPE_NAME, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + PARAM_CHECK(ret == 0, return ret, "Failed to chmod %s, err %d. ", PIPE_NAME, errno); + ret = uv_listen((uv_stream_t*)&pipeServer, SOMAXCONN, OnConnection); + PARAM_CHECK(ret == 0, return ret, "Failed to uv_listen %d %s", ret, uv_err_name(ret)); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + PARAM_LOGI("Start service exit."); + return 0; +} ``` -base/startup/ -├── appspawn_standard # 标准系统应用孵化器组件 -│ ├── include # 头文件目录 -│ ├── parameter # 系统参数 -│ ├── src # 服务程序源码 -│ └── test # 测试代码 -├── appspawn_lite # 小型系统应用孵化器组件 -│ └── services -│ ├── include # 应用孵化器组件头文件目录 -│ ├── src # 应用孵化器组件源文件目录 -│ └── test # 应用孵化器组件测试用例源文件目录 -├── bootstrap_lite # 启动引导组件 -│ └── services -│ └── source # 启动引导组件源文件目录 -├── init_lite # init组件 -│ ├── initsync # 分阶段启动源文件目录 -│ ├── interfaces # 对外接口目录 -│ └── services -│ ├── include # init组件头文件目录 -│ ├── src # init组件源文件目录 -│ └── test # init组件测试用例源文件目录 -└── syspara_lite # 系统属性组件 - ├── adapter # 系统属性适配层源文件目录 - ├── frameworks # 系统属性组件源文件目录 - ├── hals # 系统属性组件硬件抽象层头文件目录 - ├── interfaces # 系统属性组件对外接口目录 - └── simulator # 模拟器适配 -``` - -## 约束 - -系统属性:OEM厂商相关仅提供默认值,具体值需产品方按需进行调整。 - -## 使用说明 - -- init的配置文件 - - init配置文件包含了所有需要由init进程启动的系统关键服务的服务名、可执行文件路径、权限和其他属性信息,该文件位于代码仓库/vendor/hisilicon/hispark\_aries/init\_configs/目录,部署在/etc/下,文件名称为init.cfg,采用json格式,文件大小目前限制在100KB以内。 - - init进程启动后首先读取/etc/init.cfg,然后解析其json内容,并根据解析结果依次加载系统服务。配置文件格式和内容说明如下所示: +上述每个阶段在配置文件init.cfg中都用一个job表示,每个job都对应一个命令集合,init通过依次执行每个job中的命令来完成系统初始化。job执行顺序:先执行“pre-init”,再执行“init”,最后>执行“post-init”,所有job都集中放在init.cfg的jobs数组中。 + +除上述jobs数组之外,init.cfg中还有一个services数组,用于存放所有需要由init进程启动的系统关键服务的服务名、可执行文件路径、权限和其他属性信息。 + +配置文件init.cfg位于代码仓库/vendor/hisilicon/hispark\_aries/init\_configs/目录,部署在/etc/下,采用json格式,文件大小目前限制在100KB以内。 + +配置文件格式和内容说明如下所示: ``` { "jobs" : [{ - "name" : "pre-init", -------- 在init之前执行的job,可以放置一些启动进程之前的预操作(如新建文件夹等) - "cmds" : [ -------- 当前job支持的命令集合(当前cmd仅支持start/mkdir/chmod/chown/mount) - -------- 命令名称和参数(长度<=128字节)之间有且只能有一个空格 - "mkdir /testdir", -------- 创建文件夹命令,mkdir和目标文件夹之间有且只能有一个空格 - "chmod 0700 /testdir", -------- 修改权限命令,chmod 权限 目标 之间间隔有且仅有一个空格,权限必须为0xxx格式 - "chown 99 99 /testdir",-------- 修改属组命令,chown uid gid 目标 之间间隔有且仅有一个空格 + "name" : "pre-init", + "cmds" : [ + "mkdir /testdir", + "chmod 0700 /testdir", + "chown 99 99 /testdir", "mkdir /testdir2", - "mount vfat /dev/mmcblk0p0 /testdir2 noexec nosuid" -------- mount命令,格式为:mount 文件系统类型 source target flags data - -------- flags当前仅支持nodev、noexec、nosuid和rdonly,各项均以一个空格分开 + "mount vfat /dev/mmcblk0p0 /testdir2 noexec nosuid" ] }, { - "name" : "init", -------- job名称当前仅支持识别“pre-init”、“init”和“post-init” - "cmds" : [ -------- 单个job目前最多支持30条cmd - "start service1", -------- 启动服务命令1 - "start service2" -------- 启动服务命令2(可以根据需要调整命令在数组中的顺序,init进程将根据解析顺序依次执行) + "name" : "init", + "cmds" : [ + "start service1", + "start service2" ] }, { - "name" : "post-init", -------- 在init之后执行的 job,可以放置一些启动进程之后的操作 + "name" : "post-init", "cmds" : [] } ], - "services" : [{ -------- service集合(数组形式),包含了init进程需要启动的所有系统服务(当前最多支持100个服务) - "name" : "service1", -------- 当前服务的服务名,须确保非空且长度<=32字节 - "path" : "/bin/process1" -------- 当前服务的可执行文件全路径,须确保非空且长度<=64字节 - "uid" : 1, -------- 当前服务进程的uid值 - "gid" : 1, -------- 当前服务进程的gid值 - "once" : 0, -------- 当前服务进程是否为一次性进程 - 0 --- 当前服务非一次性进程,当进程因任何原因退出时,init收到SIGCHLD信号后将重新启动该服务进程 - 非0 --- 当前服务为一次性进程,当进程因任何原因退出时,init不会重新启动该服务进程 - "importance" : 1, -------- 当前服务是否为关键系统进程 - 0 --- 当前服务非关键系统进程,当进程因任何原因退出时,init不会做系统复位操作 - 非0 --- 当前服务为关键系统进程,当进程因任何原因退出时,init收到SIGCHLD信号后进行系统复位重启 - "caps" : [0, 1, 2, 5] -------- 当前服务所需的capability值,根据安全子系统已支持的capability,评估所需的capability,遵循最小权限原则配置(当前最多可配置100个值) + "services" : [{ + "name" : "service1", + "path" : "/bin/process1", + "uid" : 1, + "gid" : 1, + "once" : 0, + "importance" : 1, + "caps" : [0, 1, 2, 5] }, { - "name" : "service2", -------- 下一个需要init启动的服务。此处服务的顺序与启动顺序无关,启动顺序取决于上面job中的cmd顺序。 + "name" : "service2", "path" : "/bin/process2", "uid" : 2, "gid" : 2, "once" : 1, "importance" : 0, - "caps" : [ ] + "caps" : [] } ] } ``` -**表 2** cmds支持列表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

命令名称

-

命令格式

-

命令说明

-

start

-

start ServiceName 间隔有且仅有一个空格

-

启动服务,服务名称与文件中services数组中服务名称相同

-

mkdir

-

mkdir /xxxx/xxx 间隔有且仅有一个空格

-

创建目录

-

chmod

-

chmod 0xxx /xxx/xx 间隔有且仅有一个空格

-

修改权限,权限值必须为0xxx格式,如0755,0600等,需要遵循权限最小原则配置

-

chown

-

chown uid gid /xxx/xx 间隔有且仅有一个空格

-

修改属组

-

mount

-

mount fileSysType source target flags data

-

间隔有且仅有一个空格

-

挂载命令,其中flags目前仅支持nodev、noexec、nosuid和rdonly,其它字串均判定为data项

-
- -需要注意的是,init.cfg文件的修改需要保持json格式不被破坏,否则init进程解析失败后不会启动任何服务。对于配置的服务权限(uid/gid/capability)需要符合安全子系统要求且遵循权限最小原则。另外,对于once和importance项均为0的服务,若其在4分钟内连续退出次数超过4次,则init将终止重新启动该服务的操作。 - -- 系统参数 - - OEM厂商相关系统属性 - - Hi3516DV300,Hi3518EV300开发板需要修改vendor/hisilicon/hispark\_aries/hals/utils/sys\_param目录下源文件: - - ``` - static const char HOS_PRODUCT_TYPE[] = {"****"}; - static const char HOS_MANUFACTURE[] = {"****"}; - static const char HOS_BRAND[] = {"****"}; - static const char HOS_MARKET_NAME[] = {"****"}; - static const char HOS_PRODUCT_SERIES[] = {"****"}; - static const char HOS_PRODUCT_MODEL[] = {"****"}; - static const char HOS_SOFTWARE_MODEL[] = {"****"}; - static const char HOS_HARDWARE_MODEL[] = {"****"}; - static const char HOS_HARDWARE_PROFILE[] = {"aout:true,display:true"}; - static const char HOS_BOOTLOADER_VERSION[] = {"bootloader"}; - static const char HOS_SECURE_PATCH_LEVEL[] = {"2020-6-5"}; - static const char HOS_ABI_LIST[] = {"****"}; - ``` - - Hi3861开发板需要修改vendor/hisilicon/hispark\_pegasus/hals/utils/sys\_param目录下源文件: - - ``` - static const char HOS_PRODUCT_TYPE[] = {"****"}; - static const char HOS_MANUFACTURE[] = {"****"}; - static const char HOS_BRAND[] = {"****"}; - static const char HOS_MARKET_NAME[] = {"****"}; - static const char HOS_PRODUCT_SERIES[] = {"****"}; - static const char HOS_PRODUCT_MODEL[] = {"****"}; - static const char HOS_SOFTWARE_MODEL[] = {"****"}; - static const char HOS_HARDWARE_MODEL[] = {"****"}; - static const char HOS_HARDWARE_PROFILE[] = {"aout:true,display:true"}; - static const char HOS_BOOTLOADER_VERSION[] = {"bootloader"}; - static const char HOS_SECURE_PATCH_LEVEL[] = {"2020-6-5"}; - static const char HOS_ABI_LIST[] = {"****"}; - ``` - - - 获取默认系统属性 - - ``` - const char* value1 = GetProductType(); - printf("Product type =%s\n", value1); - const char* value2 = GetManufacture(); - printf("Manufacture =%s\n", value2); - const char* value3 = GetBrand(); - printf("GetBrand =%s\n", value3); - ``` - - - - 设置获取自定义系统属性 - - ``` - const char* defSysParam = "data of sys param ***..."; - char key[] = "rw.parameter.key"; - char value[] = "OEM-hisi-10.1.0"; - int ret = SetParameter(key, value); - char valueGet[128] = {0}; - ret = GetParameter(key, defSysParam, valueGet, 128); - printf("value = %s\n", valueGet); - ``` - - - -## 相关仓 - -启动恢复子系统 - -startup\_syspara\_lite - -startup\_appspawn\_lite - -startup\_bootstrap\_lite - -startup\_init\_lite +//备注:在调试瑞芯微时发现/sbin/init, +/bin/init均存在,删除/sbin/init才执行鸿蒙的/bin/init,所以需要检查对应目录情况 + +源码:base/startup/init_lite/services/BUILD.gn + +startup启动子系统生成init文件 + +``` + ohos_executable(\"init\") { + + sources = \[ + +\"src/device.c\", + + \"src/init_adapter.c\", + + \"src/init_capability.c\", + + \"src/init_cmds.c\", + + \"src/init_import.c\", + + \"src/init_jobs.c\", + + \"src/init_read_cfg.c\", + + \"src/init_reboot.c\", + + \"src/init_service.c\", + + \"src/init_service_manager.c\", + + \"src/init_service_socket.c\", + + \"src/init_signal_handler.c\", + + \"src/init_utils.c\", + + \"src/main.c\", + + \] +``` + + + + + +## 启动文件init_linux_5\_10_x2000.cfg + +如下源码可以说明该配置文件也是被startup启动子系统处理的 + +源码:vendor/ingenic/smartpen/init_configs + +./vendor/ingenic/smartpen/init_configs + +├── BUILD.gn + +└── init_linux_5\_10_x2000.cfg + +源码:vendor/ingenic/smartpen/init_configs/BUILD.gn + +``` +copy(\"init_configs\") { + +sources = \[ \"init_linux_5\_10_x2000.cfg\" \] + outputs = \[ \"\$root_out_dir/etc/init.cfg\" \] + +} +``` + + + +源码: + +./base/startup/init_lite/services/src/init_read_cfg.c:129: +ParseInitCfg(INIT_CONFIGURATION_FILE); + +./base/startup/init_lite/services/include/init_read_cfg.h:25:#define +INIT_CONFIGURATION_FILE \"/init.cfg\" + +./base/startup/init_lite/services/include/init_read_cfg.h:27:#define +INIT_CONFIGURATION_FILE \"/etc/init.cfg\" + +如下源码为相应的注释说明 + +源码:vendor/ingenic/smartpen/init_configs/init_linux_5\_10_x2000.cfg + +``` +{ + +\"jobs\" : \[{ + +\"name\" : \"pre-init\", + +\"cmds\" : \[ + +\"mkdir /storage/data\", + +\"chmod 0755 /storage/data\", + +...........................省略................................................ + +\"mount vfat /dev/mmcblk0 /sdcard rw,umask=000\", + +\"mount vfat /dev/mmcblk1 /sdcard rw,umask=000\" + +\] + +}, { + +\"name\" : \"init\", + +\"cmds\" : \[ + +\"start shell\", + +............调试开机阶段该段仅保留shell即可........................ + +\"start apphilogcat\", + +\"start foundation\", + +\"start bundle_daemon\", + +\"start appspawn\", + +\"start hiview\", + +\"start sensor_service\", + +\"start ai_server\", + +\"start deviceauth_service\", + +\"start softbus_server\", + +\"start devicemanagerservice\" + +\] + +}, { + +\"name\" : \"post-init\", + +\"cmds\" : \[ + +...........................省略................................................... + +\] + +} + +\], + +\"services\" : \[{ + +\"name\" : \"shell\", + +\"path\" : \[\"/sbin/getty\", \"-n\", \"-l\", \"/bin/sh\", \"-L\", +\"115200\", \"ttyS3\", \"vt100\"\], + +\"uid\" : 0, + +\"gid\" : 0, + +\"once\" : 0, + +\"importance\" : 0, + +\"caps\" : \[4294967295\] + +}, { + +\"name\" : \"appspawn\", + +\"path\" : \[\"/bin/appspawn\"\], + +\"uid\" : 1, + +\"gid\" : 1, + +\"once\" : 0, + +\"importance\" : 0, + +\"caps\" : \[2, 6, 7, 8, 11, 23\] + +} + +...........................省略................................................... + +\] + +} +``` + + + +其中红色区域为对应的shell启动,这里比较重要,一般芯片厂商知道这里该如何配置。例如瑞芯微配置如下: +`"path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L","115200", "ttyFIQ0", "vt100"]` + +# Small鸿蒙最小子系统列表 + +根据当前做产品的实际情况来看,需要集成如下子系统 + +参考文件:vendor/ingenic/smartpen/config.json ++--------------------------+-------------------------------------------+ +| 子系统列表 | 意义 | +| ~~kernel~~ | 君正另外提供了内核的img,此处去掉不参与系统编译| +| aafwk | 目前看来未使用 | +| hiviewdfx | dfx可维可测。集成过程未使用 | +| distributed_schedule | 鸿蒙中的任务管理器 | +| security | 安全相关,网络连接,富瘦设备交互需要 | +| startup | 启动子系统。此为鸿蒙子系统中第一个 | +| | 启动的子系统,此系统会加载鸿蒙中的启动文 | +| | 件/etc/init.d/rcS以及fs.yml定义的启动文件 | +| communication | Wifi,蓝牙 | +| test | 测试用例集,用来验证集成子系统的兼容性,正式商用版本中去除 | +| appexecfwk | 目前看来系统未使用 | +| utils | 功能集 | +| distributedhardware | 分布式相关,用来做轻富设备交互 | +| distributeddatamgr | | + +备注:子系统在build/lite/component中有相关的定义以及说明。 + +客户如何想添加自己的子系统,例如uboot或者buildroot。可以在build/lite/component创建对应的系统描述文件,并添加config.json中 + +# xts测试 + +待补充,此块尚未完善。目前采用的方式是将xts用例编译为bin文件 + +# 南向服务包接口 + +服务包在芯片集成阶段,需要完成两部分工作。 + +Wifi和Ble鸿蒙子系统api接口实现,Wifi有相应的xts保证测试,Ble这块当前无手段覆盖测试。只能在服务包集成阶段联调 +Todo:Wifi,Ble给出,中文描述需要同步到外网 \ No newline at end of file -- Gitee