1、mtk开机基本流程:
boot rom ————》preloader ————》lk ————》kernel ————》android
2、boot rom:
每个芯片有自己的boot rom,上电时启动,然后将preloader加载到内部sram中,因为此时外部ram还没有初始化,需要preloader去初始化
3、preloader:
vendor/mediatek/proprietary/bootable/bootloader/preloader/platform/mt6765/src
init:init.S
汇编完成,主要四切换系统到SVC模式(超级用户模式),平台要是有实现EL3,preloader就运行在EL3,否则运行在EL1,还有负责禁止irq/fiq,设置stack等,然后会jump到C语言开始的main函数中
core:C开始的main.c中的main函数
完成各种硬件的基本初始化,如uart、timer、rtc、wdt、mem、pmic等
获取rtc记录的系统的启动模式,启动原因等,保存到全局变量bootargs中
security check,和安全相关
找到 lk加载到dram的地址(是一个固定的地址),从rom中找到lk分区的地址,
battery check,如果没有电池就一直while(1)
jump到lk
重点函数:
bldr_load_images:找到lk分区地址和lk加载到dram中的地址,准备jump到lk
bldr_post_process:主要是里面的platform_post_init函数,会检查电池是否存在
platform_init:rtc、pmic、wdt、gpio、i2c、battery、mem等初始化,
也是在这里通过usb phy监听握手识别是否有usb插入
4、lk(little kernel):
进入lk之后,部分硬件可能还需要重新reset初始化,来保证一个比较干净的环境,比如timer
lk/arch/arm/crt0.S:
lk/kernel/main.c:kmain
使能 MMU、cache
使能 Uart、中断、定时器、DRAM Banks、wot、display
创建一个 bootstrap2 线程
bootstrap2:
platform_init:启动模式选择、电池、显示 Logo、背光打开、设置软件的环境变量
target_init:空
apps_init:
lk/app/app.c下的app.c中start_app,创建一个app_thread_entry线程
__apps_start 和 __apps_end 的定义,这两个变量符号在所有源文件中并不存在,而是在 arch/arm/*.ld 链接脚本中存在,所有的 app 都通过在特殊的段 .apps 中注册实现了一套插件系统,是一个十分精巧的设计。后续的任何新的 app 只需要使用以下两个宏声明即可注册到 .apps 段中,遍历 .apps 段就可以获取 aboot 的描述信息,调用 aboot 的 init 函数了
实例:
APP_START(aboot)
APP_START(mt_boot)
如果 g_boot_mode 为 FASTBOOT 就走 fastboot 模式 否则 boot_linux_from_storage()
boot_linux_from_storage()
boot_linux跳转到kernel
这里具体进入哪种boot_mode,通过全局变量g_boot_mode来分化
平台platform.c中的platform_init:
全局环境变量读取
led backlight disp等init
根据不同模式显示第一帧logo
boot_mode_select:
会检测power和其他按键是否按下,按照boot_mode.c中的按键和组合键走对应的流程,如果当前启动的原因是 USB 充电器,而不是 power 按键,电池模块将等待用户按下 power 按键启动
5、kernel:
lk下通过boot_linux跳转到kernel和ramdisk镜像地址
head.S:
解压zimage,head.S 首先初始化自解压相关的如内存等环境,接下来调用 decompress_kernel 进行解压(./arch/arm/boot/compressed/misc.c)
start_kernel:
satrt kernel启动内核,在init/main.c中
start_kernel 是任何版本 Linux 内核的通用初始化函数,它会初始化很多东西,输出 Linux 版本信息、设置体系结构相关的环境,页表结构初始化,设置系统自陷入口,初始化系统 IRQ,初始化核心调度器等
最后调用 rest_init:
调用kernel_init线程,然后kernel初始化完成后fork出init进程, 然后拉起ramdisk(ramdisk作用)中的init程序,执行 schedule 开始任务调度,进入用户空间初始化,init进程fork出zygote进程…直到整个Android启动完成