android uboot启动过程,Android启动流程简析(一)

最近一时兴起,想对Android的启动流程进行一次分析,经过一番整理,从以下几个方面进行总结,代码部分只讨论思路,不论细节。

Android架构介绍

Android启动概述

BootLoader介绍

Kernel初始化介绍

Init初始化介绍

Zygote启动介绍

SystemServer启动介绍

Launcher启动介绍

Log抓取与分析方法

由于发表文章的时候提示内容过长无法发布,于是把文章拆成了三部分发布:

1. Android架构介绍

Android的架构可以从架构图得知,主要分四层:

657336b545bd?clicktime=1578486875

Android经典的四层架构图

657336b545bd?clicktime=1578486875

Android架构图

每一层的作用不做介绍,这里主要讲涉及的镜像有boot.img、system.img、vendor.img、recovery.img、userdata.img、cache.img,与平台相关的镜像有lk.bin(MTK)、preloader.img(MTK)、logo.bin(MTK)、emmc_appsboot.mbn(QCOM)、splash.img(QCOM)等,通常来说,修改kernel层通常编译boot.img即可,修改Framework层或Native层主要是编译system.img,在Android O之后修改某些模块还需要编译vendor.img,主要是受Android O Treble的影响,具体问题需要具体分析。

2. Android启动概述

概述:Loader > Kernel > Native > Framework > Application

细分:BootRom > Bootloader > Kernel > Init > Zygote > SystemServer > Launcher

Loader层主要包括Boot Rom和Boot Loader

Kernel层主要是Android内核层

Native层主要是包括init进程以及其fork出来的用户空间的守护进程、HAL层、开机动画等

Framework层主要是AMS和PMS等Service的初始化

Application层主要指SystemUI、Launcher的启动

3. BootLoader介绍

Bootloader 就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射图,从而将系统的软硬件环境带到一个合适的状态,以便为最终调用操作系统内核准备好正确的环境。

调用流程:

crt0.S > kmain > arch_init > target_init > apps_init > aboot_init

3.1 crt0.S

高通平台:alps/bootable/bootloader/lk/arch/{paltform}/crt0.S

MTK平台:alps/vendor/mediatek/proprietary/bootable/bootloader/lk/arch/{paltform}/crt0.S

platform主要有arm、arm64、x86、x86-64等,crt0.S代码大体如下,在_start中先主要完成CPU初始化,禁用mmu,禁用cache,初始化异常向量表等操作,最后将直接跳转到函数kmain中

.section ".text.boot"

.globl _start

_start:

b reset

b arm_undefined

b arm_syscall

b arm_prefetch_abort

b arm_data_abort

b arm_reserved

b arm_irq

b arm_fiq

/*pre-loader to uboot argument Location*/

.global BOOT_ARGUMENT_LOCATION

BOOT_ARGUMENT_LOCATION:

.word 0x00000000

...

#if (!ENABLE_NANDWRITE)

#if WITH_CPU_WARM_BOOT

ldr r0, warm_boot_tag

cmp r0, #1

/* if set, warm boot */

ldreq pc, =BASE_ADDR

mov r0, #1

str r0, warm_boot_tag

#endif

#endif

...

#if defined(ARM_CPU_CORTEX_A8) || defined(ARM_CPU_CORTEX_A9)

DSB

ISB

#endif

bl kmain

b .

3.2 kmain

高通平台:alps/bootable/bootloader/lk/kernel/main.c

MTK平台:alps/vendor/mediatek/proprietary/bootable/bootloader/lk/kernel/main.c

/* called from crt0.S */

void kmain(void) __NO_RETURN __EXTERNALLY_VISIBLE;

void kmain(void)

{

#if !defined(MACH_FPGA) && !defined(SB_LK_BRINGUP)

boot_time = get_timer(0);

#endif

// get us into some sort of thread context

thread_init_early();

// early arch stuff

arch_early_init();

// do any super early platform initialization

platform_early_init();

#if defined(MACH_FPGA) || defined(SB_LK_BRINGUP)

boot_time = get_timer(0);

#endif

// do any super early target initialization

target_early_init();

dprintf(INFO, "welcome to lk\n\n");

// deal with any static constructors

dprintf(SPEW, "calling constructors\n");

call_constructors();

// bring up the kernel heap

dprintf(SPEW, "initializing heap\n");

heap_init();

// initialize the threading system

dprintf(SPEW, "initializing threads\n");

thread_init();

// initialize the dpc system

dprintf(SPEW, "initializing dpc\n");

dpc_init();

// initialize kernel timers

dprintf(SPEW, "initializing timers\n");

timer_init();

#ifdef MTK_LK_IRRX_SUPPORT

mtk_ir_init(0);

#endif

#if (!ENABLE_NANDWRITE)

// create a thread to complete system initialization

dprintf(SPEW, "creating bootstrap completion thread\n");

thread_t *thread_bs2 = thread_create("bootstrap2", &bootstrap2, NULL,

DEFAULT_PRIORITY, DEFAULT_STACK_SIZE);

if (thread_bs2)

thread_resume(thread_bs2);

else {

dprintf(CRITICAL, "Error: Cannot create bootstrap2 thread!\n");

assert(0);

}

thread_t *thread_io = thread_create("iothread", &iothread, NULL,

IO_THREAD_PRIORITY, DEFAULT_STACK_SIZE);

if (thread_io)

thread_resume(thread_io);

else {

dprintf(CRITICAL, "Error: Cannot create I/O thread!\n");

assert(0);

}

// enable interrupts

exit_critical_section();

// become the idle thread

thread_become_idle();

#else

bootstrap_nandwrite();

#endif

}

kmain主要流程:

调用thread_init_early初始化线程系统

调用arch_early_init中判断如果存在mmu就初始化,设置异常向量基地址,使能中断相关寄存器

在platform_early_init中完成初始化硬件时钟、手机的主板等操作,这个函数每种cpu的实现都不一样,定义在bootable\bootloader\lk\platform{cpu型号}\platform.c下

target_early_init中完成初始化uart端口的操作,这个函数的实现在bootable\bootloader\lk\target{cpu型号}\init.c

调用函数heap_init完成内核堆栈的初始化,用与kmalloc等函数的内存分配

在thread_init函数中初始化定时器

调用timer_init初始化内核定时器

如果没有定义ENABLE_NANDWRITE,就创建出一个名为bootstrap2的线程,然后运行这个线程。退出临界区,开中断;如果定义了ENABLE_NAND

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值