1# Combo解决方案之W800芯片移植案例 2 3本方案基于OpenHarmony LiteOS-M内核,使用联盛德W800芯片的润和软件海王星系列[Neptune100开发板](https://gitee.com/openharmony-sig/device_board_hihope),进行开发移植。移植架构采用`Board`与`SoC`分离方案,支持通过Kconfig图形化配置编译选项,增加玄铁`ck804ef`架构移植,实现了`HDF`、`XTS`等子系统及组件的适配。 4 5## 适配准备 6 7准备ubuntu20.04系统环境,安装[csky-abiv2-elf-gcc](https://occ.t-head.cn/community/download?id=3885366095506644992)交叉编译工具链。 8 9## 编译构建 10 11### 目录规划 12 13本方案的目录结构使用[Board和Soc解耦的思路](https://gitee.com/openharmony-sig/sig-content/blob/master/devboard/docs/board-soc-arch-design.md): 14 15芯片适配目录规划为: 16 ``` 17 device 18 ├── board --- 单板厂商目录 19 │ └── hihope --- 单板厂商名字:HiHope 20 │ └── neptune100 --- 单板名:Neptune100 21 └── soc --- SoC厂商目录 22 └── winnermicro --- SoC厂商名字:联盛德 23 └── wm800 --- SoC Series名:w800系列芯片 24 ``` 25 26产品样例目录规划为: 27 28 ``` 29 vendor 30 └── hihope --- 开发产品样例厂商目录,润和软件的产品样例 31 ├── neptune_iotlink_demo --- 产品名字:Neptune100产品样例代码 32 └── ... 33 ``` 34 35### 产品定义 36 37`vendor/hihope/neptune_iotlink_demo/config.json`文件下,描述了产品使用的内核、单板、子系统等信息。其中,内核、单板型号、单板厂商需提前规划好,是预编译指令`hb set`关注的。例如: 38 39 ``` 40 { 41 "product_name": "neptune_iotlink_demo", --- 产品名 42 "ohos_version": "OpenHarmony 3.1", --- 使用的OS版本 43 "type":"mini", --- 系统类型: mini 44 "version": "3.0", --- 系统版本: 3.0 45 "device_company": "hihope", --- 单板厂商:hihope 46 "board": "neptune100", --- 单板名:neptune100 47 "kernel_type": "liteos_m", --- 内核类型:liteos_m 48 "kernel_version": "3.0.0", --- 内核版本:3.0.0 49 "subsystems": [] --- 子系统 50 } 51 ``` 52填入的信息与规划的目录相对应,其中`device_company`和`board`用于关联出`device/board/<device_company>/`目录。 53 54### 单板配置 55 56关联到的\<board\>目录下,在`device/board/hihope/neptune100/liteos_m`目录下放置`config.gni`文件,该配置文件用于描述该单板信息,包括CPU型号、交叉编译工具链及全局编译、链接参数等重要信息: 57 58``` 59# Kernel type, e.g. "linux", "liteos_a", "liteos_m". 60kernel_type = "liteos_m" 61 62# Kernel version. 63kernel_version = "3.0.0" 64 65# Board CPU type, e.g. "cortex-a7", "riscv32". 66board_cpu = "ck804ef" 67 68# Board arch, e.g. "armv7-a", "rv32imac". 69board_arch = "ck803" 70 71# Toolchain name used for system compiling. 72# E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf. 73# Note: The default toolchain is "ohos-clang". It's not mandatory if you use the default toolchain. 74board_toolchain = "csky-elfabiv2-gcc" 75 76#use_board_toolchain = true 77 78# The toolchain path installed, it's not mandatory if you have added toolchain path to your ~/.bashrc. 79board_toolchain_path = "" 80 81# Compiler prefix. 82board_toolchain_prefix = "csky-elfabiv2-" 83 84# Compiler type, "gcc" or "clang". 85board_toolchain_type = "gcc" 86 87# config.json parse 88if (product_path != "") { 89 product_conf = read_file("${product_path}/config.json", "json") 90 product_name = product_conf.product_name 91 bin_list = product_conf.bin_list 92} 93 94# Board related common compile flags. 95board_cflags = [ 96 "-mcpu=ck804ef", 97 "-mhard-float", 98 "-DGCC_COMPILE=1", 99 "-DTLS_CONFIG_CPU_XT804=1", 100 "-DNIMBLE_FTR=1", 101 "-D__CSKY_V2__=1", 102 "-DCPU_CK804", 103 "-O2", 104 "-g3", 105 "-Wall", 106 "-ffunction-sections", 107 "-MMD", 108 "-MP", 109] 110 111board_cxx_flags = board_cflags 112 113board_asmflags = [ 114 "-mcpu=ck804ef", 115 "-DCPU_CK804", 116] 117 118board_ld_flags = [] 119 120# Board related headfiles search path. 121board_include_dirs = [] 122 123# Board adapter dir for OHOS components. 124board_adapter_dir = "" 125 126# Sysroot path. 127board_configed_sysroot = "" 128 129# Board storage type, it used for file system generation. 130storage_type = "" 131``` 132 133### 预编译 134 135在工程根目录下输入预编译指令`hb set`可显示相关产品信息,如下: 136 137``` 138hb set 139OHOS Which product do you need? (Use arrow keys) 140 141hihope 142 > neptune_iotlink_demo 143 144OHOS Which product do you need? neptune_iotlink_demo 145``` 146 147执行`hb set`后,会在根目录下自动生成`ohos_config.json`文件,文件中会列出待编译的产品信息。 148 149通过`hb env`可以查看选择出来的预编译环境变量。 150 151``` 152[OHOS INFO] root path: /home/xxxx/openharmony_w800 153[OHOS INFO] board: neptune100 154[OHOS INFO] kernel: liteos_m 155[OHOS INFO] product: neptune_iotlink_demo 156[OHOS INFO] product path: /home/xxxx/openharmony_w800/vendor/hihope/neptune_iotlink_demo 157[OHOS INFO] device path: /home/xxxx/openharmony_w800/device/board/hihope/neptune100/liteos_m 158[OHOS INFO] device company: hihope 159``` 160 161至此,预编译适配完成,但工程还不能执行hb build进行编译,还需要准备好后续的LiteOS-M内核移植。 162 163## 内核移植 164 165### Kconfig适配 166 167在`kernel/liteos_m`的编译中,需要在相应的单板以及SoC目录下使用`Kconfig`文件进行索引。 168 1691. 在`vendor/hihope/neptune_iotlink_demo`目录下创建kernel_configs目录,并创建`debug.config`空文件。 170 1712. 打开`kernel/liteos_m/Kconfig`文件,可以看到在该文件通过orsource命令导入了`device/board`和`device/soc`下多个`Kconfig`文件,后续需要创建并修改这些文件: 172 173 ``` 174 orsource "../../device/board/*/Kconfig.liteos_m.shields" 175 orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.defconfig.boards" 176 orsource "../../device/board/$(BOARD_COMPANY)/Kconfig.liteos_m.boards" 177 orsource "../../device/soc/*/Kconfig.liteos_m.defconfig" 178 orsource "../../device/soc/*/Kconfig.liteos_m.series" 179 orsource "../../device/soc/*/Kconfig.liteos_m.soc" 180 ``` 181 1823. 在`device/board/hihope`下创建相应的的`Kconfig`文件: 183 184 ``` 185 ├── neptune100 --- neptune100单板配置目录 186 │ ├── Kconfig.liteos_m.board --- 单板的配置选项 187 │ ├── Kconfig.liteos_m.defconfig.board --- 单板的默认配置项 188 │ └── liteos_m 189 │ └── config.gni --- 单板的配置文件 190 ├── Kconfig.liteos_m.boards --- 单板厂商下Boards配置信息 191 └── Kconfig.liteos_m.defconfig.boards --- 单板厂商下Boards默认配置信息 192 ``` 193 1944. 修改`Board`目录下`Kconfig`文件内容: 195 196 在 `neptune100/Kconfig.liteos_m.board`中添加, 197 198 ``` 199 config BOARD_NEPTUNE100 200 bool "select board neptune100" 201 depends on SOC_WM800 202 ``` 203 204 配置只有SOC_WM800被选后,BOARD_NEPTUNE100才可被选。 205 206 在 `neptune100/Kconfig.liteos_m.defconfig.board`中添加, 207 208 ``` 209 if BOARD_NEPTUNE100 210 211 endif #BOARD_NEPTUNE100 212 ``` 213 214 用于添加 BOARD_NEPTUNE100默认配置。 215 2165. 在`device/soc/winnermicro`下创建相应的的`Kconfig`文件: 217 218 ``` 219 ├── wm800 --- W800系列 220 │ ├── Kconfig.liteos_m.defconfig.wm800 --- W800芯片默认配置 221 │ ├── Kconfig.liteos_m.defconfig.series --- W800系列默认配置 222 │ ├── Kconfig.liteos_m.series --- W800系列配置 223 │ └── Kconfig.liteos_m.soc --- W800芯片配置 224 ├── Kconfig.liteos_m.defconfig --- SoC默认配置 225 ├── Kconfig.liteos_m.series --- Series配置 226 └── Kconfig.liteos_m.soc --- SoC配置 227 ``` 228 2296. 修改`Soc`目录下`Kconfig`文件内容: 230 231 在`wm800/Kconfig.liteos_m.defconfig.wm800`中添加: 232 233 ``` 234 config SOC 235 string 236 default "wm800" 237 depends on SOC_WM800 238 ``` 239 240 在`wm800/Kconfig.liteos_m.defconfig.series`中添加: 241 242 ``` 243 if SOC_SERIES_WM800 244 245 rsource "Kconfig.liteos_m.defconfig.wm800" 246 247 config SOC_SERIES 248 string 249 default "wm800" 250 251 endif 252 ``` 253 254 在 `wm800/Kconfig.liteos_m.series`中添加: 255 256 ``` 257 config SOC_SERIES_WM800 258 bool "winnermicro 800 Series" 259 select ARM 260 select SOC_COMPANY_WINNERMICRO --- 选择 SOC_COMPANY_WINNERMICRO 261 select CPU_XT804 262 help 263 Enable support for winnermicro 800 series 264 ``` 265 266 在选择了 SOC_SERIES_WM800之后,才可选 `wm800/Kconfig.liteos_m.soc`文件中的 SOC_WM800: 267 268 ``` 269 choice 270 prompt "Winnermicro 800 series SoC" 271 depends on SOC_SERIES_WM800 272 273 config SOC_WM800 --- 选择 SOC_WM800 274 bool "SoC WM800" 275 276 endchoice 277 ``` 278 279 综上所述,要编译单板BOARD_NEPTUNE100,则要分别选中:SOC_COMPANY_WINNERMICRO、SOC_SERIES_WM800、SOC_WM800 2807. 在`kernel/liteos_m`中执行`make menuconfig`进行选择配置,能够对SoC Series进行选择: 281 282  283 284 配置后的文件会默认保存在`vendor/hihope/neptune_iotlink_demo/kernel_configs/debug.config`,也可以直接填写`debug.config`: 285 286 ``` 287 LOSCFG_PLATFORM_QEMU_CSKY_SMARTL=y 288 LOSCFG_SOC_SERIES_WM800=y 289 ``` 290 291### 模块化编译 292 293`Board`和`SoC`的编译采用模块化的编译方法,从`kernel/liteos_m/BUILD.gn`开始逐级向下递增。本方案的适配过程如下: 294 2951. 在`device/board/hihope`中新建文件`BUILD.gn`,新增内容如下: 296 297 ``` 298 if (ohos_kernel_type == "liteos_m") { 299 import("//kernel/liteos_m/liteos.gni") 300 module_name = get_path_info(rebase_path("."), "name") 301 module_group(module_name) { 302 modules = [ 303 "neptune100", --- 单板模块 304 "shields", 305 ] 306 } 307 } 308 ``` 309 310 在上述`BUILD.gn`中,neptune100以及shields即是按目录层级组织的模块名。 311 3122. 在`device/soc/winnermicro`中,新建文件`BUILD.gn`,按目录层级组织,新增内容如下: 313 314 ``` 315 if (ohos_kernel_type == "liteos_m") { 316 import("//kernel/liteos_m/liteos.gni") 317 module_name = get_path_info(rebase_path("."), "name") 318 module_group(module_name) { 319 modules = [ 320 "hals", 321 "wm800", 322 ] 323 } 324 } 325 ``` 326 3273. 在`device/soc/winnermicro`各个层级模块下,同样新增文件`BUILD.gn`,将该层级模块加入编译。以`device/soc/winnermicro/wm800/board/platform/sys/BUILD.gn`为例: 328 329 ``` 330 import("//kernel/liteos_m/liteos.gni") 331 module_name = get_path_info(rebase_path("."), "name") 332 kernel_module(module_name) { --- 编译的模块 333 sources = [ --- 编译的源文件 334 "wm_main.c", 335 ] 336 include_dirs = [ --- 模块内使用到的头文件 337 ".", 338 ] 339 } 340 341 ``` 342 3434. 为了组织链接以及一些编译选项,在`device/soc/winnermicro/wm800/board/BUILD.gn`下的`config("board_config")`填入了相应的参数: 344 345 ``` 346 config("board_config") { 347 ldflags = [] --- 链接参数,包括ld文件 348 libs = [] --- 链接库 349 include_dirs = [] --- 公共头文件 350 ``` 351 352 3535. 为了组织一些产品侧的应用,需要强制链接到产品工程中来,本方案在vendor相应的`config.json`加入了相应的list来组织,在`vendor/hihope/neptune_iotlink_demo/config.json`增加对应的list: 354 355 ``` 356 "bin_list": [ --- demo list 357 { 358 "elf_name": "hihope", 359 "enable": "false", --- list开关 360 "force_link_libs": [ 361 "bootstrap", 362 "broadcast", 363 ... 364 ] 365 } 366 ``` 367 368 将demo应用作为模块库来管理,开启/关闭某个demo,在bin_list中增减相应库文件即可。bin_list在gn中可以直接被读取,在`device/board/hihope/neptune100/liteos_m/config.gni`新增内容: 369 370 ``` 371 # config.json parse 372 if (product_path != "") { 373 product_conf = read_file("${product_path}/config.json", "json") 374 product_name = product_conf.product_name 375 bin_list = product_conf.bin_list 376 } 377 ``` 378 379 读取list后即可在相应的链接选项上加入相关的组件库,在`//device/soc/winnermicro/wm800/BUILD.gn`添加内容: 380 381 ``` 382 foreach(bin_file, bin_list) { 383 build_enable = bin_file.enable 384 ... 385 if(build_enable == "true") 386 { 387 ... 388 foreach(force_link_lib, bin_file.force_link_libs) { 389 ldflags += [ "-l${force_link_lib}" ] 390 } 391 ... 392 } 393 } 394 ``` 395 396### 内核子系统适配 397 398在`vendor/hihope/neptune_iotlink_demo/config.json`添加内核子系统及相关配置,如下: 399 400 ``` 401 "subsystems": [ 402 { 403 "subsystem": "kernel", 404 "components": [ 405 { 406 "component": "liteos_m", "features":[] 407 } 408 ] 409 }, 410 ``` 411 412### 内核启动适配 413 414由于Neptune100开发板的芯片架构为OpenHarmony不支持的ck804ef架构,需要进行ck804ef架构移植。适配 `kernel\liteos_m\arch\include`中定义的通用的文件以及函数列表,并放在了 `kernel\liteos_m\arch\csky\v2\ck804\gcc`文件夹下。 415 416内核初始化示例如下: 417 418 ``` 419 osStatus_t ret = osKernelInitialize(); --- 内核初始化 420 if(ret == osOK) 421 { 422 threadId = osThreadNew((osThreadFunc_t)sys_init,NULL,&g_main_task); --- 创建init线程 423 if(threadId!=NULL) 424 { 425 osKernelStart(); --- 线程调度 426 } 427 } 428 ``` 429 430board_main在启动OHOS_SystemInit之前,需要初始化必要的动作,如下: 431 432 ``` 433 ... 434 UserMain(); --- 启动OpenHarmony OHOS_SystemInit的之前完成驱动的初始化 435 ... 436 OHOS_SystemInit(); --- 启动OpenHarmony服务,以及组件初始化 437 ... 438 ``` 439 440UserMain函数在`device/soc/winnermicro/wm800/board/app/main.c`文件中,如下: 441 442 ``` 443 ... 444 if (DeviceManagerStart()) { --- HDF初始化 445 printf("[%s] No drivers need load by hdf manager!",__func__); 446 } 447 ... 448 ``` 449 450### HDF驱动框架适配 451 452HDF驱动框架提供了一套应用访问硬件的统一接口,可以简化应用开发,添加HDF组件需要在`//vendor/hihope/neptune_iotlink_demo/kernel_configs`添加: 453 454 ``` 455 LOSCFG_DRIVERS_HDF=y 456 LOSCFG_DRIVERS_HDF_PLATFORM=y 457 ``` 458 459驱动适配相关文件放置在`drivers/adapter/platform`中,对应有gpio,i2c,pwm,spi,uart,watchdog,都是通过HDF机制加载,本章节以GPIO和UART为例进行详细说明。 460 461#### GPIO适配 462 4631. 芯片驱动适配文件位于`drivers/adapter/platform`目录,在gpio目录增加`gpio_wm.c`文件,在`BUILD.gn`文件中,描述了W800驱动的编译适配。如下: 464 465 ``` 466 ... 467 if (defined(LOSCFG_SOC_COMPANY_WINNERMICRO)) { 468 sources += [ "gpio_wm.c" ] 469 } 470 ... 471 ``` 472 4732. `gpio_wm.c`中驱动描述文件如下: 474 475 ``` 476 /* HdfDriverEntry definitions */ 477 struct HdfDriverEntry g_GpioDriverEntry = { 478 .moduleVersion = 1, 479 .moduleName = "WM_GPIO_MODULE_HDF", 480 .Bind = GpioDriverBind, 481 .Init = GpioDriverInit, 482 .Release = GpioDriverRelease, 483 }; 484 HDF_INIT(g_GpioDriverEntry); 485 ``` 486 4873. 在`device/board/hihope/shields/neptune100/neptune100.hcs`添加gpio硬件描述信息, 添加内容如下: 488 489 ``` 490 root { 491 platform { 492 gpio_config { 493 match_attr = "gpio_config"; 494 groupNum = 1; 495 pinNum = 48; 496 } 497 } 498 } 499 ``` 500 5014. 在GpioDriverInit获取hcs参数进行初始化,如下: 502 503 ``` 504 ... 505 gpioCntlr = GpioCntlrFromHdfDev(device); --- gpioCntlr节点变量获取具体gpio配置 506 if (gpioCntlr == NULL) { 507 HDF_LOGE("GpioCntlrFromHdfDev fail\r\n"); 508 return HDF_DEV_ERR_NO_DEVICE_SERVICE; 509 } 510 ... 511 ``` 512 513#### UART适配 514 5151. 芯片驱动适配文件位于`drivers/adapter/platform`目录,在uart目录增加`uart_wm.c`文件,在`BUILD.gn`文件中,描述了W800驱动的编译适配。如下: 516 517 ``` 518 ... 519 if (defined(LOSCFG_SOC_COMPANY_WINNERMICRO)) { 520 sources += [ "uart_wm.c" ] 521 } 522 ... 523 ``` 524 5252. `uart_wm.c`中驱动描述文件如下: 526 527 ``` 528 /* HdfDriverEntry definitions */ 529 struct HdfDriverEntry g_UartDriverEntry = { 530 .moduleVersion = 1, 531 .moduleName = "W800_UART_MODULE_HDF", 532 .Bind = UartDriverBind, 533 .Init = UartDriverInit, 534 .Release = UartDriverRelease, 535 }; 536 537 /* Initialize HdfDriverEntry */ 538 HDF_INIT(g_UartDriverEntry); 539 ``` 540 5413. 在`device/board/hihope/shields/neptune100/neptune100.hcs`添加uart硬件描述信息, 添加内容如下: 542 543 ``` 544 root { 545 platform { 546 uart_config { 547 /* 548 uart0 { 549 match_attr = "uart0_config"; 550 num = 0; 551 baudrate = 115200; 552 parity = 0; 553 stopBit = 1; 554 data = 8; 555 }*/ 556 uart1 { 557 match_attr = "uart1_config"; 558 num = 1; 559 baudrate = 115200; 560 parity = 0; 561 stopBit = 1; 562 data = 8; 563 } 564 } 565 } 566 } 567 ``` 568 5694. 在UartDriverInit获取hcs参数进行初始化,如下: 570 571 ``` 572 ... 573 host = UartHostFromDevice(device); 574 if (host == NULL) { 575 HDF_LOGE("%s: host is NULL", __func__); 576 return HDF_ERR_INVALID_OBJECT; 577 } 578 ... 579 ``` 580 581## OpenHarmony子系统适配 582 583子系统的编译选项入口在相应产品`config.json`下,如:`vendor/hihope/neptune_iotlink_demo/config.json`。 584 585### wifi_lite组件 586 587首先,在`config.json`文件中,增加`communication`子系统的`wifi_lite`部件,如下: 588 589 ``` 590 { 591 "subsystem": "communication", 592 "components": [ 593 { 594 "component": "wifi_lite", 595 "optional": "true" 596 } 597 ] 598 }, 599 ``` 600 601`wifi_lite`部件在 `build/lite/components/communication.json`文件中,描述如下: 602 603 ``` 604 { 605 "component": "wifi_lite", 606 "targets": [ 607 "//foundation/communication/wifi_lite:wifi" --- wifi_lite的编译目标 608 ] 609 }, 610 ``` 611 612在本案例中,`wifi`适配源码可见`device/soc/winnermicro/wm800/board/src/wifi/wm_wifi.c`,如下: 613 614 ``` 615 int tls_wifi_netif_add_status_event(tls_wifi_netif_status_event_fn event_fn) ---用于增加wifi事件功能 616 { 617 u32 cpu_sr; 618 struct tls_wifi_netif_status_event *evt; 619 //if exist, remove from event list first. 620 tls_wifi_netif_remove_status_event(event_fn); 621 evt = tls_mem_alloc(sizeof(struct tls_wifi_netif_status_event)); 622 if(evt==NULL) 623 return -1; 624 memset(evt, 0, sizeof(struct tls_wifi_netif_status_event)); 625 evt->status_callback = event_fn; 626 cpu_sr = tls_os_set_critical(); 627 dl_list_add_tail(&wifi_netif_status_event.list, &evt->list); 628 tls_os_release_critical(cpu_sr); 629 630 return 0; 631 } 632 ``` 633 634### 系统服务管理子系统适配 635系统服务管理子系统适配添加`samgr_lite`部件,直接在`config.json`配置,如下: 636 637 ``` 638 { 639 "subsystem": "systemabilitymgr", 640 "components": [ 641 { 642 "component": "samgr_lite" 643 } 644 ] 645 }, 646 ``` 647 648### 公共基础库子系统适配 649 650公共基础库子系统适配添加了`kv_store、file`部件,直接在`config.json`配置,如下: 651 652 ``` 653 { 654 "subsystem": "utils", 655 "components": [ 656 { 657 "component": "kv_store", 658 "features": [ 659 "enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true" 660 ] 661 }, 662 { "component": "file", "features":[] } 663 ] 664 }, 665 ``` 666 667适配`kv_store`部件时,键值对会写到文件中。在轻量系统中,文件操作相关接口有`POSIX`接口与`HalFiles`接口这两套实现。 668因为对接内核的文件系统,采用`POSIX`相关的接口,所以`features`需要增加`enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true`。 669 670### 启动恢复子系统适配 671 672启动恢复子系统适配添加了`bootstrap_lite、syspara_lite`部件,直接在`config.json`配置,如下: 673 674 ``` 675 { 676 "subsystem": "startup", 677 "components": [ 678 { 679 "component": "bootstrap_lite" 680 }, 681 { 682 "component": "syspara_lite", 683 "features": [ 684 "enable_ohos_startup_syspara_lite_use_posix_file_api = true", 685 "config_ohos_startup_syspara_lite_data_path = \"/data/\"" 686 ] 687 } 688 ] 689 }, 690 ``` 691 692适配bootstrap_lite部件时,需要在链接脚本文件`device/soc/winnermicro/wm800/board/ld/w800/gcc_csky.ld`中手动新增如下段: 693 694 ``` 695 .zinitcall_array : 696 { 697 . = ALIGN(0x4) ; 698 PROVIDE_HIDDEN (__zinitcall_core_start = .); 699 KEEP (*(SORT(.zinitcall.core*))) 700 KEEP (*(.zinitcall.core*)) 701 PROVIDE_HIDDEN (__zinitcall_core_end = .); 702 . = ALIGN(0x4) ; 703 PROVIDE_HIDDEN (__zinitcall_device_start = .); 704 KEEP (*(SORT(.zinitcall.device*))) 705 KEEP (*(.zinitcall.device*)) 706 PROVIDE_HIDDEN (__zinitcall_device_end = .); 707 . = ALIGN(0x4) ; 708 PROVIDE_HIDDEN (__zinitcall_bsp_start = .); 709 KEEP (*(SORT(.zinitcall.bsp*))) 710 KEEP (*(.zinitcall.bsp*)) 711 PROVIDE_HIDDEN (__zinitcall_bsp_end = .); 712 . = ALIGN(0x4) ; 713 PROVIDE_HIDDEN (__zinitcall_sys_service_start = .); 714 KEEP (*(SORT(.zinitcall.sys.service*))) 715 KEEP (*(.zinitcall.sys.service*)) 716 PROVIDE_HIDDEN (__zinitcall_sys_service_end = .); 717 . = ALIGN(0x4) ; 718 PROVIDE_HIDDEN (__zinitcall_app_service_start = .); 719 KEEP (*(SORT(.zinitcall.app.service*))) 720 KEEP (*(.zinitcall.app.service*)) 721 PROVIDE_HIDDEN (__zinitcall_app_service_end = .); 722 . = ALIGN(0x4) ; 723 PROVIDE_HIDDEN (__zinitcall_sys_feature_start = .); 724 KEEP (*(SORT(.zinitcall.sys.feature*))) 725 KEEP (*(.zinitcall.sys.feature*)) 726 PROVIDE_HIDDEN (__zinitcall_sys_feature_end = .); 727 . = ALIGN(0x4) ; 728 PROVIDE_HIDDEN (__zinitcall_app_feature_start = .); 729 KEEP (*(SORT(.zinitcall.app.feature*))) 730 KEEP (*(.zinitcall.app.feature*)) 731 PROVIDE_HIDDEN (__zinitcall_app_feature_end = .); 732 . = ALIGN(0x4) ; 733 PROVIDE_HIDDEN (__zinitcall_run_start = .); 734 KEEP (*(SORT(.zinitcall.run*))) 735 KEEP (*(.zinitcall.run*)) 736 PROVIDE_HIDDEN (__zinitcall_run_end = .); 737 . = ALIGN(0x4) ; 738 PROVIDE_HIDDEN (__zinitcall_test_start = .); 739 KEEP (*(SORT(.zinitcall.test*))) 740 KEEP (*(.zinitcall.test*)) 741 PROVIDE_HIDDEN (__zinitcall_test_end = .); 742 . = ALIGN(0x4) ; 743 PROVIDE_HIDDEN (__zinitcall_exit_start = .); 744 KEEP (*(SORT(.zinitcall.exit*))) 745 KEEP (*(.zinitcall.exit*)) 746 PROVIDE_HIDDEN (__zinitcall_exit_end = .); 747 } > REGION_RODATA 748 ``` 749 750需要新增上述段是因为`bootstrap_init`提供的对外接口,见`utils/native/lite/include/ohos_init.h`文件,采用的是灌段的形式,最终会保存到上述链接段中。主要的服务自动初始化宏如下表格所示: 751 752| 接口名 | 描述 | 753| ---------------------- | -------------------------------- | 754| SYS_SERVICE_INIT(func) | 标识核心系统服务的初始化启动入口。 | 755| SYS_FEATURE_INIT(func) | 标识核心系统功能的初始化启动入口。 | 756| APP_SERVICE_INIT(func) | 标识应用层服务的初始化启动入口。 | 757| APP_FEATURE_INIT(func) | 标识应用层功能的初始化启动入口。 | 758 759 760 761通过上面加载的组件编译出来的lib文件需要手动加入强制链接。 762 763如在 `vendor/hihope/neptune_iotlink_demo/config.json` 中配置了`bootstrap_lite` 部件。 764 765 ``` 766 { 767 "subsystem": "startup", 768 "components": [ 769 { 770 "component": "bootstrap_lite" 771 }, 772 ... 773 ] 774 }, 775 ``` 776 777`bootstrap_lite`部件会编译`base/startup/bootstrap_lite/services/source/bootstrap_service.c`,该文件中,通过`SYS_SERVICE_INIT`将`Init`函数符号灌段到`__zinitcall_sys_service_start`和`__zinitcall_sys_service_end`中,由于`Init`函数是没有显式调用它,所以需要将它强制链接到最终的镜像。如下: 778 779 ``` 780 static void Init(void) 781 { 782 static Bootstrap bootstrap; 783 bootstrap.GetName = GetName; 784 bootstrap.Initialize = Initialize; 785 bootstrap.MessageHandle = MessageHandle; 786 bootstrap.GetTaskConfig = GetTaskConfig; 787 bootstrap.flag = FALSE; 788 SAMGR_GetInstance()->RegisterService((Service *)&bootstrap); 789 } 790 SYS_SERVICE_INIT(Init); --- 通过SYS启动即SYS_INIT启动就需要强制链接生成的lib 791 ``` 792 793在`base/startup/bootstrap_lite/services/source/BUILD.gn`文件中,描述了在`out/neptune100/neptune_iotlink_demo/libs` 生成 `libbootstrap.a`,如下: 794 795 ``` 796 static_library("bootstrap") { 797 sources = [ 798 "bootstrap_service.c", 799 "system_init.c", 800 ] 801 ... 802 ``` 803 804 805适配`syspara_lite`部件时,系统参数会最终写到文件中进行持久化保存。在轻量系统中,文件操作相关接口有POSIX接口与HalFiles接口这两套实现。 806 807因为对接内核的文件系统,采用POSIX相关的接口,所以features字段中需要增加`enable_ohos_startup_syspara_lite_use_posix_file_api = true`。 808 809### XTS子系统适配 810 811XTS子系统的适配,直接在`config.json`中加入组件选项: 812 813 ``` 814 { 815 "subsystem": "xts", 816 "components": [ 817 { 818 "component": "xts_acts", 819 "features": 820 [ 821 "config_ohos_xts_acts_utils_lite_kv_store_data_path = \"/data\"", 822 "enable_ohos_test_xts_acts_use_thirdparty_lwip = true" 823 ] 824 }, 825 { "component": "xts_tools", "features":[] } 826 ] 827 } 828 ``` 829 830另外,XTS功能也使用了list来组织,在`config.json`文件中增减相应模块: 831 832 ``` 833 "bin_list": [ 834 { 835 "enable": "true", 836 "force_link_libs": [ 837 "module_ActsParameterTest", 838 "module_ActsBootstrapTest", 839 "module_ActsDfxFuncTest", 840 "module_ActsHieventLiteTest", 841 "module_ActsSamgrTest", 842 "module_ActsUtilsFileTest", 843 "module_ActsKvStoreTest", 844 "module_ActsWifiServiceTest" 845 ] 846 } 847 ], 848 ``` 849 850其它组件的适配过程与官方以及其它厂商的过程类似,不再赘述。 851