Subsystem Integration and Boot Sequence Adaptation for OpenHarmony
OpenHarmony organizes its functionality through a modular hierarchy consisting of systems, subsystems, and components. This architecture enables engineers to selectively disable non-essential modules based on hardware constraints and product specifications. To successfully deploy the framework on a new silicon platform, developers must properly adapt the required subsystems.
| Subsystem | Core Responsibility |
|---|---|
applications |
Repository for demonstration applications and vendor-specific source modules. |
kernel |
Core OS layer handling process scheduling, IPC, and dynamic memory allocation. |
hiviewdfx |
Observability framework providing log aggregation, fault injection, and diagnostic utilities. |
communication |
Wireless connectivity stacks for Wi-Fi, Bluetooth, and cellular protocols. |
iothardware |
Hardware abstraction layer exposing standard IoT interfaces (GPIO, SPI, I2C, UART). |
startup |
Orchestrates the boot pipeline from kernel handoff to application framework readiness. |
update |
Manages firmware delivery and Over-The-Air (OTA) patching mechanisms. |
utils |
Foundational C/C++ runtime libraries and cross-platform helper APIs. |
distributed_schedule |
Enables cross-device service discovery, component binding, and distributed execution. |
security |
Implements application sandboxing, cryptographic key management, access control, and data integrity verification. |
test |
Provides automated validation frameworks, unit testing utilities, and continuous integration hooks. |
The startup subsystem governs the initialization sequence that occurs immediately after the kernel hands over execution to the framework. On lightweight devices, the System Ability Manager (SAMGR) identifies bootstrap entry points via predefined markers. Once hardware prerequisites are satisfied, ivnoking the core initialization routine triggers the sequential activation of system services.
The primary boot sequence executes initialization routines stored in designated ELF segments, enforcing a strict phase order before transferring control to the service registry.
void OsInitializeCoreFramework(void)
{
MODULE_INIT(bsp); // Iterates .zinitcall.bspX.init section
MODULE_INIT(device); // Iterates .zinitcall.deviceX.init section
MODULE_INIT(core); // Iterates .zinitcall.coreX.init section
SYS_INIT(service); // Iterates .zinitcall.sys.serviceX.init section
SYS_INIT(feature); // Iterates .zinitcall.sys.featureX.init section
MODULE_INIT(run); // Iterates .zinitcall.runX.init section
SAMGR_Bootstrap(); // Finalizes service manager and registers system abilities
}
Configuration Integration
To bind the boot framework, the product definition must explicitly declare the startup components. Modify config.json within the vendor directory to include the following module references:
{
"subsystem_name": "startup",
"components": [
{ "component_name": "bootstrap_lite", "features": [] },
{ "component_name": "syspara_lite", "features": [] }
],
"product_adapter_dir": "vendor/MyVendorCompany/MyProduct/hals"
}
Components such as syspara_lite depend on adapter utilities located in the path defined by product_adapter_dir.
Linker Script Modification
The toolchain must preserve initializasion function pointers across distinct memory segments. Inject the following directives into the vendor-specific linker script to correctly map the .text region:
__zinitcall_bsp_start = .;
KEEP(*(.zinitcall.bsp0.init))
KEEP(*(.zinitcall.bsp1.init))
KEEP(*(.zinitcall.bsp2.init))
KEEP(*(.zinitcall.bsp3.init))
KEEP(*(.zinitcall.bsp4.init))
__zinitcall_bsp_end = .;
__zinitcall_device_start = .;
KEEP(*(.zinitcall.device0.init))
KEEP(*(.zinitcall.device1.init))
KEEP(*(.zinitcall.device2.init))
KEEP(*(.zinitcall.device3.init))
KEEP(*(.zinitcall.device4.init))
__zinitcall_device_end = .;
__zinitcall_core_start = .;
KEEP(*(.zinitcall.core0.init))
KEEP(*(.zinitcall.core1.init))
KEEP(*(.zinitcall.core2.init))
KEEP(*(.zinitcall.core3.init))
KEEP(*(.zinitcall.core4.init))
__zinitcall_core_end = .;
__zinitcall_sys_service_start = .;
KEEP(*(.zinitcall.sys.service0.init))
KEEP(*(.zinitcall.sys.service1.init))
KEEP(*(.zinitcall.sys.service2.init))
KEEP(*(.zinitcall.sys.service3.init))
KEEP(*(.zinitcall.sys.service4.init))
__zinitcall_sys_service_end = .;
__zinitcall_sys_feature_start = .;
KEEP(*(.zinitcall.sys.feature0.init))
KEEP(*(.zinitcall.sys.feature1.init))
KEEP(*(.zinitcall.sys.feature2.init))
KEEP(*(.zinitcall.sys.feature3.init))
KEEP(*(.zinitcall.sys.feature4.init))
__zinitcall_sys_feature_end = .;
__zinitcall_run_start = .;
KEEP(*(.zinitcall.run0.init))
KEEP(*(.zinitcall.run1.init))
KEEP(*(.zinitcall.run2.init))
KEEP(*(.zinitcall.run3.init))
KEEP(*(.zinitcall.run4.init))
__zinitcall_run_end = .;
__zinitcall_app_service_start = .;
KEEP(*(.zinitcall.app.service0.init))
KEEP(*(.zinitcall.app.service1.init))
KEEP(*(.zinitcall.app.service2.init))
KEEP(*(.zinitcall.app.service3.init))
KEEP(*(.zinitcall.app.service4.init))
__zinitcall_app_service_end = .;
__zinitcall_app_feature_start = .;
KEEP(*(.zinitcall.app.feature0.init))
KEEP(*(.zinitcall.app.feature1.init))
KEEP(*(.zinitcall.app.feature2.init))
KEEP(*(.zinitcall.app.feature3.init))
KEEP(*(.zinitcall.app.feature4.init))
__zinitcall_app_feature_end = .;
__zinitcall_test_start = .;
KEEP(*(.zinitcall.test0.init))
KEEP(*(.zinitcall.test1.init))
KEEP(*(.zinitcall.test2.init))
KEEP(*(.zinitcall.test3.init))
KEEP(*(.zinitcall.test4.init))
__zinitcall_test_end = .;
__zinitcall_exit_start = .;
KEEP(*(.zinitcall.exit0.init))
KEEP(*(.zinitcall.exit1.init))
KEEP(*(.zinitcall.exit2.init))
KEEP(*(.zinitcall.exit3.init))
KEEP(*(.zinitcall.exit4.init))
__zinitcall_exit_end = .;
SDK Task Initialization
The hardware abstraction layer must spawn the primary execution thread after completing low-level setup and kernel initialization. The following routine demonstrates the thread configuration and scheduler activation:
void FrameworkBootEntry(void)
{
OsInitializeCoreFramework();
printf("System initialization complete. Execution environment ready.\n");
}
int HardwareEntryPoint(VOID)
{
PeripheralInitPhase();
if (LOS_KernelInit() == LOS_OK) {
TSK_INIT_PARAM_T threadConfig = {0};
threadConfig.usTaskPrio = 14;
threadConfig.pcName = "BootManager";
threadConfig.pfnTaskEntry = (TSK_ENTRY_FUNC)FrameworkBootEntry;
threadConfig.uwStackSize = 10240;
UINT32 taskHandle = 0;
if (LOS_TaskCreate(&taskHandle, &threadConfig) == LOS_OK) {
LOS_Start();
} else {
printf("[ERROR] Thread creation failed.\n");
}
} else {
printf("[FATAL] Kernel initialization unsuccessful.\n");
}
while (1);
}