高通SDM660芯片的启动流程
作者:互联网
高通芯片启动流程
QSEE 运行在安全模式并且只能被OEM签名。
- UEFI启动:
bootable/bootloader/edk2/QcomModulePkg/Library/BootLib/BootLinux.c 加载boot.img流程
signer:manual
NEPTUNE: Kernel Image Signing Verification successful
No Ffbm cookie found, ignore: Not Found
Memory Base Address: 0x80000000
Decompressing kernel image start: 3488 ms//解压内核镜像
Decompressing kernel image done: 3818 ms
amzn_verify_unlock: Failed to get unlock key
PON Reason is 16 cold_boot:1 charger path: 1
Cmdline: console=ttyMSM0,921600,n8 androidboot.console=ttyMSM0 earlycon=msm_serial_dm,0xc170000 androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 lpm_levels.sleep_disabled=1 sched_enable_hmp=1 sched_enable_power_aware=1 service_lError getting pmic info ext: Device Error
Error finding board pmic info: Device Error
代码分析:
2. ABL
DEBUG((EFI_D_VERBOSE, "Kernel Size Actual: 0x%x\n", KernelSizeActual));
DEBUG((EFI_D_VERBOSE, "Second Size Actual: 0x%x\n", SecondSizeActual));
DEBUG((EFI_D_VERBOSE, "Ramdisk Size Actual: 0x%x\n", RamdiskSizeActual));
DEBUG((EFI_D_VERBOSE, "Ramdisk Offset: 0x%x\n", RamdiskOffset));
DEBUG((EFI_D_VERBOSE, "Device TreeOffset: 0x%x\n", DeviceTreeOffset));
VOID *DeviceTreeAppended(VOID *kernel, UINT32 kernel_size, UINT32 dtb_offset, VOID *tags)
{
EFI_STATUS Status;
uintptr_t kernel_end = (uintptr_t)kernel + kernel_size;
VOID *dtb = NULL;
VOID *bestmatch_tag = NULL;
UINT64 RamdiskLoadAddr;
UINT64 BaseMemory = 0;
struct dt_entry *best_match_dt_entry = NULL;
UINT32 bestmatch_tag_size;
struct dt_entry_node *dt_entry_queue = NULL;
struct dt_entry_node *dt_node_tmp1 = NULL;
struct dt_entry_node *dt_node_tmp2 = NULL;
/* Initialize the dtb entry node*/
dt_entry_queue = (struct dt_entry_node *)
AllocatePool(sizeof(struct dt_entry_node));
if (!dt_entry_queue) {
DEBUG((EFI_D_ERROR, "Out of memory\n"));
return NULL;
}
memset(dt_entry_queue, 0, sizeof(struct dt_entry_node));
list_initialize(&dt_entry_queue->node);
if (!dtb_offset){
DEBUG((EFI_D_ERROR, "DTB offset is NULL\n"));
goto out;
}
if (((uintptr_t)kernel + (uintptr_t)dtb_offset) < (uintptr_t)kernel) {
goto out;
}
dtb = kernel + dtb_offset;
while (((uintptr_t)dtb + sizeof(struct fdt_header)) < (uintptr_t)kernel_end) {
struct fdt_header dtb_hdr;
UINT32 dtb_size;
/* the DTB could be unaligned, so extract the header,
* and operate on it separately */
CopyMem(&dtb_hdr, dtb, sizeof(struct fdt_header));
if (fdt_check_header((const VOID *)&dtb_hdr) != 0 ||
fdt_check_header_ext((VOID *)&dtb_hdr) != 0 ||
((uintptr_t)dtb + (uintptr_t)fdt_totalsize((const VOID *)&dtb_hdr) < (uintptr_t)dtb) ||
((uintptr_t)dtb + (uintptr_t)fdt_totalsize((const VOID *)&dtb_hdr) > (uintptr_t)kernel_end))
break;
dtb_size = fdt_totalsize(&dtb_hdr);
if (!DeviceTreeCompatible(dtb, dtb_size, dt_entry_queue)) {
DEBUG((EFI_D_VERBOSE, "Error while DTB parse continue with next DTB\n"));
}
/* goto the next device tree if any */
dtb += dtb_size;
}
best_match_dt_entry = platform_dt_match_best(dt_entry_queue);
设备树匹配,遍历所有设备树
STATIC struct dt_entry *platform_dt_match_best(struct dt_entry_node *dt_list)
{
struct dt_entry_node *dt_node_tmp1 = NULL;
/* check Foundry id
* the foundry id must exact match board founddry id, this is compatibility check,
* if couldn't find the exact match from DTB, will exact match 0x0.
*/
if (!platform_dt_absolute_compat_match(dt_list, DTB_FOUNDRY))//匹配DTB版本
return NULL;
/* check PMIC model
* the PMIC model must exact match board PMIC model, this is compatibility check,
* if couldn't find the exact match from DTB, will exact match 0x0.
*/
if (!platform_dt_absolute_compat_match(dt_list, DTB_PMIC_MODEL))//匹配PMIC版本
return NULL;
/* check soc version
* the suitable soc version must less than or equal to board soc version
*/
if (!update_dtb_entry_node(dt_list, DTB_SOC))
return NULL;
/*check major and minor version
* the suitable major&minor version must less than or equal to board major&minor version
*/
if (!update_dtb_entry_node(dt_list, DTB_MAJOR_MINOR)) ///检查subtype
return NULL;
3. Linux kernel层
asmlinkage void __init start_kernel(void)
{
local_irq_disable();
early_boot_irqs_off();
early_init_irq_lock_class();
/*
1. Interrupts are still disabled. Do necessary setups, then
2. enable them
*/
lock_kernel();
tick_init();
boot_cpu_init();
page_address_init();
printk(KERN_NOTICE);
printk(linux_banner);
setup_arch(command_line);//初始化
setup_command_line(command_line);
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
parse_early_param();
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);
init_IRQ();//中断初始化
profile_init();
if (!irqs_disabled())
printk("start_kernel(): bug: interrupts were enabled early\n");
early_boot_irqs_on();
local_irq_enable();
console_init();
rest_init();//会通过kernel_thread来生成1个内核进程
}
4. System init:
代码路径System/core/init.cpp
对应的log如下
[ 7.900996] init: init first stage started!
[ 7.983229] audit: type=1403 audit(12.809:2): policy loaded auid=4294967295 ses=4294967295
[ 7.983950] audit: type=1404 audit(12.809:3): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295
[ 7.990647] init: (Initializing SELinux enforcing took 0.09s.)
[ 8.003941] init: init second stage started!
[ 8.013583] init: Running restorecon...
[ 8.323897] init: waitpid failed: No child processes
[ 8.324841] init: (Loading properties from /default.prop took 0.00s.)
[ 8.328755] init: could not import file '/init.recovery.qcom.rc' from '/init.rc': No such file or directory
[ 8.334335] init: (Parsing /init.rc took 0.01s.)
[ 8.344019] init: Starting service 'ueventd'...
[ 8.349071] init: Starting service 'healthd'...
- Framework层
./base/services/java/com/android/server/SystemServer.java
Systemserver 孵化出bootstrapservice /coreService/otherService等java服务。
service_manager:c++。service_manager本身工作相对简单,其功能:查询和注册服务
标签:node,kernel,芯片,dtb,SDM660,高通,init,entry,dt 来源: https://blog.csdn.net/wwxxff28/article/details/113803207