Porting the Startup Subsystem

The startup subsystem is responsible for starting key system processes and services after the kernel is started and before applications are started.

Procedure

For the mini system, the startup entry identifiers of services and functions are provided. When SAMGR is started, the entry function identified by bootstrap is called and system services are started.

After the adaptation is complete, call the OHOS_SystemInit() API to start the system.

Path: base/startup/bootstrap_lite/services/source/system_init.c

void OHOS_SystemInit(void)
{
    MODULE_INIT(bsp);           // Execute the function in the .zinitcall.bspX.init section.
    MODULE_INIT(device);        // Execute the function in the .zinitcall.deviceX.init section.
    MODULE_INIT(core);          // Execute the function in the .zinitcall.coreX.init section.
    SYS_INIT(service);          // Execute the function in the .zinitcall.sys.serviceX.init section.
    SYS_INIT(feature);          // Execute the function in the .zinitcall.sys.featureX.init section.
    MODULE_INIT(run);           // Execute the function in the .zinitcall.runX.init section.
    SAMGR_Bootstrap();          // Initialize the SAMGR service.
}

Example

  1. Add the startup subsystem to the config.json file.

    Path: vendor/MyVendorCompany/MyProduct/config.json

    The sample code is as follows:

    {
        subsystem": "startup",
        components": [
            { "component": "bootstrap_lite", "features":[] },
            { "component": "syspara_lite", "features":[] }
        ]
    },
    

    Some components (such as syspara_lite) in the startup subsystem depend on the modules in $ohos_product_adapter_dir/utils. In the preceding information, ohos_product_adapter_dir is the value of product_adapter_dir configured in the config.json file. Generally, ohos_product_adapter_dir is set to vendor/MyVendorCompany/MyProduct/hals.

  2. Add the zinitcall and run definitions.

    Add the following code to the .text section in the vendor .ld linking script:

        __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 = .; // SAMGR executes the function in the .zinitcall.app.featureX.init section.
        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 = .; // SAMGR executes the function in the .zinitcall.app.featureX.init section.
        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 = .;
    
  3. The chip SDK creates a task.

    Set task parameters. After the system is started, start the task. The following is an example:

    void mainTask(void) {
       // Vendor-defined function
        OHOS_SystemInit();        // Initialize the startup subsystem.
        printf("MainTask running...\n");
    }
     
    void main(VOID) {
       // Initialize the hardware and redirect the printf output to the debug serial port.
        if (LOS_KernelInit() == 0) {            // Initialize the kernel.
            task_init_param.usTaskPrio = 10;    // Task priority.
            task_init_param.pcName = "mainTask"; // Task process name.
            task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)mainTask; // Task entry function.
            task_init_param.uwStackSize = 8192;          // Size of the task stack.
            LOS_TaskCreate(&tid, &task_init_param);      // Create a task.
            LOS_Start();                                 // Start the task.
        }
        else {
            printf("[BUG] LOS_KernelInit fail\n");
        }
        printf("[BUG] reach to unexpected code\n");
        while (1);
    }