当前位置: 首页 > news >正文

郑州东站附近网站建设公司中国最新军事新闻西陆网

郑州东站附近网站建设公司,中国最新军事新闻西陆网,网页打不开但是有网什么原因禁用,成都网站搭建公司启动流程(基于openharmony4.1) 系统上电加载内核后#xff0c;按照以下流程完成系统各个服务和应用的启动#xff1a; 内核加载init进程#xff0c;一般在bootloader启动内核时通过设置内核的cmdline来指定init的位置。init进程启动后#xff0c;会挂载tmpfs#xff0c;…启动流程(基于openharmony4.1) 系统上电加载内核后按照以下流程完成系统各个服务和应用的启动 内核加载init进程一般在bootloader启动内核时通过设置内核的cmdline来指定init的位置。init进程启动后会挂载tmpfsprocfs创建基本的dev设备节点提供最基本的根文件系统。init也会启动ueventd监听内核热插拔设备事件为这些设备创建dev设备节点。包括block设备各个分区设备都是通过此事件创建。init进程挂载block设备各个分区systemvendor后开始扫描各个系统服务的init启动脚本并拉起各个SA服务。samgr是各个SA的服务注册中心每个SA启动时都需要向samgr注册每个SA会分配一个ID应用可以通过该ID访问SA。foundation是一个特殊的SA服务进程提供了用户程序管理框架及基础服务。由该进程负责应用的生命周期管理。由于应用都需要加载JS的运行环境涉及大量准备工作因此appspawn作为应用的孵化器在接收到foundation里的应用启动请求时可以直接孵化出应用进程减少应用启动时间。 启动子系统内部涉及以下组件 init启动引导组件 init启动引导组件对应的进程为init进程是内核完成初始化后启动的第一个用户态进程。init进程启动之后读取init.cfg配置文件根据解析结果执行相应命令见job解析接口说明并依次启动各关键系统服务进程在启动系统服务进程的同时设置其对应权限。 ueventd启动引导组件 ueventd负责监听内核设备驱动插拔的netlink事件根据事件类型动态管理相应设备的dev节点。 appspawn应用孵化组件 负责接收用户程序框架的命令孵化应用进程设置新进程的权限并调用应用程序框架的入口函数。 bootstrap服务启动组件 提供了各服务和功能的启动入口标识。在SAMGR启动时会调用bootstrap标识的入口函数并启动系统服务。 图1 启动子系统上下文结构图 约束与限制 启动恢复子系统源代码目录和适配平台 表1 启动恢复子系统源代码目录和适配平台 名称适配平台base/startup/appspawne小型系统设备参考内存≥1MB、 标准系统如Hi3516DV300nbsp、Hi3518EV300、 RK3568base/startup/bootstrap_lite轻量系统设备参考内存≥128KB如Hi3861V100base/startup/init小型系统设备参考内存≥1MB、标准系统如Hi3516DV300、Hi3518EV300、RK3568 init启动引导组件 每个系统服务启动时都需要编写各自的启动脚本文件init.cfg定义各自的服务名、可执行文件路径、权限和其他信息。每个系统服务各自安装其启动脚本到/system/etc/init目录下init进程统一扫码执行。 新芯片平台移植时平台相关的初始化配置需要增加平台相关的初始化配置文件/vendor/etc/init/init.{hardware}.cfg该文件完成平台相关的初始化设置如安装ko驱动设置平台相关的/proc节点信息。 说明 配置文件init.cfg仅支持json格式。 bootstrap服务启动组件需要在链接脚本中配置zInit代码段。 bootstrap服务启动组件实现了服务的自动初始化即服务的初始化函数无需显式调用而是将其使用宏定义的方式申明就会在系统启动时自动被执行。实现原理是将服务启动的函数通过宏定义的方式申明之后放在预定义好的zInit代码段中系统启动的时候调用OHOS_SystemInit接口遍历该代码段并调用其中的函数。因此需要在链接脚本中添加zInit段并且在main函数里调用OHOS_SystemInit接口。 zInit段的添加可参考已有的Hi3861平台的链接脚本文件路径为vendor/hisi/hi3861/hi3861/build/link/link.ld.S。 用于实现服务的自动初始化的宏定义接口请参见启动恢复子系统的API接口文档。 接口说明 bootstrap服务自动初始化宏如表1所述。 表1 主要的服务自动初始化宏 接口名描述SYS_SERVICE_INIT(func)标识核心系统服务的初始化启动入口。SYS_FEATURE_INIT(func)标识核心系统功能的初始化启动入口。APP_SERVICE_INIT(func)标识应用层服务的初始化启动入口。APP_FEATURE_INIT(func)标识应用层功能的初始化启动入口。开发实例 服务自动初始化宏使用实例 void SystemServiceInit(void) {printf(Init System Service\n); } SYS_SERVICE_INIT(SystemServiceInit);void SystemFeatureInit(void) {printf(Init System Feature\n); } SYS_FEATURE_INIT(SystemFeatureInit);void AppServiceInit(void) {printf(Init App Service\n); } APP_SERVICE_INIT(AppServiceInit);void AppFeatureInit(void) {printf(Init App Feature\n); } APP_FEATURE_INIT(AppFeatureInit);// 日志打印顺序为 // Init System Service // Init System Feature // Init App Service // Init App Feature启动引导OpenHarmony标准系统的详细流程 当前OpenHarmony标准系统默认支持以下几个镜像 镜像名称挂载点说明boot.imgNA内核和ramdisk镜像bootloader加载的第一个镜像system.img/system系统组件镜像存放与芯片方案无关的平台业务vendor.img/vendor芯片组件镜像存放芯片相关的硬件抽象服务updater.img/升级组件镜像用于完成升级正常启动时不加载次镜像userdata.img/data可写的用户数据镜像 每个开发板都需要在存储器上划分好分区来存放上述镜像SOC启动时都由bootloader来加载这些镜像具体过程包括以下几个大的步骤 bootloader初始化ROM和RAM等硬件加载分区表信息。bootloader根据分区表加载boot.img从中解析并加载ramdisk.img到内存中。bootloader准备好分区表信息ramdisk地址等信息进入内核内核加载ramdisk并执行init。init准备初始文件系统挂载required.fstab包括system.img和vendor.img的挂载。扫描system.img和vendor.img中etc/init目录下的启动配置脚本执行各个启动命令。 u-boot启动 u-boot加载 支持了ramdisk的启动过程此场景需要修改productdefine中的产品配置文件通过enable_ramdisk开关开启ramdisk生成这一部分与平台相关不同的平台对于ramdisk的处理方式不一样。以Hi3516DV300平台为例需要将u-boot中的原启动参数修改为root/dev/ram0 initrd0x84000000,0x292e00。 uboot引导内核启动 u-boot进入 u-boot启动进入内核时可以通过bootargs传递关键信息给内核这一部分内容是与平台相关的主要信息如下 名称示例说明initrd0x84000000,0x292e00参考内核文档。ramfs-rootfs-initramfs.rstinitrd.rstinit/initblkdevpartsmmcblk0:1M(boot),15M(kernel),200M(system),200M(vendor),2M(misc),20M(updater),-(userdata)分区表信息kernel会根据此信息创建物理分区。hardwareHi3516DV300、rk3568等必要信息硬件平台。root/dev/ram0Hi3516DV00)、rootPARTUUID614e0000-0000 rwrk3568kernel加载的启动设备。rootfstypeext4根文件系统类型。default_boot_devicesoc/10100000.himci.eMMC建议配置信息默认启动设备在启动第一阶段会根据这个参数创建required设备的软链接。ohos.required_mount.xxx/dev/block/platform/soc/10100000.himci.eMMC/by-name/xxx/usrext4ro,barrier1wait,required现支持从cmdline中读取fstab信息获取失败的情况下会继续尝试从fstab.required文件中读取 图 内核启动流程图 表 启动框架层级 层级说明LOS_INIT_LEVEL_EARLIEST最早期初始化说明不依赖架构单板以及后续模块会对其有依赖的纯软件模块初始化例如Trace模块LOS_INIT_LEVEL_ARCH_EARLY架构早期初始化说明架构相关后续模块会对其有依赖的模块初始化如启动过程中非必需的功能建议放到LOS_INIT_LEVEL_ARCH层LOS_INIT_LEVEL_PLATFORM_EARLY平台早期初始化说明单板平台、驱动相关后续模块会对其有依赖的模块初始化如启动过程中必需的功能建议放到LOS_INIT_LEVEL_PLATFORM层例如uart模块LOS_INIT_LEVEL_KMOD_PREVM内存初始化前的内核模块初始化说明在内存初始化之前需要使能的模块初始化LOS_INIT_LEVEL_VM_COMPLETE基础内存就绪后的初始化说明此时内存初始化完毕需要进行使能且不依赖进程间通讯机制与系统进程的模块初始化例如共享内存功能LOS_INIT_LEVEL_ARCH架构后期初始化说明架构拓展功能相关后续模块会对其有依赖的模块初始化LOS_INIT_LEVEL_PLATFORM平台后期初始化说明单板平台、驱动相关后续模块会对其有依赖的模块初始化例如驱动内核抽象层初始化mmc、mtdLOS_INIT_LEVEL_KMOD_BASIC内核基础模块初始化说明内核可拆卸的基础模块初始化例如VFS初始化LOS_INIT_LEVEL_KMOD_EXTENDED内核扩展模块初始化说明内核可拆卸的扩展模块初始化例如系统调用初始化、ProcFS初始化、Futex初始化、HiLog初始化、HiEvent初始化、LiteIPC初始化LOS_INIT_LEVEL_KMOD_TASK内核任务创建说明进行内核任务的创建内核任务软件定时器任务例如资源回收系统常驻任务的创建、SystemInit任务创建、CPU占用率统计任务创建LOS_INIT_LEVEL_FINISH内核初始化完成 汇编阶段(LiteOS-A内核) uboot引导LiteOS-A启动入口 kernel\liteos_a\tools\build\liteos.ld ENTRY(reset_vector) INCLUDE board.ld SECTIONS {_start .;.set_sysinit_set : {__start_set_sysinit_set ABSOLUTE(.);KEEP (*(.set_sysinit_set))__stop_set_sysinit_set ABSOLUTE(.);} ram... }reset_vector就是整个鸿蒙内核启动入口点这是个符号定义在 kernel\liteos_a\arch\arm\arm\src\startup\reset_vector_mp.S, 这个文件是多核使用的同目录下的reset_vector_up.S是单核使用的。 bl main_start_hang:b _start_hang通过main函数进入内核的C语言阶段 c语言阶段(LiteOS-A内核) kernel\liteos_a\kernel\common\main.c /*** brief * 内核入口函数,由汇编调用,见于reset_vector_up.S 和 reset_vector_mp.S * up指单核CPU, mp指多核CPU bl main* return LITE_OS_SEC_TEXT_INIT */ LITE_OS_SEC_TEXT_INIT INT32 main(VOID)//由主CPU执行,默认0号CPU 为主CPU {UINT32 ret OsMain();if (ret ! LOS_OK) {return (INT32)LOS_NOK;}CPU_MAP_SET(0, OsHwIDGet());//设置主CPU映射信息OsSchedStart();//调度开始while (1) {__asm volatile(wfi);//WFI: wait for Interrupt 等待中断即下一次中断发生前都在此hold住不干活} }kernel\liteos_a\kernel\common\los_config.c ///由汇编调用,鸿蒙C语言层级的入口点 LITE_OS_SEC_TEXT_INIT UINT32 OsMain(VOID) {UINT32 ret; #ifdef LOS_INIT_STATISTICSUINT64 startNsec, endNsec, durationUsec; #endifret EarliestInit();//鸿蒙初开天地混沌if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_EARLIEST);ret ArchEarlyInit(); //架构级初始化,包括硬中断if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_ARCH_EARLY);ret PlatformEarlyInit();//平台级初始化if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_PLATFORM_EARLY);/* system and chip info */OsSystemInfo();PRINT_RELEASE(\nmain core booting up...\n);#ifdef LOS_INIT_STATISTICSstartNsec LOS_CurrNanosec(); #endif//进程模块初始化ret OsProcessInit();if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_KMOD_PREVM);ret OsSysMemInit();//系统内存初始化if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_VM_COMPLETE);ret OsIpcInit();//进程间通讯模块初始化if (ret ! LOS_OK) {return ret;}ret OsSystemProcessCreate();//创建系统进程 if (ret ! LOS_OK) {return ret;}ret ArchInit(); //MMU架构初始化if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_ARCH);ret PlatformInit();if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_PLATFORM);ret KModInit();if (ret ! LOS_OK) {return ret;}OsInitCall(LOS_INIT_LEVEL_KMOD_BASIC);OsInitCall(LOS_INIT_LEVEL_KMOD_EXTENDED);#ifdef LOSCFG_KERNEL_SMPOsSmpInit(); #endifOsInitCall(LOS_INIT_LEVEL_KMOD_TASK);#ifdef LOS_INIT_STATISTICSendNsec LOS_CurrNanosec();durationUsec (endNsec - startNsec) / OS_SYS_NS_PER_US;PRINTK(The main core takes %lluus to start.\n, durationUsec); #endifreturn LOS_OK; }....../*! 进程模块初始化,被编译放在代码段 .init 中*/ UINT32 OsProcessInit(VOID) {UINT32 index;UINT32 size;UINT32 ret;g_processMaxNum LOSCFG_BASE_CORE_PROCESS_LIMIT;//默认支持64个进程size (g_processMaxNum 1) * sizeof(LosProcessCB);g_processCBArray (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);// 进程池占用内核堆,内存池分配 if (g_processCBArray NULL) {return LOS_NOK;}(VOID)memset_s(g_processCBArray, size, 0, size);//安全方式重置清0LOS_ListInit(g_freeProcess);//进程空闲链表初始化创建一个进程时从g_freeProcess中申请一个进程描述符使用LOS_ListInit(g_processRecycleList);//进程回收链表初始化,回收完成后进入g_freeProcess等待再次被申请使用for (index 0; index g_processMaxNum; index) {//进程池循环创建g_processCBArray[index].processID index;//进程ID[0-g_processMaxNum-1]赋值g_processCBArray[index].processStatus OS_PROCESS_FLAG_UNUSED;// 默认都是白纸一张,贴上未使用标签LOS_ListTailInsert(g_freeProcess, g_processCBArray[index].pendList);//注意g_freeProcess挂的是pendList节点,所以使用要通过OS_PCB_FROM_PENDLIST找到进程实体.}/* Default process to prevent thread PCB from being empty */g_processCBArray[index].processID index;g_processCBArray[index].processStatus OS_PROCESS_FLAG_UNUSED;ret OsTaskInit((UINTPTR)g_processCBArray[g_processMaxNum]);if (ret ! LOS_OK) {(VOID)LOS_MemFree(m_aucSysMem1, g_processCBArray);return LOS_OK;}#ifdef LOSCFG_KERNEL_CONTAINEROsInitRootContainer(); #endif #ifdef LOSCFG_KERNEL_PLIMITSOsProcLimiterSetInit(); #endifSystemProcessEarlyInit(OsGetIdleProcess());//初始化 0,1,2号进程SystemProcessEarlyInit(OsGetUserInitProcess());SystemProcessEarlyInit(OsGetKernelInitProcess());return LOS_OK; } . . . . . . #ifndef LOSCFG_PLATFORM_ADAPT STATIC VOID SystemInit(VOID) {PRINTK(dummy: *** %s ***\n, __FUNCTION__); } #else extern VOID SystemInit(VOID); #endif #ifndef LOSCFG_ENABLE_KERNEL_TEST ///创建系统初始任务并申请调度 STATIC UINT32 OsSystemInitTaskCreate(VOID) {UINT32 taskID;TSK_INIT_PARAM_S sysTask;(VOID)memset_s(sysTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));sysTask.pfnTaskEntry (TSK_ENTRY_FUNC)SystemInit;//任务入口函数sysTask.uwStackSize LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16ksysTask.pcName SystemInit;//任务名称sysTask.usTaskPrio LOSCFG_BASE_CORE_TSK_DEFAULT_PRIO;//内核默认优先级10sysTask.uwResved LOS_TASK_STATUS_DETACHED;//任务分离模式 #ifdef LOSCFG_KERNEL_SMPsysTask.usCpuAffiMask CPUID_TO_AFFI_MASK(ArchCurrCpuid()); #endifreturn LOS_TaskCreate(taskID, sysTask); }//系统任务初始化 STATIC UINT32 OsSystemInit(VOID) {UINT32 ret;ret OsSystemInitTaskCreate();if (ret ! LOS_OK) {return ret;}return 0; }//在内核初始化的时候初始化该模块则通过内核启动框架将该模块的初始化函数注册进内核启动流程 LOS_MODULE_INIT(OsSystemInit, LOS_INIT_LEVEL_KMOD_TASK);//模块初始化 #endif通过上述调用最终调用到SystemInit任务,跳转到soc的SystemInit()做系统初始化。 device\soc\hisilicon\hi3516dv300\sdk_liteos\mpp\module_init\src\system_init.c void SystemInit(void) {SystemInit_QuickstartInit();SystemInit_IPCM();SystemInit_RandomInit();SystemInit_MMCInit();SystemInit_MemDevInit();SystemInit_GpioDevInit();SystemInit_SDKInit();SystemInit_HDFInit();SystemInit_NetInit(); /* need to check later */SystemInit_MountRootfs();SystemInit_ConsoleInit(); #ifndef LOSCFG_DRIVERS_QUICKSTARTSystemInit1();SystemInit2();SystemInit3(); #endifSystemInit_UserInitProcess(); }void SystemInit_UserInitProcess(void) {if (OsUserInitProcess()) {//跳转回到内核创建1号init进程PRINT_ERR(Create user init process faialed!\n);return;}return; }kernel\liteos_a\kernel\base\core\los_process.c LITE_OS_SEC_TEXT_INIT UINT32 OsUserInitProcess(VOID) {UINT32 ret;UINT32 size;TSK_INIT_PARAM_S param { 0 };VOID *stack NULL;//获取用户态进程的根进程,所有用户进程都是g_processCBArray[g_userInitProcess] fork来的LosProcessCB *processCB OsGetUserInitProcess();ret OsSystemProcessInit(processCB, OS_USER_MODE, Init);// 进程创建初始化if (ret ! LOS_OK) {return ret;}ret OsLoadUserInit(processCB);if (ret ! LOS_OK) {goto ERROR;}stack OsUserInitStackAlloc(processCB, size);//初始化堆栈区分配栈内存if (stack NULL) {PRINT_ERR(Alloc user init process user stack failed!\n);goto ERROR;}//代码区开始位置对应LITE_USER_SEC_ENTRYparam.pfnTaskEntry (TSK_ENTRY_FUNC)(CHAR *)__user_init_entry;param.userParam.userSP (UINTPTR)stack size;//指向栈顶param.userParam.userMapBase (UINTPTR)stack;//栈底param.userParam.userMapSize size;//栈大小param.uwResved OS_TASK_FLAG_PTHREAD_JOIN;//能够被其他线程收回其资源和啥事ret OsUserInitProcessStart(processCB, param);//用户进程开始初始化if (ret ! LOS_OK) {(VOID)OsUnMMap(processCB-vmSpace, param.userParam.userMapBase, param.userParam.userMapSize);goto ERROR;}return LOS_OK;ERROR:OsDeInitPCB(processCB);return ret; }STATIC UINT32 OsUserInitProcessStart(LosProcessCB *processCB, TSK_INIT_PARAM_S *param) {UINT32 intSave;INT32 ret;UINT32 taskID OsCreateUserTask((UINTPTR)processCB, param);if (taskID OS_INVALID_VALUE) {return LOS_NOK;}//设置进程优先级ret LOS_SetProcessPriority(processCB-processID, OS_PROCESS_USERINIT_PRIORITY);if (ret ! LOS_OK) {PRINT_ERR(User init process set priority failed! ERROR:%d \n, ret);goto EXIT;}SCHEDULER_LOCK(intSave);processCB-processStatus ~OS_PROCESS_STATUS_INIT;SCHEDULER_UNLOCK(intSave);//调度器:设置为抢占式调度和最低任务优先级(31级)ret LOS_SetTaskScheduler(taskID, LOS_SCHED_RR, OS_TASK_PRIORITY_LOWEST);if (ret ! LOS_OK) {PRINT_ERR(User init process set scheduler failed! ERROR:%d \n, ret);goto EXIT;}return LOS_OK;EXIT:(VOID)LOS_TaskDelete(taskID);return ret; }__user_init_entry在编译链接文件 kernel\liteos_a\tools\build\liteos.ld 中 .user_init USER_INIT_VM_START : ALIGN(0x1000) {. ALIGN(0x4);__user_init_load_addr LOADADDR(.user_init);__user_init_entry .;KEEP(libuserinit.O (.user.entry))//地址指向镜像的.user.entryKEEP(libuserinit.O (.user.text))KEEP(libuserinit.O (.user.rodata)). ALIGN(0X4);__user_init_data .;KEEP(libuserinit.O (.user.data)). ALIGN(0X4);__user_init_bss .;KEEP(libuserinit.O (.user.bss)). ALIGN(0x1000);__user_init_end .;} user_ram AT ram.user.entry通过宏定义在 kernel\liteos_a\kernel\user\include\los_user_init.h中 #ifndef LITE_USER_SEC_TEXT #define LITE_USER_SEC_TEXT __attribute__((section(.user.text))) #endif#ifndef LITE_USER_SEC_ENTRY #define LITE_USER_SEC_ENTRY __attribute__((section(.user.entry))) #endif#ifndef LITE_USER_SEC_DATA #define LITE_USER_SEC_DATA __attribute__((section(.user.data))) #endif#ifndef LITE_USER_SEC_RODATA #define LITE_USER_SEC_RODATA __attribute__((section(.user.rodata))) #endif#ifndef LITE_USER_SEC_BSS #define LITE_USER_SEC_BSS __attribute__((section(.user.bss))) #endifinit进程启动进入函数OsUserInit kernel\liteos_a\kernel\user\src\los_user_init.c #ifdef LOSCFG_QUICK_START LITE_USER_SEC_RODATA STATIC CHAR *g_initPath /dev/shm/init; #else LITE_USER_SEC_RODATA STATIC CHAR *g_initPath /bin/init;//由Init_lite在编译后,生成 #endif ///将 sys_call3 链接在 section(.user.text)段 LITE_USER_SEC_TEXT STATIC UINT32 sys_call3(UINT32 nbr, UINT32 parm1, UINT32 parm2, UINT32 parm3) {register UINT32 reg7 __asm__(r7) (UINT32)(nbr); //系统调用号给了R7寄存器register UINT32 reg2 __asm__(r2) (UINT32)(parm3);//R2 参数3register UINT32 reg1 __asm__(r1) (UINT32)(parm2);//R1 参数2register UINT32 reg0 __asm__(r0) (UINT32)(parm1);//R0 参数1//SVC指令会触发一个特权调用异常。这为非特权软件调用操作系统或其他只能在PL1级别访问的系统组件提供了一种机制。__asm__ __volatile__(svc %1 //管理模式svc 10011操作系统使用的保护模式: r(reg0) //输出寄存器为R0: i(SYS_CALL_VALUE), r(reg7), r(reg0), r(reg1), r(reg2): memory, r14);//相当于执行了 reset_vector_mp.S 中的 向量表0x08对应的 _osExceptSwiHdl return reg0;//reg0的值将在汇编中改变. }LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) { #ifdef LOSCFG_KERNEL_DYNLOADsys_call3(__NR_execve, (UINTPTR)g_initPath, 0, 0);//发起系统调用,陷入内核态,对应 SysExecve ,加载elf运行 #endifwhile (true) {} } #endif最终启动了/bin/init可执行程序 标准linux内核 kernel\linux\linux-5.10\init\main.c 各种模块的初始化 asmlinkage __visible void __init __no_sanitize_address start_kernel(void) {char *command_line;char *after_dashes;set_task_stack_end_magic(init_task);smp_setup_processor_id();debug_objects_early_init();cgroup_init_early();local_irq_disable();early_boot_irqs_disabled true;/** Interrupts are still disabled. Do necessary setups, then* enable them.*/boot_cpu_init();page_address_init();pr_notice(%s, linux_banner);early_security_init();setup_arch(command_line);setup_boot_config(command_line);setup_command_line(command_line);setup_nr_cpu_ids();setup_per_cpu_areas();smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */boot_cpu_hotplug_init();build_all_zonelists(NULL);page_alloc_init();pr_notice(Kernel command line: %s\n, saved_command_line);/* parameters may set static keys */jump_label_init();parse_early_param();after_dashes parse_args(Booting kernel,static_command_line, __start___param,__stop___param - __start___param,-1, -1, NULL, unknown_bootoption);if (!IS_ERR_OR_NULL(after_dashes))parse_args(Setting init args, after_dashes, NULL, 0, -1, -1,NULL, set_init_arg);if (extra_init_args)parse_args(Setting extra init args, extra_init_args,NULL, 0, -1, -1, NULL, set_init_arg);/** These use large bootmem allocations and must precede* kmem_cache_init()*/setup_log_buf(0);vfs_caches_init_early();sort_main_extable();trap_init();mm_init();ftrace_init();/* trace_printk can be enabled here */early_trace_init();/** Set up the scheduler prior starting any interrupts (such as the* timer interrupt). Full topology setup happens at smp_init()* time - but meanwhile we still have a functioning scheduler.*/sched_init();if (WARN(!irqs_disabled(),Interrupts were enabled *very* early, fixing it\n))local_irq_disable();radix_tree_init();/** Set up housekeeping before setting up workqueues to allow the unbound* workqueue to take non-housekeeping into account.*/housekeeping_init();/** Allow workqueue creation and work item queueing/cancelling* early. Work item execution depends on kthreads and starts after* workqueue_init().*/workqueue_init_early();rcu_init();/* Trace events are available after this */trace_init();if (initcall_debug)initcall_debug_enable();context_tracking_init();/* init some links before init_ISA_irqs() */early_irq_init();init_IRQ();tick_init();rcu_init_nohz();init_timers();hrtimers_init();softirq_init();timekeeping_init();time_init();/** For best initial stack canary entropy, prepare it after:* - setup_arch() for any UEFI RNG entropy and boot cmdline access* - timekeeping_init() for ktime entropy used in random_init()* - time_init() for making random_get_entropy() work on some platforms* - random_init() to initialize the RNG from from early entropy sources*/random_init(command_line);boot_init_stack_canary();perf_event_init();profile_init();call_function_init();WARN(!irqs_disabled(), Interrupts were enabled early\n);early_boot_irqs_disabled false;local_irq_enable();kmem_cache_init_late();/** HACK ALERT! This is early. Were enabling the console before* weve done PCI setups etc, and console_init() must be aware of* this. But we do want output early, in case something goes wrong.*/console_init();if (panic_later)panic(Too many boot %s vars at %s, panic_later,panic_param);lockdep_init();/** Need to run this when irqs are enabled, because it wants* to self-test [hard/soft]-irqs on/off lock inversion bugs* too:*/locking_selftest();/** This needs to be called before any devices perform DMA* operations that might use the SWIOTLB bounce buffers. It will* mark the bounce buffers as decrypted so that their usage will* not cause plain-text data to be decrypted when accessed.*/mem_encrypt_init();#ifdef CONFIG_BLK_DEV_INITRDif (initrd_start !initrd_below_start_ok page_to_pfn(virt_to_page((void *)initrd_start)) min_low_pfn) {pr_crit(initrd overwritten (0x%08lx 0x%08lx) - disabling it.\n,page_to_pfn(virt_to_page((void *)initrd_start)),min_low_pfn);initrd_start 0;} #endifsetup_per_cpu_pageset();numa_policy_init();acpi_early_init();if (late_time_init)late_time_init();sched_clock_init();calibrate_delay();pid_idr_init();anon_vma_init(); #ifdef CONFIG_X86if (efi_enabled(EFI_RUNTIME_SERVICES))efi_enter_virtual_mode(); #endifthread_stack_cache_init();cred_init();fork_init();proc_caches_init();uts_ns_init();buffer_init();key_init();security_init();dbg_late_init();vfs_caches_init();pagecache_init();signals_init();seq_file_init();proc_root_init();nsfs_init();cpuset_init();cgroup_init();taskstats_init_early();delayacct_init(); #ifdef CONFIG_RECLAIM_ACCTreclaimacct_init(); #endifpoking_init();check_bugs();acpi_subsystem_init();arch_post_acpi_subsys_init();sfi_init_late();kcsan_init();/* Do the rest non-__inited, were now alive */arch_call_rest_init();prevent_tail_call_optimization(); } . . . . . void __init __weak arch_call_rest_init(void) {rest_init(); }noinline void __ref rest_init(void) {struct task_struct *tsk;int pid;rcu_scheduler_starting();/** We need to spawn init first so that it obtains pid 1, however* the init task will end up wanting to create kthreads, which, if* we schedule it before we create kthreadd, will OOPS.*/启动1号进程initpid kernel_thread(kernel_init, NULL, CLONE_FS);/** Pin init on the boot CPU. Task migration is not properly working* until sched_init_smp() has been run. It will set the allowed* CPUs for init to the non isolated CPUs.*/rcu_read_lock();tsk find_task_by_pid_ns(pid, init_pid_ns);set_cpus_allowed_ptr(tsk, cpumask_of(smp_processor_id()));rcu_read_unlock();numa_default_policy();pid kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);rcu_read_lock();kthreadd_task find_task_by_pid_ns(pid, init_pid_ns);rcu_read_unlock();/** Enable might_sleep() and smp_processor_id() checks.* They cannot be enabled earlier because with CONFIG_PREEMPTIONy* kernel_thread() would trigger might_sleep() splats. With* CONFIG_PREEMPT_VOLUNTARYy the init task might have scheduled* already, but its stuck on the kthreadd_done completion.*/system_state SYSTEM_SCHEDULING;complete(kthreadd_done);/** The boot idle thread must execute schedule()* at least once to get things moving:*/schedule_preempt_disabled();/* Call into cpu_idle with preempt disabled */cpu_startup_entry(CPUHP_ONLINE); }. . . . . . static int __ref kernel_init(void *unused) {int ret;kernel_init_freeable();/* need to finish all async __init code before freeing the memory */async_synchronize_full();kprobe_free_init_mem();ftrace_free_init_mem();kgdb_free_init_mem();free_initmem();mark_readonly();/** Kernel mappings are now finalized - update the userspace page-table* to finalize PTI.*/pti_finalize();system_state SYSTEM_RUNNING;numa_default_policy();rcu_end_inkernel_boot();do_sysctl_args();if (ramdisk_execute_command) {ret run_init_process(ramdisk_execute_command);if (!ret)return 0;pr_err(Failed to execute %s (error %d)\n,ramdisk_execute_command, ret);}/** We try each of these until one succeeds.** The Bourne shell can be used instead of init if we are* trying to recover a really broken machine.*/if (execute_command) {ret run_init_process(execute_command);if (!ret)return 0;panic(Requested init %s failed (error %d).,execute_command, ret);}if (CONFIG_DEFAULT_INIT[0] ! \0) {ret run_init_process(CONFIG_DEFAULT_INIT);if (ret)pr_err(Default init %s failed (error %d)\n,CONFIG_DEFAULT_INIT, ret);elsereturn 0;}//最终启动了/bin/init可执行程序,同liteos-a 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进程 (标准系统) 通过BUILD.gn可知如下路径代码编译成了可执行程序init base\startup\init\services\init\standard\BUILD.gn ohos_executable(init) {sources [../adapter/init_adapter.c,../standard/device.c,../standard/fd_holder_service.c,../standard/init.c,../standard/init_cmdexecutor.c,../standard/init_cmds.c,../standard/init_control_fd_service.c,../standard/init_firststage.c,../standard/init_jobs.c,../standard/init_mount.c,../standard/init_reboot.c,../standard/init_service.c,../standard/init_signal_handler.c,../standard/switch_root.c,bootstagehooker.c,]...... }从init进程main函数开始 base\startup\init\services\init\main.c static const pid_t INIT_PROCESS_PID 1;int main(int argc, char * const argv[]) {const char *uptime NULL;long long upTimeInMicroSecs 0;int isSecondStage 0;//在接收到SIGPIPE信号时,设置成SIG_IGN忽略信号不会中断程序执行而是继续执行后续操作(void)signal(SIGPIPE, SIG_IGN);// Number of command line parameters is 2//从kernel启动的init进程不会携带任何参数从StartInitSecondStage启动的init进程第二阶段会携带参数if (argc 1 (strcmp(argv[1], --second-stage) 0)) {isSecondStage 1;if (argc 2) {uptime argv[2];}} else {upTimeInMicroSecs GetUptimeInMicroSeconds(NULL);}//正常启动init进程的pid为1if (getpid() ! INIT_PROCESS_PID) {INIT_LOGE(Process id error %d!, getpid());return 0;}//使能init阶段logEnableInitLog(INIT_INFO);// Updater modeif (isSecondStage 0) {//从kernel启动的init第一阶段走如下SystemPrepare(upTimeInMicroSecs);} else {//初始化kmsgLogInit();}SystemInit();//执行init进程的初始化注册socketSystemExecuteRcs();//执行Linux的初始化(rcs进程)SystemConfig(uptime);//1. 读取cfg配置文件内容根据是否重启计重启原因加载不同的cfg配置扫描各个系统的启动脚本解析jobs的pre-initinitpost-init合并到一起存储在/etc/init.cfg中其他自命名的job默认在post-init阶段执行2. 解析services配置获取要初始化服务的path、uid、gid等信息/foundation/appspawn等服务3. 最后通过trigger依次执行这些操作执行如创建文件夹文件授权等cmd操作和start service的操作SystemRun();//创建一个LoopEvent处理事件通过epoll实现运行启动service服务return 0; }base\startup\init\services\init\standard\init_firststage.c void SystemPrepare(long long upTimeInMicroSecs) {(void)signal(SIGPIPE, SIG_IGN);EnableInitLog(INIT_INFO);EarlyLogInit();INIT_LOGI(Start init first stage.);//挂载一些目录创建一些设备节点打开/proc/sys/kernel/printk_devkmsg文件//base\startup\init\services\init\standard\device.cCreateFsAndDeviceNode();//钩子函数 插桩//base\startup\init\interfaces\innerkits\hookmgr\hookmgr.cHookMgrExecute(GetBootStageHookMgr(), INIT_FIRST_STAGE, NULL, NULL);// Updater mode no need to mount and switch root//升级模式不进入第二阶段if (InUpdaterMode() ! 0) {return;}//挂载required分区MountRequiredPartitions();//二级启动initStartSecondStageInit(upTimeInMicroSecs); } . . . int InUpdaterMode(void) {const char * const updaterExecutabeFile /bin/updater;if (access(updaterExecutabeFile, X_OK) 0) { //判断/bin/updater文件是否有执行权限,由于文件不存在,所以不可能为0,那么此函数的返回值为0.return 1;} else {return 0;} } . . . static void MountRequiredPartitions(void) {int requiredNum 0;//获取required分区信息Fstab *fstab LoadRequiredFstab();char **devices (fstab ! NULL) ? GetRequiredDevices(*fstab, requiredNum) : NULL;if (devices ! NULL requiredNum 0) {//创建socket触发内核上报uevent事件int ret StartUeventd(devices, requiredNum);if (ret 0) {ret MountRequriedPartitions(fstab);}FreeStringVector(devices, requiredNum);devices NULL;ReleaseFstab(fstab);fstab NULL;if (ret 0) {// If mount required partitions failure.// There is no necessary to continue.// Just abortINIT_LOGE(Mount required partitions failed; please check fstab file);// Execute sh for debugging #ifndef STARTUP_INIT_TESTexecv(/bin/sh, NULL);abort(); #endif}}if (fstab ! NULL) {ReleaseFstab(fstab);fstab NULL;} }static void StartSecondStageInit(long long uptime) {INIT_LOGI(Start init second stage.);// It will panic if close stdio before execv(/bin/sh, NULL)CloseStdio();SwitchRoot(/usr);char buf[64];snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, %lld, uptime);// Execute init second stagechar * const args[] {/bin/init,--second-stage,buf,NULL,};if (execv(/bin/init, args) ! 0) {INIT_LOGE(Failed to exec \/bin/init\, err %d, errno);exit(-1);} }init挂载required分区 (详情介绍见init进程挂载ruquired分区.md) 所谓required分区就是系统启动引导过程的必要分区必须在二级启动开始前进行挂载。比如system、vendor等必选镜像挂载这些镜像前需要先创建对应的块设备文件。这些块设备文件是通过内核上报UEVENT事件来创建的。init需要知道存储器的主设备目录需要bootloader通过default_boot_device传递。 目前init支持两种方式获取required分区信息一是通过保存在/proc/cmdline中的bootargsinit会首先尝试从cmdline读取required分区信息二是通过读取ramdisk中的fstab.required文件只有在前一种方式获取失败的情况下才会尝试通过这种方式获取。 块设备的创建逻辑 准备工作 init从cmdline中读取required fstab若获取失败则尝试读fstab.required文件从中获取必须挂载的块设备的PARTNAME例如system和vendor.创建接收内核上报uevent事件广播消息的socket从/proc/cmdline里读取default_boot_device。带着fstab信息和socket句柄遍历/sys/devices目录准备开始触发内核上报uevent事件。 触发事件 通过ueventd触发内核上报uevent事件匹配uevent事件中的partitionName与required fstab中的device信息。匹配成功后将会进一步处理格式化设备节点路径准备开始创建设备节点。 创建节点 为了便于用户态下对设备节点的访问以及提高设备节点的可读性会对即将创建的required块设备节点同时创建软链接这就需要先格式化软链接的路径。以上工作都完成后将执行最后的创建设备节点的步骤根据传入的uevent中的主次设备号、前置步骤中构建的设备节点路径和软链接路径等创建设备节点并创建相应软链接。 至此块设备节点创建完毕。 与default_boot_device匹配关系 内核将bootargs信息写入/proc/cmdline其中就包含了default_boot_device这个值是内核当中约定好的系统启动必要的主设备目录。以ohos.required_mount.为前缀的内容则是系统启动必要的分区挂载信息其内容与fstab.required文件内容应当是一致的。另外分区挂载信息中的块设备节点就是default_boot_device目录中by-name下软链接指向的设备节点。例如default_boot_device的值为soc/10100000.himci.eMMC那么ohos.required_mount.system的值就包含了/dev/block/platform/soc/10100000.himci.eMMC/by-name/system这个指向system设备节点的软链接路径。 在创建块设备节点的过程中会有一个将设备路径与default_boot_device的值匹配的操作匹配成功后会在/dev/block/by-name目录下创建指向真实块设备节点的软链接以此在访问设备节点的过程中实现芯片平台无关化。 通过StartSecondStageInit函数开始init进程启动的第二阶段 base\startup\init\services\init\main.c static const pid_t INIT_PROCESS_PID 1;int main(int argc, char * const argv[]) {const char *uptime NULL;long long upTimeInMicroSecs 0;int isSecondStage 0;//在接收到SIGPIPE信号时,设置成SIG_IGN忽略信号不会中断程序执行而是继续执行后续操作(void)signal(SIGPIPE, SIG_IGN);// Number of command line parameters is 2//从kernel启动的init进程不会携带任何参数从StartInitSecondStage启动的init进程第二阶段会携带参数if (argc 1 (strcmp(argv[1], --second-stage) 0)) {isSecondStage 1;if (argc 2) {uptime argv[2];}} else {upTimeInMicroSecs GetUptimeInMicroSeconds(NULL);}//正常启动init进程的pid为1if (getpid() ! INIT_PROCESS_PID) {INIT_LOGE(Process id error %d!, getpid());return 0;}//使能init阶段logEnableInitLog(INIT_INFO);// Updater modeif (isSecondStage 0) {//从kernel启动的init第一阶段走如下SystemPrepare(upTimeInMicroSecs);} else {//初始化kmsgLogInit();}SystemInit();//执行init进程的初始化注册socketSystemExecuteRcs();//执行Linux的初始化(rcs进程)SystemConfig(uptime);//1. 读取cfg配置文件内容根据是否重启计重启原因加载不同的cfg配置扫描各个系统的启动脚本解析jobs的pre-initinitpost-init合并到一起存储在/etc/init.cfg中其他自命名的job默认在post-init阶段执行2. 解析services配置获取要初始化服务的path、uid、gid等信息/foundation/appspawn等服务3. 最后通过trigger依次执行这些操作执行如创建文件夹文件授权等cmd操作和start service的操作SystemRun();//创建一个LoopEvent处理事件通过epoll实现运行启动service服务return 0; }由于第二阶段启动携带参数--second-stage,所以走到LogInit(),接着串行执行SystemInit(); base\startup\init\services\init\standard\init.c void LogInit(void) {//创建/dev/kmsg节点文件int ret mknod(/dev/kmsg, S_IFCHR | S_IWUSR | S_IRUSR,makedev(MEM_MAJOR, DEV_KMSG_MINOR));if (ret 0) {//打开节点文件/dev/kmsgOpenLogDevice();} } . . . . . . void SystemInit(void) {CloseStdio(); #ifndef STARTUP_INIT_TEST// Set up a session keyring that all processes will have access to.//设置一个所有进程都可以访问的会话密钥环???//具体见foundation\filemanagement\storage_service\KeyCtrlGetKeyringId(KEY_SPEC_SESSION_KEYRING, 1); #endif// umask call always succeeds and return the previous mask value which is not needed here//设置文件权限(void)umask(DEFAULT_UMASK_INIT);//递归赋予目录权限MakeDirRecursive(/dev/unix/socket, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);int sock FdHolderSockInit();if (sock 0) {RegisterFdHoldWatcher(sock);}InitControlFd();// sysclktz 0//设置系统时间struct timezone tz { 0 };if (settimeofday(NULL, tz) -1) {INIT_LOGE(Set time of day failed, err %d, errno);} } . . . static int FdHolderSockInit(void) {int sock -1;int on 1;int fdHolderBufferSize FD_HOLDER_BUFFER_SIZE; // 4KiB//创建一个本地通信的socket,sock 是创建成功的套接字sock socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);if (sock 0) {INIT_LOGE(Failed to create fd holder socket, err %d, errno);return -1;}setsockopt(sock, SOL_SOCKET, SO_RCVBUFFORCE, fdHolderBufferSize, sizeof(fdHolderBufferSize)); //设置接收缓冲区setsockopt(sock, SOL_SOCKET, SO_PASSCRED, on, sizeof(on));//允许SCM_CREDENTIALS 控制消息的接收if (access(INIT_HOLDER_SOCKET_PATH, F_OK) 0) { //#define INIT_HOLDER_SOCKET_PATH /dev/unix/socket/fd_holderINIT_LOGI(%s exist, remove it, INIT_HOLDER_SOCKET_PATH);unlink(INIT_HOLDER_SOCKET_PATH);}struct sockaddr_un addr;addr.sun_family AF_UNIX;if (strncpy_s(addr.sun_path, sizeof(addr.sun_path),INIT_HOLDER_SOCKET_PATH, strlen(INIT_HOLDER_SOCKET_PATH)) ! 0) {INIT_LOGE(Faild to copy fd hoder socket path);close(sock);return -1;}socklen_t len (socklen_t)(offsetof(struct sockaddr_un, sun_path) strlen(addr.sun_path) 1);if (bind(sock, (struct sockaddr *)addr, len) 0) {INIT_LOGE(Failed to binder fd folder socket %d, errno);close(sock);return -1;}// Owned by rootif (lchown(addr.sun_path, 0, 0)) {INIT_LOGW(Failed to change owner of fd holder socket, err %d, errno);}mode_t mode S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;if (fchmodat(AT_FDCWD, addr.sun_path, mode, AT_SYMLINK_NOFOLLOW)) {INIT_LOGW(Failed to change mode of fd holder socket, err %d, errno);}INIT_LOGI(Init fd holder socket done);return sock; }base\startup\init\services\init\standard\init_control_fd_service.c void InitControlFd(void) {//初始化/dev/unix/socket/init_control_fd对应的处理函数ProcessControlFdCmdServiceInit(INIT_CONTROL_FD_SOCKET_PATH, ProcessControlFd, LE_GetDefaultLoop());return; }base\startup\init\services\init\adapter\init_adapter.c 由于只有小型系统定义了NEED_EXEC_RCS_LINUX所以标准系统不会执行 init程序首先会调用/etc/init.d/rcS脚本rcS脚本执行第一条命令为/bin/mount -a”该命令会加载fstab文件在fstab中的命令执行完后rcS将顺序调用Sxxx脚本完成设备节点创建和扫描、文件权限配置等操作。 void SystemExecuteRcs(void) { #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 processif (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 processsem_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 exitedif (sem_wait(sem) ! 0) {INIT_LOGE(ExecuteRcs, sem_wait failed, err %d., errno);} #endifbase\startup\init\services\init\standard\init.c SystemConfig void SystemConfig(const char *uptime) {INIT_TIMING_STAT timingStat;//设置/proc/self/oom_score_adj 值为-1000InitSysAdj();HOOK_EXEC_OPTIONS options;options.flags 0;options.preHook InitPreHook;options.postHook InitPostHook;//主要就是给g_initWorkspace结构体赋值InitServiceSpace();HookMgrExecute(GetBootStageHookMgr(), INIT_GLOBAL_INIT, (void *)timingStat, (void *)options);//记录开机事件init.prepareRecordInitBootEvent(init.prepare);HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_PARAM_SERVICE, (void *)timingStat, (void *)options);if (InitParamService() ! 0) {ExecReboot(panic);}//将解析的cfg值放入对应的groupNodes中InitParseGroupCfg();//记录开机事件RecordInitBootEvent//设置开机的时间属性ohos.boot.time.initRegisterBootStateChange(BootStateChange);INIT_LOGI(boot stage: init finish.);// load SELinux context and policy// Do not move position!//加载selinux上下文和策略PluginExecCmdByName(loadSelinuxPolicy, );RecordInitBootEvent(init.prepare);// after selinux loaded/*init是一个守护进程为了防止init的子进程成为僵尸进程(zombie process)需要init在子进程在结束时获取子进程的结束码通过结束码将程序表中的子进程移除防止成为僵尸进程的子进程占用程序表的空间程序表的空间达到上限时系统就不能再启动新的进程了会引起严重的系统问题在linux当中父进程是通过捕捉SIGCHLD信号来得知子进程运行结束的情况SIGCHLD信号会在子进程终止的时候发出*/SignalInit();RecordInitBootEvent(init.ParseCfg);//加载系统的一些特殊参数LoadSpecialParam();// parse parametersHookMgrExecute(GetBootStageHookMgr(), INIT_PRE_PARAM_LOAD, (void *)timingStat, (void *)options);//加载系统的参数InitLoadParamFiles();// Write kernel uptime into system parameter//设置kernel启动时间WriteUptimeSysParam(ohos.boot.time.kernel, uptime);// read configHookMgrExecute(GetBootStageHookMgr(), INIT_PRE_CFG_LOAD, (void *)timingStat, (void *)options);//读取cfg参数ReadConfig();RecordInitBootEvent(init.ParseCfg);INIT_LOGI(boot stage: parse config file finish.);HookMgrExecute(GetBootStageHookMgr(), INIT_POST_CFG_LOAD, (void *)timingStat, (void *)options);//根据属性const.sandbox判断sandbox是否启用IsEnableSandbox();// execute init//触发执行对应的init*.cfg中job servicePostTrigger(EVENT_TRIGGER_BOOT, pre-init, strlen(pre-init));PostTrigger(EVENT_TRIGGER_BOOT, init, strlen(init));TriggerServices(START_MODE_BOOT);PostTrigger(EVENT_TRIGGER_BOOT, post-init, strlen(post-init));TriggerServices(START_MODE_NORMAL);clock_gettime(CLOCK_MONOTONIC, (g_bootJob.startTime)); } . . . static void InitLoadParamFiles(void) {if (InUpdaterMode() ! 0) {LoadDefaultParams(/etc/param/ohos_const, LOAD_PARAM_NORMAL);LoadDefaultParams(/etc/param, LOAD_PARAM_ONLY_ADD);LoadDefaultParams(/vendor/etc/param, LOAD_PARAM_ONLY_ADD);return;}// Load developer mode paramLoadDefaultParams(/proc/dsmm/developer, LOAD_PARAM_NORMAL);// Load const params, these cant be override!LoadDefaultParams(/system/etc/param/ohos_const, LOAD_PARAM_NORMAL);CfgFiles *files GetCfgFiles(etc/param);for (int i MAX_CFG_POLICY_DIRS_CNT - 1; files i 0; i--) {if (files-paths[i]) {LoadDefaultParams(files-paths[i], LOAD_PARAM_ONLY_ADD);}}FreeCfgFiles(files); }cfg文件 (具体见cfg文件解析.md) base\startup\init\services\init\init_group_manager.c void InitServiceSpace(void) {if (g_initWorkspace.initFlags ! 0) {return;}HashInfo info {GroupNodeNodeCompare,GroupNodeKeyCompare,GroupNodeGetNodeHashCode,GroupNodeGetKeyHashCode,GroupNodeFree,GROUP_HASHMAP_BUCKET};for (size_t i 0; i ARRAY_LENGTH(g_initWorkspace.hashMap); i) {int ret OH_HashMapCreate(g_initWorkspace.hashMap[i], info);if (ret ! 0) {INIT_LOGE(%s, Failed to create hash map);}}for (int i 0; i NODE_TYPE_MAX; i) {g_initWorkspace.groupNodes[i] NULL;}// get boot mode, set default modestrcpy_s(g_initWorkspace.groupModeStr, sizeof(g_initWorkspace.groupModeStr), BOOT_GROUP_DEFAULT);int ret GetParameterFromCmdLine(BOOT_GROUP_NAME,g_initWorkspace.groupModeStr, sizeof(g_initWorkspace.groupModeStr));if (ret ! 0) {INIT_LOGV(Failed to get boot group);if (GetBootModeFromMisc() GROUP_CHARGE) {strcpy_s(g_initWorkspace.groupModeStr, sizeof(g_initWorkspace.groupModeStr), device.charge.group);}}INIT_LOGI(boot start %s, g_initWorkspace.groupModeStr);//device.boot.group 系统默认配置触发执行配置文件中的所有的job和服务。//device.charge.group charge模式限制只启动改文件中允许的job和服务。g_initWorkspace.groupMode GetBootGroupMode();g_initWorkspace.initFlags 1; } . . . int InitParseGroupCfg(void) {char buffer[128] {0}; // 128 buffer size// /data/init_ut/system/etcchar *realPath GetAbsolutePath(GROUP_DEFAULT_PATH,g_initWorkspace.groupModeStr, buffer, sizeof(buffer));INIT_ERROR_CHECK(realPath ! NULL, return -1,Failed to get path for %s, g_initWorkspace.groupModeStr);InitParseGroupCfg_(realPath);InitGroupNode *groupRoot g_initWorkspace.groupNodes[NODE_TYPE_GROUPS];int level 0;while ((groupRoot ! NULL) (level GROUP_IMPORT_MAX_LEVEL)) { // for more importg_initWorkspace.groupNodes[NODE_TYPE_GROUPS] NULL;InitImportGroupCfg_(groupRoot);groupRoot g_initWorkspace.groupNodes[NODE_TYPE_GROUPS];level;}InitFreeGroupNodes_(g_initWorkspace.groupNodes[NODE_TYPE_GROUPS]);g_initWorkspace.groupNodes[NODE_TYPE_GROUPS] NULL;return 0; }LoadSpecialParam base\startup\init\services\param\linux\param_service.c void LoadSpecialParam(void) {// read param area size from cfg and save to dacLoadParamAreaSize();// read selinux labelLoadSelinuxLabel(init);// from cmdlineLoadParamFromCmdLine();// from buildLoadParamFromBuild(); }base\startup\init\services\param\manager\param_server.c INIT_LOCAL_API void LoadParamAreaSize(void) {LoadDefaultParam_(/sys_prod/etc/param/ohos.para.size, 0, NULL, 0, LoadOneParamAreaSize_);LoadDefaultParam_(PARAM_AREA_SIZE_CFG, 0, NULL, 0, LoadOneParamAreaSize_); } . . . INIT_LOCAL_API void LoadParamFromBuild(void) {PARAM_LOGI(load parameters from build ); #ifdef INCREMENTAL_VERSIONif (strlen(INCREMENTAL_VERSION) 0) {WriteParam(const.product.incremental.version, INCREMENTAL_VERSION, NULL, LOAD_PARAM_NORMAL);} #endif #ifdef BUILD_TYPEif (strlen(BUILD_TYPE) 0) {WriteParam(const.product.build.type, BUILD_TYPE, NULL, LOAD_PARAM_NORMAL);} #endif #ifdef BUILD_USERif (strlen(BUILD_USER) 0) {WriteParam(const.product.build.user, BUILD_USER, NULL, LOAD_PARAM_NORMAL);} #endif #ifdef BUILD_TIMEif (strlen(BUILD_TIME) 0) {WriteParam(const.product.build.date, BUILD_TIME, NULL, LOAD_PARAM_NORMAL);} #endif #ifdef BUILD_HOSTif (strlen(BUILD_HOST) 0) {WriteParam(const.product.build.host, BUILD_HOST, NULL, LOAD_PARAM_NORMAL);} #endif #ifdef BUILD_ROOTHASHif (strlen(BUILD_ROOTHASH) 0) {WriteParam(const.ohos.buildroothash, BUILD_ROOTHASH, NULL, LOAD_PARAM_NORMAL);} #endif }ReadConfig base\startup\init\services\init\init_config.c void ReadConfig(void) {// parse cfgchar buffer[32] {0}; // 32 reason max lebuint32_t len sizeof(buffer);//读取启动模式根据不同模式解析对应的cfg文件SystemReadParam(ohos.boot.mode, buffer, len);INIT_LOGI(ohos.boot.mode %s, buffer);if (strcmp(buffer, charger_mode) 0) {ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);ReadFileInDir(OTHER_CHARGE_PATH, .cfg, ParseInitCfg, NULL);ParseInitCfgByPriority();} else if (strcmp(buffer, charger) 0) {ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);ReadFileInDir(OTHER_CHARGE_PATH, .cfg, ParseInitCfg, NULL);} else if (InUpdaterMode() 0) {ParseInitCfg(INIT_CONFIGURATION_FILE, NULL);ParseInitCfgByPriority();} else {ReadFileInDir(/etc, .cfg, ParseInitCfg, NULL);} } static void ParseInitCfgContents(const char *cfgName, const cJSON *root) {INIT_ERROR_CHECK(root ! NULL, return, Root is null);ConfigContext context { INIT_CONTEXT_MAIN };context.type GetConfigContextType(cfgName);INIT_LOGV(Parse %s configs in context %d, cfgName, context.type);// 解析cfg文件中的servicesParseAllServices(root, context);// 解析cfg文件中的jobsParseAllJobs(root, context);// parse imports//解析所有导入cfg文件ParseAllImports(root); }int ParseInitCfg(const char *configFile, void *context) {UNUSED(context);INIT_LOGV(Parse init configs from %s, configFile);char *fileBuf ReadFileToBuf(configFile);INIT_ERROR_CHECK(fileBuf ! NULL, return -1, Cfg error, %s not found, configFile);cJSON *fileRoot cJSON_Parse(fileBuf);INIT_ERROR_CHECK(fileRoot ! NULL, free(fileBuf);return -1, Cfg error, failed to parse json %s , configFile);ParseInitCfgContents(configFile, fileRoot);cJSON_Delete(fileRoot);free(fileBuf);return 0; }SystemRun base\startup\init\services\init\standard\init.c void SystemRun(void) {StartParamService(); }base\startup\init\services\param\linux\param_service.c int StartParamService(void) {// read selinux labelLoadSelinuxLabel(permission);return ParamServiceStart(); }base\startup\init\services\param\linux\param_msgadp.c int ParamServiceStart(void) {LE_RunLoop(LE_GetDefaultLoop());return 0; }samgr系统服务进程 samgr是各个SystemAbility的服务进程中心每个SA的启动都需要向samgr注册然后分配到一个ID通过ID才能访问到该SA。 samgr由init进程启动,由之前的SystemConfig函数可知,执行post-init的时候会触发early-fs此时执行samgr的job。samgr服务配置的模式为boot则会在init阶段启动 void SystemConfig(const char *uptime) {.....// execute initPostTrigger(EVENT_TRIGGER_BOOT, pre-init, strlen(pre-init));PostTrigger(EVENT_TRIGGER_BOOT, init, strlen(init));TriggerServices(START_MODE_BOOT);PostTrigger(EVENT_TRIGGER_BOOT, post-init, strlen(post-init));TriggerServices(START_MODE_NORMAL);clock_gettime(CLOCK_MONOTONIC, (g_bootJob.startTime)); }base\startup\init\services\etc\init.cfg {name : post-init,cmds : [trigger early-fs,trigger fs,trigger post-fs,trigger late-fs,trigger post-fs-data,trigger firmware_mounts_complete,trigger early-boot,trigger boot] }samgr的cfg文件如下。服务介绍详见服务管理.md foundation\systemabilitymgr\samgr\etc\samgr_standard.cfg {jobs : [{name : early-fs,cmds : [mkdir /data/samgr 0740 samgr samgr]}],services : [{name : samgr,path : [/system/bin/samgr],critical : [1, 1, 60],uid : samgr,gid : [samgr, readproc],bootevents:bootevent.samgr.ready,permission: [ohos.permission.DISTRIBUTED_DATASYNC,ohos.permission.ACCESS_SERVICE_DM,ohos.permission.RECEIVER_STARTUP_COMPLETED,ohos.permission.MANAGE_LOCAL_ACCOUNTS,ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS,ohos.permission.LOCATION,ohos.permission.GET_WIFI_INFO,ohos.permission.USE_BLUETOOTH,ohos.permission.DISCOVER_BLUETOOTH,ohos.permission.MANAGE_SECURE_SETTINGS,ohos.permission.LISTEN_BUNDLE_CHANGE,ohos.permission.STORAGE_MANAGER,ohos.permission.RECEIVE_SMS,ohos.permission.GET_TELEPHONY_STATE,ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT],secon : u:r:samgr:s0,start-mode : boot //启动模式}] }foundation进程 ams,wms等服务都在foundation进程中。 foundation是一个特殊的SA服务进程提供用户程序管理框架及基础服务该进程负责应用的生命周期管理ready可进行startAbility/connectAbility。当多个服务都完成对应的启动事件后由bootevents投票在init进程中设置bootevent.boot.completed事件为true表示系统启动完成。 在foundation监控到此事件再以CES事件的方式广播出去让应用能够检测到。foundation服务进程想应用孵化器appspawn发送应用启动请求。appspawn接收到应用启动请求直接孵化出应用进程。当foundation启动Openharmony应用Home即我们看到的桌面程序至此从开机到应用启动所有过程就完成了。 foundation在post-init阶段启动 foundation\systemabilitymgr\safwk\etc\profile\foundation.cfg services : [{name : foundation,path : [/system/bin/sa_main, /system/profile/foundation.json],critical : [1, 4, 240],importance : -20,uid : foundation,permission : [ohos.permission.INPUT_MONITORING,ohos.permission.PERMISSION_USED_STATS,ohos.permission.DISTRIBUTED_SOFTBUS_CENTER,ohos.permission.DISTRIBUTED_DATASYNC,ohos.permission.MANAGE_AUDIO_CONFIG,ohos.permission.WRITE_CALL_LOG,ohos.permission.READ_CONTACTS,ohos.permission.READ_DFX_SYSEVENT,ohos.permission.GRANT_SENSITIVE_PERMISSIONS,ohos.permission.REVOKE_SENSITIVE_PERMISSIONS,ohos.permission.MANAGE_SECURE_SETTINGS,ohos.permission.START_ABILITIES_FROM_BACKGROUND,ohos.permission.ACCESS_SERVICE_DM,ohos.permission.STORAGE_MANAGER,ohos.permission.PROXY_AUTHORIZATION_URI,ohos.permission.ABILITY_BACKGROUND_COMMUNICATION,ohos.permission.USE_USER_IDM,ohos.permission.MANAGE_LOCAL_ACCOUNTS,ohos.permission.LISTEN_BUNDLE_CHANGE,ohos.permission.GET_TELEPHONY_STATE,ohos.permission.SEND_MESSAGES,ohos.permission.CONNECT_CELLULAR_CALL_SERVICE,ohos.permission.SET_TELEPHONY_STATE,ohos.permission.VIBRATE,ohos.permission.SYSTEM_LIGHT_CONTROL,ohos.permission.MANAGE_HAP_TOKENID,ohos.permission.WRITE_WHOLE_CALENDAR,ohos.permission.UPDATE_CONFIGURATION,ohos.permission.REPORT_RESOURCE_SCHEDULE_EVENT,ohos.permission.START_INVISIBLE_ABILITY,ohos.permission.GET_BUNDLE_INFO,ohos.permission.GET_SUSPEND_STATE,ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT,ohos.permission.GET_BUNDLE_INFO_PRIVILEGED,ohos.permission.GET_SENSITIVE_PERMISSIONS,ohos.permission.CLEAN_APPLICATION_DATA,ohos.permission.REMOVE_CACHE_FILES,ohos.permission.INSTALL_SANDBOX_BUNDLE,ohos.permission.USE_BLUETOOTH,ohos.permission.CONNECTIVITY_INTERNAL,ohos.permission.GET_RUNNING_INFO,ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS,ohos.permission.ACCESS_BLUETOOTH,ohos.permission.RUNNING_STATE_OBSERVER],permission_acls:[ohos.permission.MANAGE_HAP_TOKENID,ohos.permission.GRANT_SENSITIVE_PERMISSIONS,ohos.permission.INPUT_MONITORING,ohos.permission.REVOKE_SENSITIVE_PERMISSIONS,ohos.permission.START_INVISIBLE_ABILITY,ohos.permission.INSTALL_SANDBOX_BUNDLE],gid : [system, appspawn, update],caps : [SYS_PTRACE, KILL],bootevents: [bootevent.wms.fullscreen.ready,bootevent.appfwk.ready,bootevent.lockscreen.ready],jobs : {on-start : services:foundation,on-restart : services:restartfoundation},secon : u:r:foundation:s0}]系统服务框架组件SystemAbility(具体详见: 系统服务框架部件.md) SystemAbility实现一般采用XXX.cfg profile.json libXXX.z.so的方式由init进程执行对应的XXX.cfg文件拉起相关SystemAbility进程。 AbilityManagerService的启动 由系统服务框架部件.md可知的服务配置需要对应.json文件和BUILD.gn文件以及cfg文件。 对应的ams的json和BUILD.gn文件如下 foundation\ability\ability_runtime\services\sa_profile\180.json foundation\ability\ability_runtime\services\sa_profile\BUILD.gn {process: foundation,systemability: [{name: 180,libpath: libabilityms.z.so,run-on-create: true,distributed: false,dump_level: 1}] }import(//build/ohos/sa_profile/sa_profile.gni)ohos_sa_profile(ams_sa_profile) {sources [180.json,182.json,183.json,184.json,501.json,]part_name ability_runtime }由于ams跑在foundation进程中所以对应的文件查看foundation.cfg 所以查看对应的/system/bin/sa_main的流程找到对应的main函数 foundation\systemabilitymgr\safwk\services\safwk\src\main.cpp int main(int argc, char *argv[]) {HILOGD(TAG, [PerformanceTest] SAFWK main entry process starting!);// find update list//检测服务cfg文件中是否配置按需启动ondemandbool checkOnDemand true;string updateList;for (int i 0; i argc - 1; i) {if (PARAM_PREFIX_U.compare(argv[i]) 0) {if (i EVENT_INDEX) {checkOnDemand false;}updateList argv[i 1];break;}}if (!updateList.empty()) {LocalAbilityManager::GetInstance().SetUpdateList(updateList);}// Load ondemand system abilities related shared libraries from specific json-format profile// when this process starts.//从.json配置文件加载与ondemand系统功能相关的共享库如ams配置的180.json中加载libabilityms.z.so int32_t saId DEFAULT_SAID;if (checkOnDemand argc ONDEMAND_LOAD) {nlohmann::json eventMap;saId ParseArgv(argv, eventMap);if (!CheckSaId(saId)) {HILOGE(TAG, saId is invalid!);return 0;}LocalAbilityManager::GetInstance().SetStartReason(saId, eventMap);}//启动服务进程DoStartSAProcess(argc, argv, saId);return 0; }....static int DoStartSAProcess(int argc, char *argv[], int32_t saId) {auto setProcessName [argc, argv](const string name) - void {char *endCh strchr(argv[argc - 1], 0);if (endCh nullptr) {HILOGW(TAG, argv is invalid);return;}uintptr_t start reinterpret_castuintptr_t(argv[0]);uintptr_t end reinterpret_castuintptr_t(endCh);uintptr_t argvSize end - start;if (memset_s(argv[0], argvSize, 0, argvSize) ! EOK) {HILOGW(TAG, failed to clear argv:%{public}s, strerror(errno));return;}if (strcpy_s(argv[0], argvSize, name.c_str()) ! EOK) {HILOGW(TAG, failed to set process name:%{public}s, strerror(errno));return;}HILOGI(TAG, Set process name to %{public}s, argv[0]);};// Load default system abilities related shared libraries from specific format profile// when this process starts.string profilePath(DEFAULT_JSON);if (argc DEFAULT_LOAD) {string filePath(argv[PROFILE_INDEX]);//寻找对应的json文件if (filePath.empty() || filePath.find(.json) string::npos) {HILOGE(TAG, profile file path is invalid!);return 0;}SetProcName(filePath, setProcessName);profilePath std::move(filePath);}LocalAbilityManager::GetInstance().DoStartSAProcess(profilePath, saId);return 0; }foundation\systemabilitymgr\safwk\services\safwk\src\local_ability_manager.cpp void LocalAbilityManager::DoStartSAProcess(const std::string profilePath, int32_t saId) {startBegin_ GetTickCount();HILOGD(TAG, SA:%{public}d, saId);string realProfilePath ;//检测文件路径是否正确if (!CheckAndGetProfilePath(profilePath, realProfilePath)) {HILOGE(TAG, DoStartSAProcess invalid path);return;}{std::string traceTag GetTraceTag(realProfilePath);HITRACE_METER_NAME(HITRACE_TAG_SAMGR, traceTag);//初始化sa profilesbool ret InitSystemAbilityProfiles(realProfilePath, saId);if (!ret) {HILOGE(TAG, InitSystemAbilityProfiles no right profile, will exit);return;}//等待samg的启动ret CheckSystemAbilityManagerReady();if (!ret) {HILOGE(TAG, CheckSystemAbilityManagerReady failed! will exit);return;}//启动SAret Run(saId);if (!ret) {HILOGE(TAG, Run failed! will exit);return;}}IPCSkeleton::JoinWorkThread();ClearResource();HILOGE(TAG, JoinWorkThread stop, will exit); }.....bool LocalAbilityManager::CheckAndGetProfilePath(const std::string profilePath, std::string realProfilePath) {if (profilePath.length() PATH_MAX) {HILOGE(TAG, profilePath length too long!);return false;}char realPath[PATH_MAX] {\0};if (realpath(profilePath.c_str(), realPath) nullptr) {HILOGE(TAG, file path does not exist!);return false;}// realProfilePath must begin with /system/profile/ or begin with /system/usr/realProfilePath realPath;if (realProfilePath.find(PROFILES_DIR) ! 0 realProfilePath.find(DEFAULT_DIR) ! 0) {HILOGE(TAG, file path is not matched);return false;}return true; }.....bool LocalAbilityManager::InitSystemAbilityProfiles(const std::string profilePath, int32_t saId) {HILOGD(TAG, [PerformanceTest]parse sa profiles!);int64_t begin GetTickCount();//解析profilebool ret profileParser_-ParseSaProfiles(profilePath);if (!ret) {HILOGW(TAG, ParseSaProfiles failed!);return false;}procName_ profileParser_-GetProcessName();auto saInfos profileParser_-GetAllSaProfiles();std::string process Str16ToStr8(procName_);HILOGI(TAG, [PerformanceTest]parse process:%{public}s profiles finished, spend:%{public}PRId64 ms, process.c_str(), (GetTickCount() - begin));std::string path PREFIX process SUFFIX;bool isExist profileParser_-CheckPathExist(path);if (isExist) {CheckTrustSa(path, process, saInfos);}return InitializeSaProfiles(saId); }bool LocalAbilityManager::InitializeSaProfiles(int32_t saId) {if (saId ! DEFAULT_SAID) {return InitializeOnDemandSaProfile(saId);} else {return InitializeRunOnCreateSaProfiles(BOOT_START);} }void LocalAbilityManager::CheckTrustSa(const std::string path, const std::string process,const std::listSaProfile saInfos) {HILOGD(TAG, CheckTrustSa start);std::mapstd::u16string, std::setint32_t trustMaps;//解析trust sa profiles,并移除不受信任的sa//foundation进程受信任profile配置在如下文件中://foundation\systemabilitymgr\safwk\etc\profile\foundation_trust.jsonbool ret profileParser_-ParseTrustConfig(path, trustMaps);if (ret !trustMaps.empty()) {// 1.get allowed sa set in the processconst auto saSets trustMaps[Str8ToStr16(process)];// 2.check to-load sa in the allowed sa set, and if to-load sa not in the allowed, will remove and not load itfor (const auto saInfo : saInfos) {if (saSets.find(saInfo.saId) saSets.end()) {HILOGW(TAG, SA:%{public}d not allow to load in %{public}s, saInfo.saId, process.c_str());profileParser_-RemoveSaProfile(saInfo.saId);}}} }.....bool LocalAbilityManager::CheckSystemAbilityManagerReady() {int32_t timeout RETRY_TIMES_FOR_SAMGR;constexpr int32_t duration std::chrono::microseconds(MILLISECONDS_WAITING_SAMGR_ONE_TIME).count();sptrISystemAbilityManager samgrProxy SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();//循环检测samg是否初始化完成while (samgrProxy nullptr) {HILOGI(TAG, %{public}s waiting for samgr..., Str16ToStr8(procName_).c_str());if (timeout 0) {usleep(duration);samgrProxy SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();} else {HILOGE(TAG, wait for samgr time out (10s));return false;}timeout--;}return true; }.....bool LocalAbilityManager::InitializeRunOnCreateSaProfiles(uint32_t bootPhase) {/*bootphase可不设置可以设置的值有三种BootStartPhase、CoreStartPhase、OtherStartPhase默认类型三种优先级依次降低当同一个进程中会优先拉起注册配置BootStartPhase的SystemAbility然后是配置了CoreStartPhase的SystemAbility最后是OtherStartPhase当高优先级的SystemAbility全部启动注册完毕才会启动下一级的SystemAbility的注册启动。*/if (bootPhase OTHER_START) {return false;}int64_t begin GetTickCount();HILOGD(TAG, [PerformanceTest]load phase %{public}d libraries, bootPhase);//dlopen各sa所在的so库profileParser_-OpenSo(bootPhase);HILOGI(TAG, [PerformanceTest]load process:%{public}s phase %{public}d finished, spend:%{public} PRId64 ms,Str16ToStr8(procName_).c_str(), bootPhase, (GetTickCount() - begin));auto saProfileList profileParser_-GetAllSaProfiles();if (saProfileList.empty()) {HILOGW(TAG, sa profile is empty);return false;}for (const auto saProfile : saProfileList) {if (saProfile.bootPhase ! bootPhase) {continue;}//将sa对象注册到abilityPhaseMap_中if (!InitializeSaProfilesInnerLocked(saProfile)) {HILOGW(TAG, SA:%{public}d init fail, saProfile.saId);continue;}}return true; }bool LocalAbilityManager::InitializeSaProfilesInnerLocked(const SaProfile saProfile) {std::unique_lockstd::shared_mutex readLock(abilityMapLock_);auto iterProfile abilityMap_.find(saProfile.saId);if (iterProfile abilityMap_.end()) {HILOGW(TAG, SA:%{public}d not found, saProfile.saId);return false;}auto systemAbility iterProfile-second;if (systemAbility nullptr) {HILOGW(TAG, SA:%{public}d is null, saProfile.saId);return false;}auto saList abilityPhaseMap_[saProfile.bootPhase];saList.emplace_back(systemAbility);return true; }......bool LocalAbilityManager::Run(int32_t saId) {HILOGD(TAG, local ability manager is running...);bool addResult AddLocalAbilityManager();if (!addResult) {HILOGE(TAG, failed to add local abilitymanager);return false;}HILOGD(TAG, success to add process name:%{public}s, Str16ToStr8(procName_).c_str());//获取系统支持的并发线程数uint32_t concurrentThreads std::thread::hardware_concurrency();HILOGI(TAG, concurrentThreads is %{public}d, process:%{public}s, SA:%{public}d,concurrentThreads, Str16ToStr8(procName_).c_str(), saId);//通过线程池启动线程可以通过增加线程数优化sa启动时间initPool_-Start(concurrentThreads);initPool_-SetMaxTaskNum(MAX_TASK_NUMBER);//对应ondemand类型的sa的信息添加到samgrRegisterOnDemandSystemAbility(saId);//遍历sa,调用对应sa的start()函数FindAndStartPhaseTasks(saId);initPool_-Stop();return true; }bool LocalAbilityManager::AddLocalAbilityManager() {auto samgrProxy SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();if (samgrProxy nullptr) {HILOGE(TAG, failed to get samgrProxy);return false;}if (localAbilityManager_ nullptr) {localAbilityManager_ this;}//通过 IPC 调用 samgr 服务的 AddSystemProcess()方法将服务进程本质上是一个绑定了服务相关信息的 lsamgr 实例注册到 samgr然后启动服务进程int32_t ret samgrProxy-AddSystemProcess(procName_, localAbilityManager_);return ret ERR_OK; }......void LocalAbilityManager::RegisterOnDemandSystemAbility(int32_t saId) {auto samgrProxy SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();if (samgrProxy nullptr) {HILOGI(TAG, failed to get samgrProxy);return;}auto saProfileList profileParser_-GetAllSaProfiles();for (const auto saProfile : saProfileList) {if (NeedRegisterOnDemand(saProfile, saId)) {HILOGD(TAG, register ondemand SA:%{public}d to samgr, saProfile.saId);//SA 对应的系统进程启动之后便需要加载启动 SA 自身。首先samgr 调用 AddOnDemandSystemAbilityInfo()将对应的 SA 实例与服务进程进行绑定并准备启动对应的 SA//将对应ondemand类型的sa的信息添加到samgrint32_t ret samgrProxy-AddOnDemandSystemAbilityInfo(saProfile.saId, procName_);if (ret ! ERR_OK) {HILOGI(TAG, failed to add ability info for on-demand SA:%{public}d, saProfile.saId);}}} }.....void LocalAbilityManager::FindAndStartPhaseTasks(int32_t saId) {if (saId DEFAULT_SAID) {for (uint32_t bootPhase BOOT_START; bootPhase OTHER_START; bootPhase) {auto iter abilityPhaseMap_.find(bootPhase);if (iter ! abilityPhaseMap_.end()) {StartPhaseTasks(iter-second);InitializeRunOnCreateSaProfiles(bootPhase 1);WaitForTasks();} else {InitializeRunOnCreateSaProfiles(bootPhase 1);}}} else {for (uint32_t bootPhase BOOT_START; bootPhase OTHER_START; bootPhase) {auto iter abilityPhaseMap_.find(bootPhase);if (iter ! abilityPhaseMap_.end()) {StartPhaseTasks(iter-second);WaitForTasks();}}} }//启动sa void LocalAbilityManager::StartPhaseTasks(const std::listSystemAbility* systemAbilityList) {if (systemAbilityList.empty()) {return;}for (auto systemAbility : systemAbilityList) {if (systemAbility ! nullptr) {HILOGD(TAG, add phase task for SA:%{public}d, systemAbility-GetSystemAbilitId());std::lock_guardstd::mutex autoLock(startPhaseLock_);startTaskNum_;auto task std::bind(LocalAbilityManager::StartSystemAbilityTask, this, systemAbility);initPool_-AddTask(task);}} }void LocalAbilityManager::StartSystemAbilityTask(SystemAbility* ability) {if (ability ! nullptr) {HILOGD(TAG, StartSystemAbility is called for SA:%{public}d, ability-GetSystemAbilitId());if (ability-GetDependSa().empty()) {//调用SystemAbility::Start()ability-Start();} else {StartDependSaTask(ability);}HILOGI(TAG, %{public}s SA:%{public}d init finished, %{public} PRId64 ms,Str16ToStr8(procName_).c_str(), ability-GetSystemAbilitId(), (GetTickCount() - startBegin_));}std::lock_guardstd::mutex lock(startPhaseLock_);if (startTaskNum_ 0) {--startTaskNum_;}startPhaseCV_.notify_one(); }foundation\systemabilitymgr\safwk\services\safwk\src\system_ability.cpp //在 Start()方法中会触发钩子函数 OnStart()的调用OnStart()通常由 SA 自己实现用来完成其的初始化工作并调用 Publish()发布 SA。 最后 Publish()方法会调用 samgr 的 AddSystemAbility()方法将 SA 注册到 samgr 中void SystemAbility::Start() {// Ensure that the lifecycle is sequentially called by SAMGRHILOGD(TAG, starting system ability...);{std::lock_guardstd::recursive_mutex autoLock(abilityLock);if (abilityState_ ! SystemAbilityState::NOT_LOADED) {return;}}HILOGD(TAG, [PerformanceTest]OnStart SA:%{public}d, saId_);int64_t begin GetTickCount();HITRACE_METER_NAME(HITRACE_TAG_SAMGR, ToString(saId_) _OnStart);nlohmann::json startReason LocalAbilityManager::GetInstance().GetStartReason(saId_);SystemAbilityOnDemandReason onDemandStartReason LocalAbilityManager::GetInstance().JsonToOnDemandReason(startReason);GetOnDemandReasonExtraData(onDemandStartReason);OnStart(onDemandStartReason);std::lock_guardstd::recursive_mutex autoLock(abilityLock);isRunning_ true;HILOGI(TAG, [PerformanceTest]OnStart SA:%{public}d finished, spend:%{public} PRId64 ms,saId_, (GetTickCount() - begin)); }// The details should be implemented by subclass void SystemAbility::OnStart() { }// The details should be implemented by subclass void SystemAbility::OnStart(const SystemAbilityOnDemandReason startReason) {OnStart(); }// The details should be implemented by subclass void SystemAbility::OnAddSystemAbility(int32_t systemAbilityId, const std::string deviceId) { }......bool SystemAbility::Publish(sptrIRemoteObject systemAbility) {if (systemAbility nullptr) {HILOGE(TAG, systemAbility is nullptr);return false;}HILOGD(TAG, [PerformanceTest]Publish SA:%{public}d, saId_);// Avoid automatic destruction of system ability caused by failure of publishing abilitypublishObj_ systemAbility;int64_t begin GetTickCount();sptrISystemAbilityManager samgrProxy SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();if (samgrProxy nullptr) {HILOGE(TAG, failed to get samgrProxy);return false;}ISystemAbilityManager::SAExtraProp saExtra(GetDistributed(), GetDumpLevel(), capability_, permission_);std::lock_guardstd::recursive_mutex autoLock(abilityLock);//调用 samgr 的 AddSystemAbility()方法将 SA 注册到 samgr 中int32_t result samgrProxy-AddSystemAbility(saId_, publishObj_, saExtra);HILOGI(TAG, [PerformanceTest]Publish SA:%{public}d result:%{public}d, spend:%{public} PRId64 ms,saId_, result, (GetTickCount() - begin));if (result ERR_OK) {abilityState_ SystemAbilityState::ACTIVE;return true;}return false; }foundation\ability\ability_runtime\services\abilitymgr\src\ability_manager_service.cpp //服务启动完成可以对外提供服务 void AbilityManagerService::OnStart() {if (state_ ServiceRunningState::STATE_RUNNING) {HILOG_INFO(AMS has already started.);return;}HILOG_INFO(AMS starting.);if (!Init()) {HILOG_ERROR(Failed to init AMS.);return;}state_ ServiceRunningState::STATE_RUNNING;/* Publish service maybe failed, so we need call this function at the last,* so it cant affect the TDD test program */instance_ DelayedSingletonAbilityManagerService::GetInstance().get();if (instance_ nullptr) {HILOG_ERROR(AMS enter OnStart, but instance_ is nullptr!);return;}bool ret Publish(instance_);if (!ret) {HILOG_ERROR(Publish AMS failed!);return;}//投票SetParameter(BOOTEVENT_APPFWK_READY.c_str(), true);AddSystemAbilityListener(BACKGROUND_TASK_MANAGER_SERVICE_ID);AddSystemAbilityListener(DISTRIBUTED_SCHED_SA_ID);AddSystemAbilityListener(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);HILOG_INFO(AMS start success.); }account进程 account在post-init阶段启动 base\account\os_account\services\accountmgr\accountmgr.cfg services : [{name : accountmgr,path : [/system/bin/sa_main, /system/profile/accountmgr.json],permission : [ohos.permission.GET_BUNDLE_INFO_PRIVILEGED,ohos.permission.GET_RUNNING_INFO,ohos.permission.ENFORCE_USER_IDM,ohos.permission.USE_USER_IDM,ohos.permission.MANAGE_USER_IDM,ohos.permission.ACCESS_USER_AUTH_INTERNAL,ohos.permission.ACCESS_PIN_AUTH,ohos.permission.STORAGE_MANAGER,ohos.permission.securityguard.REPORT_SECURITY_INFO,ohos.permission.DISTRIBUTED_DATASYNC,ohos.permission.RUNNING_STATE_OBSERVER,ohos.permission.PUBLISH_SYSTEM_COMMON_EVENT,ohos.permission.STORAGE_MANAGER_CRYPT],permission_acls : [ohos.permission.ENFORCE_USER_IDM,ohos.permission.STORAGE_MANAGER_CRYPT],uid : account,gid : [account, shell, access_token],bootevents : [ bootevent.account.ready ],writepid : [/dev/cpuset/foreground/tasks,/dev/stune/foreground/tasks,/dev/blkio/foreground/tasks],jobs : {on-start : services:accountmgr},secon : u:r:accountmgr:s0}]base\account\os_account\services\accountmgr\src\account_mgr_service.cpp //服务启动 void AccountMgrService::OnStart() {if (state_ ServiceRunningState::STATE_RUNNING) {ACCOUNT_LOGI(AccountMgrService has already started.);return;}UpdateTraceLabelAdapter();StartTraceAdapter(accountmgr service onstart);CountTraceAdapter(activeid, -1);PerfStat::GetInstance().SetInstanceStartTime(GetTickCount());ACCOUNT_LOGI(start is triggered);if (!Init()) {ACCOUNT_LOGE(failed to init AccountMgrService);FinishTraceAdapter();return;}bool isAccountCompleted false;std::int32_t defaultActivatedId Constants::START_USER_ID;osAccountManagerService_-GetDefaultActivatedOsAccount(defaultActivatedId);osAccountManagerService_-IsOsAccountCompleted(defaultActivatedId, isAccountCompleted);if (!isAccountCompleted) {AddSystemAbilityListener(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);}AddSystemAbilityListener(STORAGE_MANAGER_MANAGER_ID);AddSystemAbilityListener(ABILITY_MGR_SERVICE_ID);ACCOUNT_LOGI(AccountMgrService::OnStart start service finished.);FinishTraceAdapter();IPCSkeleton::SetMaxWorkThreadNum(5); // 5: ipc thread num }void AccountMgrService::OnStop() {PerfStat::GetInstance().SetInstanceStopTime(GetTickCount());ACCOUNT_LOGI(onstop is called);IAccountContext::SetInstance(nullptr);SelfClean(); }//addSystemAbility回调 void AccountMgrService::OnAddSystemAbility(int32_t systemAbilityId, const std::string deviceId) {ACCOUNT_LOGI(OnAddSystemAbility systemAbilityId %{public}d, systemAbilityId);std::lock_guardstd::mutex lock(statusMutex_);switch (systemAbilityId) {case STORAGE_MANAGER_MANAGER_ID: {isStorageReady_ true;break;}case ABILITY_MGR_SERVICE_ID: {isAmsReady_ true;break;}case BUNDLE_MGR_SERVICE_SYS_ABILITY_ID: {isBmsReady_ true;break;}default:break;}if (!isStorageReady_) {return;}bool isAccountCompleted false;std::int32_t defaultActivatedId Constants::START_USER_ID;osAccountManagerService_-GetDefaultActivatedOsAccount(defaultActivatedId);osAccountManagerService_-IsOsAccountCompleted(defaultActivatedId, isAccountCompleted);if (!isAccountCompleted !isBmsReady_) {return;}if (isAccountCompleted !isAmsReady_) {return;}//创建基础账户osAccountManagerService_-CreateBasicAccounts(); }base\account\os_account\services\accountmgr\src\osaccount\os_account_manager_service.cpp void OsAccountManagerService::CreateBasicAccounts() {ACCOUNT_LOGI(enter!);//初始化innerManager_.Init();ACCOUNT_LOGI(exit!); }base\account\os_account\services\accountmgr\src\osaccount\inner_os_account_manager.cpp void IInnerOsAccountManager::Init() {CreateBaseAdminAccount();CreateBaseStandardAccount();//启动账户StartAccount(); #ifdef ENABLE_MULTIPLE_ACTIVE_ACCOUNTSRestartActiveAccount(); #endif // ENABLE_MULTIPLE_ACTIVE_ACCOUNTSCleanGarbageAccounts(); }......void IInnerOsAccountManager::StartAccount() {ACCOUNT_LOGI(start to activate default account);ResetAccountStatus();OsAccountInfo osAccountInfo;ErrCode errCode osAccountControl_-GetOsAccountInfoById(defaultActivatedId_, osAccountInfo);if (errCode ! ERR_OK) {ACCOUNT_LOGE(account not found, localId: %{public}d, error: %{public}d, defaultActivatedId_, errCode);RetryToGetAccount(osAccountInfo);defaultActivatedId_ osAccountInfo.GetLocalId();osAccountControl_-SetDefaultActivatedOsAccount(defaultActivatedId_);}auto task std::bind(IInnerOsAccountManager::WatchStartUser, this, defaultActivatedId_);std::thread taskThread(task);pthread_setname_np(taskThread.native_handle(), WATCH_START_USER);taskThread.detach();if (!osAccountInfo.GetIsCreateCompleted() (SendMsgForAccountCreate(osAccountInfo) ! ERR_OK)) {ACCOUNT_LOGE(account %{public}d not created completely, defaultActivatedId_);return;}// activate//传输账号信息SendMsgForAccountActivate(osAccountInfo); }.....ErrCode IInnerOsAccountManager::SendMsgForAccountActivate(OsAccountInfo osAccountInfo) {// activateint localId osAccountInfo.GetLocalId();ErrCode errCode OsAccountInterface::SendToStorageAccountStart(osAccountInfo);if (errCode ! ERR_OK) {ACCOUNT_LOGE(account %{public}d call storage active failed, errCode %{public}d.,localId, errCode);return ERR_ACCOUNT_COMMON_GET_SYSTEM_ABILITY_MANAGER;}//通知ams账号启动errCode OsAccountInterface::SendToAMSAccountStart(osAccountInfo);if (errCode ! ERR_OK) {ACCOUNT_LOGE(account %{public}d call ams active failed, errCode %{public}d.,localId, errCode);return errCode;}// update infoosAccountInfo.SetIsActived(true);int64_t time std::chrono::duration_caststd::chrono::seconds(std::chrono::system_clock::now().time_since_epoch()).count();osAccountInfo.SetLastLoginTime(time);errCode osAccountControl_-UpdateOsAccount(osAccountInfo);if (errCode ! ERR_OK) {ACCOUNT_LOGE(update %{public}d account info failed, errCode %{public}d.,localId, errCode);return ERR_OSACCOUNT_SERVICE_INNER_UPDATE_ACCOUNT_ERROR;}RefreshActiveList(localId);//投票SetParameter(ACCOUNT_READY_EVENT.c_str(), true);OsAccountInterface::SendToCESAccountSwitched(osAccountInfo);subscribeManager_.Publish(localId, OS_ACCOUNT_SUBSCRIBE_TYPE::ACTIVED);ACCOUNT_LOGI(SendMsgForAccountActivate ok);return errCode; }base\account\os_account\services\accountmgr\src\osaccount\os_account_interface.cpp ErrCode OsAccountInterface::SendToAMSAccountStart(OsAccountInfo osAccountInfo) {ACCOUNT_LOGI(start);StartTraceAdapter(AbilityManagerAdapter StartUser);ErrCode code AbilityManagerAdapter::GetInstance()-StartUser(osAccountInfo.GetLocalId());if (code ! ERR_OK) {ACCOUNT_LOGE(AbilityManagerAdapter StartUser failed! errcode is %{public}d, code);ReportOsAccountOperationFail(osAccountInfo.GetLocalId(), Constants::OPERATION_ACTIVATE, code,AbilityManagerAdapter StartUser failed!);FinishTraceAdapter();return code;}ACCOUNT_LOGI(end, succeed!);FinishTraceAdapter();return ERR_OK; }base\account\os_account\services\accountmgr\src\ability_manager_adapter\ability_manager_adapter.cpp ErrCode AbilityManagerAdapter::StartUser(int32_t accountId) {auto abms GetAbilityManager();if (abms nullptr) {ACCOUNT_LOGE(ability manager proxy is nullptr.);return ERR_ACCOUNT_COMMON_CONNECT_ABILITY_MANAGER_SERVICE_ERROR;}int error;MessageParcel data;MessageParcel reply;MessageOption option;if (!data.WriteInterfaceToken(ABILITY_MGR_DESCRIPTOR)) {ACCOUNT_LOGE(write interface token failed.);return INNER_ERR;}if (!data.WriteInt32(accountId)) {ACCOUNT_LOGE(StartUser:WriteInt32 fail.);return ERR_INVALID_VALUE;}//ipc调用startUsererror abms-SendRequest(static_castuint32_t(AbilityManagerInterfaceCode::START_USER), data, reply, option);if (error ! NO_ERROR) {ACCOUNT_LOGE(StartUser:SendRequest error: %{public}d, error);return error;}return reply.ReadInt32(); }foundation\ability\ability_runtime\services\abilitymgr\src\ability_manager_stub.cpp 消息码START_USER对应的函数为StartUserInner(); requestFuncMap_[static_castuint32_t(AbilityManagerInterfaceCode::START_USER)] AbilityManagerStub::StartUserInner;......int AbilityManagerStub::StartUserInner(MessageParcel data, MessageParcel reply) {int32_t userId data.ReadInt32();int result StartUser(userId);if (!reply.WriteInt32(result)) {HILOG_ERROR(StartUser failed.);return ERR_INVALID_VALUE;}return NO_ERROR; }StartUser对应的实现在AbilityManagerStub的实现类AbilityManagerService中 foundation\ability\ability_runtime\services\abilitymgr\src\ability_manager_service.cpp int AbilityManagerService::StartUser(int userId) {HILOG_DEBUG(%{public}s, userId:%{public}d, __func__, userId);//权限验证if (IPCSkeleton::GetCallingUid() ! ACCOUNT_MGR_SERVICE_UID) {HILOG_ERROR(%{public}s: Permission verification failed, not account process, __func__);return CHECK_PERMISSION_FAILED;}if (userController_) {return userController_-StartUser(userId, true);}return 0; }foundation\ability\ability_runtime\services\abilitymgr\src\user_controller.cpp int32_t UserController::StartUser(int32_t userId, bool isForeground) {if (userId 0 || userId USER_ID_NO_HEAD) {HILOG_ERROR(StartUser userId is invalid:%{public}d, userId);return -1;}if (IsCurrentUser(userId)) {HILOG_WARN(StartUser user is already current:%{public}d, userId);return 0;}if (!IsExistOsAccount(userId)) {HILOG_ERROR(StartUser not exist such account:%{public}d, userId);return -1;}if (isForeground GetCurrentUserId() ! USER_ID_NO_HEAD !Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {// start freezing screenSetFreezingNewUserId(userId);DelayedSingletonAbilityManagerService::GetInstance()-StartFreezingScreen();}auto oldUserId GetCurrentUserId();auto userItem GetOrCreateUserItem(userId);auto state userItem-GetState();if (state STATE_STOPPING || state STATE_SHUTDOWN) {HILOG_ERROR(StartUser user is stop now, userId:%{public}d, userId);return -1;}if (isForeground) {SetCurrentUserId(userId);// notify wms switching now}bool needStart false;if (state STATE_BOOTING) {needStart true;// send user start msg.SendSystemUserStart(userId);}if (isForeground) {SendSystemUserCurrent(oldUserId, userId);SendReportUserSwitch(oldUserId, userId, userItem);SendUserSwitchTimeout(oldUserId, userId, userItem);}if (needStart) {BroadcastUserStarted(userId);}UserBootDone(userItem);if (isForeground) {MoveUserToForeground(oldUserId, userId);}return 0; }......void UserController::MoveUserToForeground(int32_t oldUserId, int32_t newUserId) {auto manager DelayedSingletonAbilityManagerService::GetInstance();if (!manager) {return;}//切到当前用户manager-SwitchToUser(oldUserId, newUserId);BroadcastUserBackground(oldUserId);BroadcastUserForeground(newUserId); }foundation\ability\ability_runtime\services\abilitymgr\src\ability_manager_service.cpp void AbilityManagerService::SwitchToUser(int32_t oldUserId, int32_t userId) {HILOG_INFO(%{public}s, oldUserId:%{public}d, newUserId:%{public}d, __func__, oldUserId, userId);SwitchManagers(userId);if (!Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {PauseOldUser(oldUserId);ConnectBmsService();//启动用户应用StartUserApps();}bool isBoot oldUserId U0_USER_ID ? true : false;//启动luancher或者开机引导StartHighestPriorityAbility(userId, isBoot);PauseOldConnectManager(oldUserId); }......void AbilityManagerService::StartUserApps() {if (currentMissionListManager_ currentMissionListManager_-IsStarted()) {HILOG_INFO(missionListManager ResumeManager);currentMissionListManager_-ResumeManager();} }......void AbilityManagerService::StartHighestPriorityAbility(int32_t userId, bool isBoot) {HILOG_DEBUG(%{public}s, __func__);auto bms GetBundleManager();CHECK_POINTER(bms);/* Query the highest priority ability or extension ability, and start it. usually, it is OOBE or launcher */Want want;want.AddEntity(HIGHEST_PRIORITY_ABILITY_ENTITY);AppExecFwk::AbilityInfo abilityInfo;AppExecFwk::ExtensionAbilityInfo extensionAbilityInfo;int attemptNums 0;//查询优先级最高的abilitywhile (!IN_PROCESS_CALL(bms-ImplicitQueryInfoByPriority(want,AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_DEFAULT, userId,abilityInfo, extensionAbilityInfo))) {HILOG_INFO(Waiting query highest priority ability info completed.);attemptNums;if (!isBoot attemptNums SWITCH_ACCOUNT_TRY) {HILOG_ERROR(Query highest priority ability failed.);return;}AbilityRequest abilityRequest;usleep(REPOLL_TIME_MICRO_SECONDS);}if (abilityInfo.name.empty() extensionAbilityInfo.name.empty()) {HILOG_ERROR(Query highest priority ability failed);return;}Want abilityWant; // donot use want here, because the entity of want is not emptyif (!abilityInfo.name.empty()) {/* highest priority ability */HILOG_INFO(Start the highest priority ability. bundleName: %{public}s, ability:%{public}s,abilityInfo.bundleName.c_str(), abilityInfo.name.c_str());abilityWant.SetElementName(abilityInfo.bundleName, abilityInfo.name);} else {/* highest priority extension ability */HILOG_INFO(Start the highest priority extension ability. bundleName: %{public}s, ability:%{public}s,extensionAbilityInfo.bundleName.c_str(), extensionAbilityInfo.name.c_str());abilityWant.SetElementName(extensionAbilityInfo.bundleName, extensionAbilityInfo.name);}#ifdef SUPPORT_GRAPHICSabilityWant.SetParam(NEED_STARTINGWINDOW, false);// wait BOOT_ANIMATION_STARTED to start LAUNCHER//等待开机动画是否准备好才能继续往下走启动launcherWaitBootAnimationStart(); #endif/* OOBE APP启动完成之后需要disable自己否者每次重启都会启动 */(void)StartAbility(abilityWant, userId, DEFAULT_INVAL_VALUE); }......void AbilityManagerService::WaitBootAnimationStart() {//判读属性bootevent.bootanimation.ready是否被置为true.char value[BOOTEVENT_BOOT_ANIMATION_READY_SIZE] ;int32_t ret GetParameter(BOOTEVENT_BOOT_ANIMATION_READY.c_str(), , value,BOOTEVENT_BOOT_ANIMATION_READY_SIZE);if (ret 0 !std::strcmp(value, false)) {// Get new param success and new param is not ready, wait the new param.WaitParameter(BOOTEVENT_BOOT_ANIMATION_READY.c_str(), true,AmsConfigurationParameter::GetInstance().GetBootAnimationTimeoutTime());} else if (ret 0 || !std::strcmp(value, )) {// Get new param failed or new param is not set, wait the old param.WaitParameter(BOOTEVENT_BOOT_ANIMATION_STARTED.c_str(), true,AmsConfigurationParameter::GetInstance().GetBootAnimationTimeoutTime());}// other, the animation is ready, not wait. }......std::shared_ptrAppExecFwk::BundleMgrHelper AbilityManagerService::GetBundleManager() {if (bundleMgrHelper_ nullptr) {bundleMgrHelper_ AbilityUtil::GetBundleManagerHelper();}return bundleMgrHelper_; }至此launcher或者开机引导(OOBE)就启动完成。 foundation\ability\ability_runtime\frameworks\native\appkit\ability_bundle_manager_helper\bundle_mgr_helper.cpp bool BundleMgrHelper::ImplicitQueryInfoByPriority(const Want want, int32_t flags, int32_t userId, AbilityInfo abilityInfo, ExtensionAbilityInfo extensionInfo) {HILOG_DEBUG(Called.);//绑定服务BundleMgrServiceauto bundleMgr Connect();if (bundleMgr nullptr) {HILOG_ERROR(Failed to connect.);return false;}//调用包管理服务的ImplicitQueryInfoByPriorityreturn bundleMgr-ImplicitQueryInfoByPriority(want, flags, userId, abilityInfo, extensionInfo); }......sptrIBundleMgr BundleMgrHelper::Connect() {HILOG_DEBUG(Called.);std::lock_guardstd::mutex lock(mutex_);if (bundleMgr_ nullptr) {sptrISystemAbilityManager systemAbilityManager SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();if (systemAbilityManager nullptr) {HILOG_ERROR(Failed to get system ability manager.);return nullptr;}sptrIRemoteObject remoteObject_ systemAbilityManager-GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);if (remoteObject_ nullptr || (bundleMgr_ iface_castIBundleMgr(remoteObject_)) nullptr) {HILOG_ERROR(Failed to get bundle mgr service remote object.);return nullptr;}std::weak_ptrBundleMgrHelper weakPtr shared_from_this();auto deathCallback [weakPtr](const wptrIRemoteObject object) {auto sharedPtr weakPtr.lock();if (sharedPtr nullptr) {HILOG_ERROR(Bundle helper instance is nullptr.);return;}sharedPtr-OnDeath();};deathRecipient_ new (std::nothrow) BundleMgrServiceDeathRecipient(deathCallback);if (deathRecipient_ nullptr) {HILOG_ERROR(Failed to create death recipient ptr deathRecipient_!);return nullptr;}if (bundleMgr_-AsObject() ! nullptr) {bundleMgr_-AsObject()-AddDeathRecipient(deathRecipient_);}}return bundleMgr_; }foundation\bundlemanager\bundle_framework\interfaces\inner_api\appexecfwk_core\src\bundlemgr\bundle_mgr_proxy.cpp bool BundleMgrProxy::ImplicitQueryInfoByPriority(const Want want, int32_t flags, int32_t userId,AbilityInfo abilityInfo, ExtensionAbilityInfo extensionInfo) {APP_LOGD(begin to ImplicitQueryInfoByPriority);HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);MessageParcel data;if (!data.WriteInterfaceToken(GetDescriptor())) {APP_LOGE(fail to implicit query info by priority due to write MessageParcel fail);return false;}if (!data.WriteParcelable(want)) {APP_LOGE(fail to implicit query info by priority due to write want fail);return false;}if (!data.WriteInt32(flags)) {APP_LOGE(fail to implicit query info by priority due to write flags fail);return false;}if (!data.WriteInt32(userId)) {APP_LOGE(fail to implicit query info by priority due to write userId error);return false;}MessageParcel reply;//将消息码和对应的数据发给服务端if (!SendTransactCmd(BundleMgrInterfaceCode::IMPLICIT_QUERY_INFO_BY_PRIORITY, data, reply)) {return false;}if (!reply.ReadBool()) {APP_LOGE(reply result false);return false;}std::unique_ptrAbilityInfo abilityInfoPtr(reply.ReadParcelableAbilityInfo());if (abilityInfoPtr nullptr) {APP_LOGE(read AbilityInfo failed);return false;}abilityInfo *abilityInfoPtr;std::unique_ptrExtensionAbilityInfo extensionInfoPtr(reply.ReadParcelableExtensionAbilityInfo());if (extensionInfoPtr nullptr) {APP_LOGE(read ExtensionAbilityInfo failed);return false;}extensionInfo *extensionInfoPtr;return true; }foundation\bundlemanager\bundle_framework\interfaces\inner_api\appexecfwk_core\src\bundlemgr\bundle_mgr_host.cpp //消息码对应的函数 funcMap_.emplace(static_castuint32_t(BundleMgrInterfaceCode::IMPLICIT_QUERY_INFO_BY_PRIORITY),BundleMgrHost::HandleImplicitQueryInfoByPriority);......ErrCode BundleMgrHost::HandleImplicitQueryInfoByPriority(MessageParcel data, MessageParcel reply) {HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__);std::unique_ptrWant want(data.ReadParcelableWant());if (want nullptr) {APP_LOGE(ReadParcelablewant failed);return ERR_APPEXECFWK_PARCEL_ERROR;}int32_t flags data.ReadInt32();int32_t userId data.ReadInt32();AbilityInfo abilityInfo;ExtensionAbilityInfo extensionInfo;bool ret ImplicitQueryInfoByPriority(*want, flags, userId, abilityInfo, extensionInfo);if (!reply.WriteBool(ret)) {APP_LOGE(write failed);return ERR_APPEXECFWK_PARCEL_ERROR;}if (ret) {if (!reply.WriteParcelable(abilityInfo)) {APP_LOGE(write AbilityInfo failed);return ERR_APPEXECFWK_PARCEL_ERROR;}if (!reply.WriteParcelable(extensionInfo)) {APP_LOGE(write ExtensionAbilityInfo failed);return ERR_APPEXECFWK_PARCEL_ERROR;}}return ERR_OK; }foundation\bundlemanager\bundle_framework\services\bundlemgr\src\bundle_mgr_host_impl.cpp //ImplicitQueryInfoByPriority函数对应的服务端实现 bool BundleMgrHostImpl::ImplicitQueryInfoByPriority(const Want want, int32_t flags, int32_t userId,AbilityInfo abilityInfo, ExtensionAbilityInfo extensionInfo) {APP_LOGD(start ImplicitQueryInfoByPriority, flags : %{public}d, userId : %{public}d, flags, userId);//判断是否是系统应用以及sdk版本号是否为9if (!BundlePermissionMgr::IsSystemApp() !BundlePermissionMgr::VerifyCallingBundleSdkVersion(Constants::API_VERSION_NINE)) {APP_LOGD(non-system app calling system api);return true;}//判断是否有对应的权限if (!BundlePermissionMgr::VerifyCallingPermissionsForAll({Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED,Constants::PERMISSION_GET_BUNDLE_INFO}) !BundlePermissionMgr::IsBundleSelfCalling(want.GetElement().GetBundleName())) {APP_LOGE(verify permission failed);return false;}auto dataMgr GetDataMgrFromService();if (dataMgr nullptr) {APP_LOGE(DataMgr is nullptr);return false;}return dataMgr-ImplicitQueryInfoByPriority(want, flags, userId, abilityInfo, extensionInfo); }foundation\bundlemanager\bundle_framework\services\bundlemgr\src\bundle_data_mgr.cpp bool BundleDataMgr::ImplicitQueryInfoByPriority(const Want want, int32_t flags, int32_t userId,AbilityInfo abilityInfo, ExtensionAbilityInfo extensionInfo) const {int32_t requestUserId GetUserId(userId);if (requestUserId Constants::INVALID_USERID) {APP_LOGW(invalid userId);return false;}//查询对应的abilityInfos和extensionInfosstd::vectorAbilityInfo abilityInfos;bool abilityValid ImplicitQueryAbilityInfos(want, flags, requestUserId, abilityInfos) (abilityInfos.size() 0);std::vectorExtensionAbilityInfo extensionInfos;bool extensionValid ImplicitQueryExtensionInfos(want, flags, requestUserId, extensionInfos) (extensionInfos.size() 0);if (!abilityValid !extensionValid) {// both invalidAPP_LOGW(cant find target AbilityInfo or ExtensionAbilityInfo);return false;}if (abilityValid extensionValid) {// both validif (abilityInfos[0].priority extensionInfos[0].priority) {APP_LOGD(find target AbilityInfo with higher priority, name : %{public}s, abilityInfos[0].name.c_str());abilityInfo abilityInfos[0];} else {APP_LOGD(find target ExtensionAbilityInfo with higher priority, name : %{public}s,extensionInfos[0].name.c_str());extensionInfo extensionInfos[0];}} else if (abilityValid) {// only ability validAPP_LOGD(find target AbilityInfo, name : %{public}s, abilityInfos[0].name.c_str());abilityInfo abilityInfos[0];} else {// only extension validAPP_LOGD(find target ExtensionAbilityInfo, name : %{public}s, extensionInfos[0].name.c_str());extensionInfo extensionInfos[0];}return true; }......bool BundleDataMgr::ImplicitQueryAbilityInfos(const Want want, int32_t flags, int32_t userId, std::vectorAbilityInfo abilityInfos, int32_t appIndex) const {int32_t requestUserId GetUserId(userId);if (requestUserId Constants::INVALID_USERID) {return false;}//开机启动的时候传进来的entity为HIGHEST_PRIORITY_ABILITY_ENTITYif (want.GetAction().empty() want.GetEntities().empty() want.GetUriString().empty() want.GetType().empty()) {APP_LOGE(param invalid);return false;}APP_LOGD(action:%{public}s, uri:%{private}s, type:%{public}s,want.GetAction().c_str(), want.GetUriString().c_str(), want.GetType().c_str());APP_LOGD(flags:%{public}d, userId:%{public}d, flags, userId);std::shared_lockstd::shared_mutex lock(bundleInfoMutex_);if (bundleInfos_.empty()) {APP_LOGW(bundleInfos_ is empty);return false;}//开机启动的时候没有设置bundleName所以为emptystd::string bundleName want.GetElement().GetBundleName();if (!bundleName.empty()) {// query in current bundleNameif (!ImplicitQueryCurAbilityInfos(want, flags, requestUserId, abilityInfos, appIndex)) {APP_LOGD(ImplicitQueryCurAbilityInfos failed, bundleName: %{public}s, bundleName.c_str());return false;}} else {// query allImplicitQueryAllAbilityInfos(want, flags, requestUserId, abilityInfos, appIndex);}// sort by priority, descending order.//根据proority做排序if (abilityInfos.size() 1) {std::stable_sort(abilityInfos.begin(), abilityInfos.end(),[](AbilityInfo a, AbilityInfo b) { return a.priority b.priority; });}return true; }......void BundleDataMgr::ImplicitQueryAllAbilityInfos(const Want want, int32_t flags, int32_t userId,std::vectorAbilityInfo abilityInfos, int32_t appIndex) const {APP_LOGD(begin to ImplicitQueryAllAbilityInfos.);int32_t requestUserId GetUserId(userId);if (requestUserId Constants::INVALID_USERID) {APP_LOGW(invalid userId);return;}// query from bundleInfos_if (appIndex 0) {for (const auto item : bundleInfos_) {const InnerBundleInfo innerBundleInfo item.second;int32_t responseUserId innerBundleInfo.GetResponseUserId(requestUserId);if (CheckInnerBundleInfoWithFlags(innerBundleInfo, flags, responseUserId) ! ERR_OK) {APP_LOGD(ImplicitQueryAllAbilityInfos failed, bundleName:%{public}s, responseUserId:%{public}d,innerBundleInfo.GetBundleName().c_str(), responseUserId);continue;}GetMatchAbilityInfos(want, flags, innerBundleInfo, responseUserId, abilityInfos);}} else {// query from sandbox manager for sandbox bundleif (sandboxAppHelper_ nullptr) {APP_LOGW(sandboxAppHelper_ is nullptr);return;}auto sandboxMap sandboxAppHelper_-GetSandboxAppInfoMap();for (const auto item : sandboxMap) {InnerBundleInfo info;size_t pos item.first.rfind(Constants::FILE_UNDERLINE);if (pos std::string::npos) {APP_LOGD(sandbox map contains invalid element);continue;}std::string innerBundleName item.first.substr(pos 1);if (sandboxAppHelper_-GetSandboxAppInfo(innerBundleName, appIndex, userId, info) ! ERR_OK) {APP_LOGD(obtain innerBundleInfo of sandbox app failed);continue;}int32_t responseUserId info.GetResponseUserId(userId);GetMatchAbilityInfos(want, flags, info, responseUserId, abilityInfos);}}APP_LOGD(finish to ImplicitQueryAllAbilityInfos.); }void BundleDataMgr::GetMatchAbilityInfos(const Want want, int32_t flags,const InnerBundleInfo info, int32_t userId, std::vectorAbilityInfo abilityInfos) const {if ((static_castuint32_t(flags) GET_ABILITY_INFO_SYSTEMAPP_ONLY) GET_ABILITY_INFO_SYSTEMAPP_ONLY !info.IsSystemApp()) {return;}std::mapstd::string, std::vectorSkill skillInfos info.GetInnerSkillInfos();for (const auto abilityInfoPair : info.GetInnerAbilityInfos()) {bool isPrivateType MatchPrivateType(want, abilityInfoPair.second.supportExtNames, abilityInfoPair.second.supportMimeTypes);auto skillsPair skillInfos.find(abilityInfoPair.first);if (skillsPair skillInfos.end()) {continue;}for (const Skill skill : skillsPair-second) {if (isPrivateType || skill.Match(want)) {AbilityInfo abilityinfo abilityInfoPair.second;AddAbilitySkillUrisInfo(flags, skill, abilityinfo);if (abilityinfo.name Constants::APP_DETAIL_ABILITY) {continue;}if (!(static_castuint32_t(flags) GET_ABILITY_INFO_WITH_DISABLE)) {if (!info.IsAbilityEnabled(abilityinfo, GetUserId(userId))) {APP_LOGW(GetMatchAbilityInfos %{public}s is disabled, abilityinfo.name.c_str());continue;}}if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_APPLICATION) GET_ABILITY_INFO_WITH_APPLICATION) {info.GetApplicationInfo(ApplicationFlag::GET_APPLICATION_INFO_WITH_CERTIFICATE_FINGERPRINT, userId,abilityinfo.applicationInfo);}if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_PERMISSION) !GET_ABILITY_INFO_WITH_PERMISSION) {abilityinfo.permissions.clear();}if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_METADATA) ! GET_ABILITY_INFO_WITH_METADATA) {abilityinfo.metaData.customizeData.clear();abilityinfo.metadata.clear();}abilityInfos.emplace_back(abilityinfo);break;}}} }void BundleDataMgr::AddAbilitySkillUrisInfo(int32_t flags, const Skill skill, AbilityInfo abilityInfo) const {if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_SKILL_URI) GET_ABILITY_INFO_WITH_SKILL_URI) {std::vectorSkillUriForAbilityAndExtension skillUriTmp;for (const SkillUri uri : skill.uris) {SkillUriForAbilityAndExtension skillinfo;skillinfo.scheme uri.scheme;skillinfo.host uri.host;skillinfo.port uri.port;skillinfo.path uri.path;skillinfo.pathStartWith uri.pathStartWith;skillinfo.pathRegex uri.pathRegex;skillinfo.type uri.type;skillinfo.utd uri.utd;skillinfo.maxFileSupported uri.maxFileSupported;skillUriTmp.emplace_back(skillinfo);}abilityInfo.skillUri skillUriTmp;} } AbilityInfo abilityInfos) const {if ((static_castuint32_t(flags) GET_ABILITY_INFO_SYSTEMAPP_ONLY) GET_ABILITY_INFO_SYSTEMAPP_ONLY !info.IsSystemApp()) {return;}std::mapstd::string, std::vectorSkill skillInfos info.GetInnerSkillInfos();for (const auto abilityInfoPair : info.GetInnerAbilityInfos()) {bool isPrivateType MatchPrivateType(want, abilityInfoPair.second.supportExtNames, abilityInfoPair.second.supportMimeTypes);auto skillsPair skillInfos.find(abilityInfoPair.first);if (skillsPair skillInfos.end()) {continue;}for (const Skill skill : skillsPair-second) {if (isPrivateType || skill.Match(want)) {AbilityInfo abilityinfo abilityInfoPair.second;AddAbilitySkillUrisInfo(flags, skill, abilityinfo);if (abilityinfo.name Constants::APP_DETAIL_ABILITY) {continue;}if (!(static_castuint32_t(flags) GET_ABILITY_INFO_WITH_DISABLE)) {if (!info.IsAbilityEnabled(abilityinfo, GetUserId(userId))) {APP_LOGW(GetMatchAbilityInfos %{public}s is disabled, abilityinfo.name.c_str());continue;}}if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_APPLICATION) GET_ABILITY_INFO_WITH_APPLICATION) {info.GetApplicationInfo(ApplicationFlag::GET_APPLICATION_INFO_WITH_CERTIFICATE_FINGERPRINT, userId,abilityinfo.applicationInfo);}if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_PERMISSION) !GET_ABILITY_INFO_WITH_PERMISSION) {abilityinfo.permissions.clear();}if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_METADATA) ! GET_ABILITY_INFO_WITH_METADATA) {abilityinfo.metaData.customizeData.clear();abilityinfo.metadata.clear();}abilityInfos.emplace_back(abilityinfo);break;}}} }void BundleDataMgr::AddAbilitySkillUrisInfo(int32_t flags, const Skill skill, AbilityInfo abilityInfo) const {if ((static_castuint32_t(flags) GET_ABILITY_INFO_WITH_SKILL_URI) GET_ABILITY_INFO_WITH_SKILL_URI) {std::vectorSkillUriForAbilityAndExtension skillUriTmp;for (const SkillUri uri : skill.uris) {SkillUriForAbilityAndExtension skillinfo;skillinfo.scheme uri.scheme;skillinfo.host uri.host;skillinfo.port uri.port;skillinfo.path uri.path;skillinfo.pathStartWith uri.pathStartWith;skillinfo.pathRegex uri.pathRegex;skillinfo.type uri.type;skillinfo.utd uri.utd;skillinfo.maxFileSupported uri.maxFileSupported;skillUriTmp.emplace_back(skillinfo);}abilityInfo.skillUri skillUriTmp;} }
http://www.w-s-a.com/news/502395/

