• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 产品
2### 产品配置规则
3
4产品解决方案为基于开发板的完整产品,主要包含产品对OS的适配、部件拼装配置、启动配置和文件系统配置等。产品解决方案的源码路径规则为:**vendor/{产品解决方案厂商}/{产品名称}**_。
5
6产品解决方案的目录树规则如下:
7
8```shell
9vendor
10└── company                         # 产品解决方案厂商
11    ├── product                     # 产品名称
12    │   ├── init_configs
13    │   │     ├── etc               # init进程启动配置(可选,仅linux内核需要)
14    │   │     └── init.cfg          # 系统服务启动配置
15    │   ├── hals                    # 产品解决方案OS适配
16    │   ├── BUILD.gn                # 产品编译脚本
17    │   └── config.json             # 产品配置文件
18    │   └── fs.yml                  # 文件系统打包配置
19    └── ......
20```
21
22> ![icon-note.gif](public_sys-resources/icon-note.gif)**注意**:新增产品须按如上的规则创建目录和文件,编译构建系统将按该规则扫描已配置的产品。
23
24关键的目录和文件详细介绍如下:
25
261. **vendor/company/product/init_configs/etc** 该文件夹中包含rcS脚本,Sxxx脚本和fstab脚本。init进程在启动系统服务之前执行这些脚本。执行的流程为“rcS->fstab->S00-xxx“。Sxxx脚本中的内容与开发板和产品需要有关,主要包括设备节点的创建、创建目录、扫描设备节点、修改文件权限等等。这些文件在产品编译的BUILD.gn中按需拷贝到产品out目录中,最终打包到rootfs镜像中。
27
282. **vendor/company/product/init_configs/init.cfg** init进程启动服务的配置文件,当前支持解析的命令有:
29
30   - start: 启动某个服务
31
32   - mkdir: 创建文件夹
33
34   - chmod: 修改指定路径/文件的权限
35
36   - chown: 修改指定路径/文件的属组
37
38   - mount: 挂载命令
39
40     该文件中的各个字段的解释如下:
41
42   ```shell
43   {
44       "jobs" : [{                                                     # job数组,一个job对应一个命令集合。job的执行顺序:pre-init -> init -> post-init。
45               "name" : "pre-init",
46               "cmds" : [
47                   "mkdir /storage/data",                              # 创建目录
48                   "chmod 0755 /storage/data",                         # 修改权限,权限值的格式为0xxx, 如0755
49                   "mkdir /storage/data/log",
50                   "chmod 0755 /storage/data/log",
51                   "chown 4 4 /storage/data/log",                      # 修改属组,第一个数字为uid, 第二个数字为gid
52                   ......
53                   "mount vfat /dev/mmcblock0 /sdcard rw,umask=000"    # 挂载,格式为: mount [文件系统类型] [source] [target] [flags] [data]
54                                                                       # 其中flags仅支持:nodev、noexec、nosuid和rdonly
55               ]
56           }, {
57               "name" : "init",
58               "cmds" : [                                              # 按cmds数组顺序启动启动服务
59                   "start shell",                                      # 注意:start与服务名称之间有且只有一个空格
60                   ......
61                   "start service1"
62               ]
63           }, {
64               "name" : "post-init",                                   # 最后执行的job, init进程启动完成后的处理(如驱动初始化后再mount设备)
65               "cmds" : []
66           }
67       ],
68       "services" : [{                                                 # service数组,一个service对应一个进程
69               "name" : "shell",                                       # 服务名称
70               "path" : ["/sbin/getty", "-n", "-l", "/bin/sh", "-L", "115200", "ttyS000", "vt100"],    # 可执行文件全路径,path必须为第一个元素
71               "uid" : 0,                                              # 进程的uid,须与二进制文件的uid保持一致
72               "gid" : 0,                                              # 进程的gid,须与二进制文件的gid保持一致
73               "once" : 0,                                             # 是否为一次性进程,1:进程退出后,init不在重新拉起。0:常驻进程,进程若退出,init将重新拉起
74               "importance" : 0,                                       # 是否为关键进程,1:是关键进程,若进程退出,init将会重启单板。0:非关键进程,若进程退出,init不会重启单板
75               "caps" : [4294967295]
76           },
77           ......
78       ]
79   }
80   ```
81
823. **vendor/company/product/init_configs/hals** 解决方案厂商对OS的适配,需要实现的接口请见各个部件的readme说明文档。
83
844. **vendor/company/product/config.json** config.json为编译构建的主入口,包含了开发板、OS部件和内核等配置信息。
85
86   以基于hispark_taurus开发板的ipcamera产品为例,配置文件如下:
87
88   ```shell
89   {
90        "product_name": "ipcamera",                       # 产品名称
91        "version": "3.0",                                 # config.json的版本号, 固定"3.0"
92        "type": "small",                                  # 系统类型, 可选[mini, small, standard]
93        "ohos_version": "OpenHarmony 1.0",                # 选择的OS版本
94        "device_company": "hisilicon",                    # 芯片厂商
95        "board": "hispark_taurus",                        # 开发板名称
96        "kernel_type": "liteos_a",                        # 选择的内核类型
97        "kernel_version": "3.0.0",                        # 选择的内核版本
98        "subsystems": [
99          {
100            "subsystem": "aafwk",                         # 选择的子系统
101            "components": [
102              { "component": "ability", "features":[ "enable_ohos_appexecfwk_feature_ability = true" ] }   # 选择的部件和部件特性配置
103            ]
104          },
105          {
106           ......
107          }
108         ......
109         更多子系统和部件
110        }
111    }
112   ```
113
1145. **vendor/company/product/fs.yml** 该文件用于配置文件系统镜像制作过程,将编译产物打包成文件系统镜像,比如用户态根文件系统rootfs.img和可读写的userfs.img。它由多个列表组成,每个列表对应一个文件系统。字段说明如下:
115
116   ```shell
117   fs_dir_name: 必填,声明文件系统文件名, 如rootfs、userfs
118   fs_dirs:     选填,配置out下文件目录与文件系统文件目录的映射关系,每个文件目录对应一个列表
119   source_dir:  选填,out下目标文件目录,若缺失则将根据target_dir在文件系统下创建空目录
120   target_dir:  必填,文件系统下对应文件目录
121   ignore_files:选填,声明拷贝忽略文件
122   dir_mode:    选填,文件目录权限,默认755
123   file_mode:   选填,该文件目录下所有文件的权限,默认555
124   fs_filemode: 选填,配置需要特殊声明权限的文件,每个文件对应一个列表
125   file_dir:    必填,文件系统下具体文件路径
126   file_mode:   必填,文件权限声明
127   fs_symlink:  选填,配置文件系统软连接
128   fs_make_cmd: 必填,配置需要制作文件系统脚本,OS提供的脚本在build/lite/make_rootfs下, 支持linux,liteos内核和ext4、jffs2、vfat格式。也支持芯片解决方案厂商自定义。
129   fs_attr:     选填,根据配置项动态调整文件系统
130   ```
131
132   其中fs_symlink、fs_make_cmd字段支持以下变量:
133
134   - rootpath代码根目录,对应gn的{ohos_root_path}
135   - outpath产品out目录,对应gn的{root_out_dir}
136   - ${fs_dir} 文件系统目录,由以下变量拼接而成
137   - ${root_path}
138   - ${fs_dir_name}
139
140>  ![icon-note.gif](public_sys-resources/icon-note.gif)**注意**:fs.yml是可选的,对于没有文件系统的设备可不配置。
141
1426. **vendor/company/product/BUILD.gn** 产品编译的入口,主要用于编译解决方案厂商源码和拷贝启动配置文件。如果某个产品被选择为要编译的产品,那么对应产品目录下的BUILD.gn会默认编译。一个典型的产品编译BUILD.gn应该如下:
143
144   ```shell
145   group("product") {               # target名称需与product名称即三级目录名称一致
146     deps = []
147     deps += [ "init_configs" ]     # 拷贝init配置
148     ......                         # 其他
149   }
150   ```
151
152### 新增并编译产品
153
154编译构建支持芯片解决方案和部件的灵活拼装,形成定制化的产品解决方案。具体步骤如下:
155
1561. 创建产品目录 按照产品配置规则创建产品目录,以基于“rtl8720“开发板的wifiiot模组为例,在代码根目录执行:
157
158   ```shell
159   mkdir -p vendor/my_company/wifiiot
160   ```
161
1622. 拼装产品 在新建的产品目录下新建config.json文件,以步骤1中的wifiiot为例,vendor/my_company/wifiiot/config.json可以是:
163
164   ```shell
165   {
166       "product_name": "wifiiot",                        # 产品名称
167       "version": "3.0",                                 # config.json的版本号, 固定"3.0"
168       "type": "small",                                  # 系统类型, 可选[mini, small, standard]
169       "ohos_version": "OpenHarmony 1.0",                # 使用的OS版本
170       "device_company": "realtek",                      # 芯片解决方案厂商名称
171       "board": "rtl8720",                               # 开发板名称
172       "kernel_type": "liteos_m",                        # 选择的内核类型
173       "kernel_version": "3.0.0",                        # 选择的内核版本
174       "subsystems": [
175         {
176           "subsystem": "kernel",                        # 选择的子系统
177           "components": [
178             { "component": "liteos_m", "features":[] }  # 选择的部件和部件特性
179           ]
180         },
181         ...
182         {
183            更多子系统和部件
184         }
185       ]
186   }
187   ```
188
189   ![icon-note.gif](public_sys-resources/icon-note.gif)**注意**:编译构建系统编译前会对device_company,board,kernel_type,kernel_version、subsystem、component字段进行有效性检查,其中device_company,board,kernel_type,kernel_version应与已知的芯片解决方案匹配,subsystem、component应与build/lite/components下的部件描述匹配。
190
1913. 适配OS接口 在产品目录下创建hals目录,并将产品解决方案对OS适配的源码和编译脚本放入该目录下。
192
1934. 配置系统服务 在产品目录下创建init_configs目录,并在init_configs目录下创建init.cfg文件,按需配置要启动的系统服务。
194
1955. 配置init进程(仅linux内核需要) 在init_configs目录下创建etc目录,然后在etc下创建init.d文件夹和fstab文件。最后按产品需求在init.d文件下创建并编辑rcS文件和Sxxx文件。
196
1976. 配置文件系统镜像(可选,仅支持文件系统的开发板需要) 在产品目录下创建fs.yml文件。fs.yml需按产品实际情况配置,一个典型的fs.yml文件如下:
198
199   ```shell
200   -
201     fs_dir_name: rootfs # 镜像的名称
202     fs_dirs:
203       -
204         # 将编译生成的out/my_board/my_product/bin目录下的文件拷贝到rootfs/bin中,并忽略测试bin
205         source_dir: bin
206         target_dir: bin
207         ignore_files:
208           - Test.bin
209           - TestSuite.bin
210       -
211         # 将编译生成的out/my_board/my_product/libs目录下的文件拷贝到rootfs/lib中,忽略所有.a文件,并设置文件和文件夹的权限为644和755
212         source_dir: libs
213         target_dir: lib
214         ignore_files:
215           - .a
216         dir_mode: 755
217         file_mode: 644
218       -
219         source_dir: usr/lib
220         target_dir: usr/lib
221         ignore_files:
222           - .a
223         dir_mode: 755
224         file_mode: 644
225       -
226         source_dir: config
227         target_dir: etc
228       -
229         source_dir: system
230         target_dir: system
231       -
232         source_dir: sbin
233         target_dir: sbin
234       -
235         source_dir: usr/bin
236         target_dir: usr/bin
237       -
238         source_dir: usr/sbin
239         target_dir: usr/sbin
240       -
241         # 创建一个proc空目录
242         target_dir: proc
243       -
244         target_dir: mnt
245       -
246         target_dir: opt
247       -
248         target_dir: tmp
249       -
250         target_dir: var
251       -
252         target_dir: sys
253       -
254         source_dir: etc
255         target_dir: etc
256       -
257         source_dir: vendor
258         target_dir: vendor
259       -
260         target_dir: storage
261
262     fs_filemode:
263       -
264         file_dir: lib/ld-uClibc-0.9.33.2.so
265         file_mode: 555
266       -
267         file_dir: lib/ld-2.24.so
268         file_mode: 555
269       -
270         file_dir: etc/init.cfg
271         file_mode: 400
272     fs_symlink:
273       -
274         # 在rootfs/lib下创建软连接ld-musl-arm.so.1 -> libc.so
275         source: libc.so
276         link_name: ${fs_dir}/lib/ld-musl-arm.so.1
277       -
278         source: mksh
279         link_name: ${fs_dir}/bin/sh
280       -
281         source: mksh
282         link_name: ${fs_dir}/bin/shell
283     fs_make_cmd:
284       # 使用脚本将rootfs制作为ext4格式的image
285       - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4
286   -
287     fs_dir_name: userfs
288     fs_dirs:
289       -
290         source_dir: storage/etc
291         target_dir: etc
292       -
293         source_dir: data
294         target_dir: data
295     fs_make_cmd:
296       - ${root_path}/build/lite/make_rootfs/rootfsimg_linux.sh ${fs_dir} ext4
297   ```
298
2997. 配置产品Patch(可选,视产品涉及部件是否需要打补丁而定) 在产品目录下创建patch.yml文件。patch.yml需按产品实际情况配置,一个典型的patch.yml文件如下:
300
301   ```shell
302     # 需要打patch的路径
303   foundation/communication/dsoftbus:
304     # 该路径下需要打的patch存放路径
305     - foundation/communication/dsoftbus/1.patch
306     - foundation/communication/dsoftbus/2.patch
307   third_party/wpa_supplicant:
308     - third_party/wpa_supplicant/1.patch
309     - third_party/wpa_supplicant/2.patch
310     - third_party/wpa_supplicant/3.patch
311   ...
312   ```
313
314   配置完成后,编译时增加--patch参数,即可在产品编译前将配置的Patch文件打到对应目录中,再进行编译:
315
316   ```shell
317   hb build -f --patch
318   ```
319
3208. 编写编译脚本 在产品目录下创建BUILD.gn文件,按产品实际情况编写脚本。以步骤1中的wifiiot为例,BUILD.gn示例如下:
321
322   ```shell
323   group("wifiiot") {             # target名称与产品名一致
324     deps = []
325     deps += [ "init_configs" ]   # 拷贝init配置
326     deps += [ "hals" ]           # 将hals加入编译
327     ......                       # 其他
328   }
329   ```
330
3319. 编译产品。 主要有两种编译方式,[命令行方式和hb方式](subsys-build-all.md#编译命令),这里以命令行方式为例,假设编译的产品名是hispark_taurus_standard,则编译命令是:
332
333   ```
334   ./build.sh --product-name hispark_taurus_standard --ccache
335   ```
336
337
338