相关文章:

  • 更改各网站企业信息怎么做张家港企业网站制作
  • 郑州网站建设咨询银川做网站哪家好
  • 微信网站 微信支付合肥seo排名收费
  • 织梦做的网站如何上线广东省广州市番禺区南村镇
  • 网站设计的导航栏怎么做太原有网站工程公司吗
  • 苏州虎丘区建设局网站如何在一个数据库做两个网站
  • 淘宝天猫优惠券网站建设费用腾讯邮箱企业邮箱登录
  • 深圳福田做网站公司海航科技网站建设
  • 网站降权查询wordpress更换文章背景色
  • 大型电商网站开发金融企业网站建设公司
  • 成都营销型网站建设价格化妆品品牌推广方案
  • 深圳公司手机网站制作苏州网站推广哪家好
  • 网站建设开发方式包括购买学校网站建设费计入什么科目
  • 做简单网站的框架图中小微企业查询平台
  • 哪些网站可以免费做产品推广建设建设部网站
  • 网站开发销售怎么做django做网站
  • 淘宝客网站做百度竞价万网域名怎么绑定网站
  • 建设网站找哪个公司北京知名大公司有哪些
  • 专业彩票网站开发网站流量在哪设置
  • 网站建设对应的岗位榆林做网站公司
  • 网站建设公司怎么算专业js网站分页怎么做
  • 网和网站的区别phpcms和帝国cms哪个好
  • wordpress改网站名字长沙网络营销外包
  • 宝塔怎么做第二个网站网站内容设计遵循的原则有
  • 网站违反了 google 质量指南免费ppt模版网站
  • 郑州网站建设郑州网站建设成都那家网站建设好
  • 温州网站排名优化公司如何招聘软件网站开发人员
  • 成都 网站建设公司哪家好襄阳行业网站建设
  • wordpress 调用时间做网站seo的公司哪家好
  • 手机上网站搭建网站账户系统