[Android6.0][MTK6737] 启动流程分析

news/2024/9/12 16:54:08/

OS:Android6.0 
Hardware:MTK6737

一、启动流程概览
1. BootRom
2. Preloader
3. LK
4. Kernel
5. Android

二、Bootloader 引导
2.1 preloader 启动过程
2.1.1 preloader 的功能
preloader 中的硬件部分
2.1.2 preloader 启动代码
2.2 LK 启动过程
2.2.1 LK 中的上电情景
2.2.2 LK 中的充电情景
2.2.3 LK 中的其他启动模式
2.2.4 LK 启动代码

三、Linux 内核启动
3.1 zImage 解压
3.2 start_kernel 启动
3.3 rest_init 调用 kernel_init

一、启动流程概览
1. BootRom
固化在 CPU 内部。 
负责从外部的存储器中加载 Preloader。 
负责 USB Download。

2. Preloader
属于 Bootloader 的第一部分。 
负责 MTK Licensed 
负责 基础 Module 的 初始化,比如 eMMC,PLL,DRAM 等。 
负责 加载 LittleKernel(LK)

3. LK(little kernel )
属于 Bootloader 的第二部分。 
负责 设备的初始化。 
负责 加载 Linux Kernel。 
支持 fastboot 更新。

4. Kernel
负责 设备初始化 / 内核初始化。 
负责 引导启动内核态 init 进程。

5. Android
负责 引导启动用户态 init 进程。 
负责 Zygote 启动。 
负责 Framework 初始化等。

以上基本可以化为三个部分:Bootloader(Preloader+LK)、Kernel、  Android。 
后面我们深入代码逐个分析。

二、Bootloader 引导
Bootloader 部分主要功能包括 设置处理器和内存频率、指定调试信息端口、可引导的存储设备等。完成可执行环境创建后,把 software 装载到内存并执行。除了装载 software ,外部工具也可以和 bootloader 握手,指示设备进入不同的操作模式(比如 USB 下载模式和 META 模式)。就算没有外部工具的握手,也可以通过自定义按键,使 bootloader 进入这些模式。

由于不同芯片商对 arm core 封装差异比较大,所以不同的 arm 处理器,对于上电引导都是由特定处理器芯片厂商自己开发的程序,这个上电引导程序通常比较简单,会初始化硬件,提供下载模式等,然后才会加载通常的 bootloader (uboot)。

对于 MTK 平台,其 bootloader 分为两个部分 
1. preloader ,依赖平台 
2. LK(little kernel),作用和 uboot 类似,依赖操作系统,负责引导 linux 系统和 Android 框架

我们结合前面的那张图,更加详细的看一下启动过程中 Bootloader 部分的动作: 
1. 设备上电,BootROM 开始运行。 
2. BootROM 初始化软件堆栈 (SoftwareStack)、通信端口和可引导存储设备(NAND/EMMC)。 
3. BootROM 从存储器中加载 pre-loader 到内部 SRAM(ISRAM)中,因为这时候还没有初始化外部的 DRAM。 
4. BootROM 跳转 pre-loader 入口并执行。 
5. pre-loader 初始化 DRAM 并加载 u-boot 到 RAM中 
6. pre-loader 跳转到 u-boot 中执行,u-boot 开始做初始化,比如显示初始化 
7. u-boot 从存储器中加载引导镜像(boot image)包括 linux kernel 和 ramdisk 
8. u-boot 跳转到 linux kernel 并执行。

2.1 preloader 启动过程
2.1.1 preloader 的功能
负责在芯片组平台准备好可执行环境
如果检测到外部工具,会试图通过 uart 或者 usb 与外部工具握手
从 NAND/EMMC 加载 u-boot ,并跳转到 u-boot
使用工具握手,设备能够触发进入下载模式来下载需要的镜像,或是进入工厂/测试模式,比如 META 模式和 ATE 工厂模式,在这些模式下可以测试模块,或是通过传递引导参数给 U-Boot 和 linux kernel 来校准设备 (device calibration)
preloader 中的硬件部分
PLL 模块 
调整处理器和外部内存频率。PLL 模块初始化后,处理器和外部内存的频率由 26MHZ/26MHZ 增加到 1GHZ/192MHZ。

UART 模块 
用于调试或是 META 模式下的握手。 
默认情况下 UART4 初始化波特率为 9216000bps ,用于调试信息输出。 
UART1 初始化为 115200bps 和作为 UART META 默认端口。不过 UART1 也可以被作为调试或者是 UART META 端口。

计时器 timer 模块 
用于计算硬件模块所需要的延时或是超时时间。

内存模块 
preloader 由 bootROM 加载和芯片组内部的 SRAM 中执行,因为外部的 DRAM 还没有初始化。 
接下来 preloader 采用内置的内存设置来初始化 DRAM,这样 u-boot 就可以被加载到 DRAM 中并执行。

GPIO

PMIC

RTC 
当通过 power 按键开机后,preloader 拉高 RTC 的 PWBB 来保持设备一直有电,并继续引导 u-boot。 
RTC alarm 可能是设备开机的启动源,这种情况,设备不需要按 power 按键就可以自启动。

USB

NAND

MSDC 
pre-loader 可以从 NAND Flash 或者是 EMMC 中加载 u-boot,两种选其一

2.1.2 preloader 启动代码
代码流程如下图:

2.2 LK 启动过程
LK (Little Kernel)也是一种 bootloader ,作用和 u-boot 差不多。 
MTK它由 preloader 引导并执行,因为 preloader 中已经完成了硬件模块,所以不需要在 lk 中重新配置这些模块了。但部分模块会在 lk 中重新被复位来配置硬件寄存器,这样可以创造一个干净的环境。比如计时器模块,在 lk 中,timer 被重新复位清零硬件计数来对计时进行复位。

2.2.1 LK 中的上电情景
LK 加载后,电池将检查 power 按键是否按下, 
如果当前启动的原因是 USB 充电器,而不是 power 按键,电池模块将等待用户按下 power 按键启动;

// lk/platform/mt6735/mtk_key.c
BOOL mtk_detect_key(unsigned short key)  /* key: HW KeyCode */
1
2
key 表示要检查的按键码,返回值表示这个按键是否按下,此函数来判断指定的按键是否按下。

2.2.2 LK 中的充电情景


2.2.3 LK 中的其他启动模式

 Factory mode 
出厂模式,用于批量生产

META mode 
META 模式,用于批量生产的功能性测试

Advanced META mode 
META 高级模式,用于批量生产时的功能性测试,用以测试多媒体功能,和 android 启动共存 
恢复模式,用于 SD 卡镜像升级

ATE Factory boot 
自动测试环境出场模式。通过 PC 的 ATE 工具发送命令测试产品特性。

Alarm boot 
RTC 闹钟启动

Fastboot 
刷机

download boot 
下载时,支持 logo 显示

sw reboot 
启动原因是重启

2.2.4 LK 启动代码
代码流程如下图:

lk/arch/arm/crt0.S

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();  // 使能 MMU、cache

        // do any super early platform initialization
        platform_early_init();  // 使能 Uart、中断、定时器、DRAM Banks、wot、display

#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_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));

        // enable interrupts
        exit_critical_section();

        // become the idle thread
        thread_become_idle();
#else
        bootstrap_nandwrite();
#endif
}

这里会创建一个 bootstrap2 线程

static int bootstrap2(void *arg)
{
        dprintf(SPEW, "top of bootstrap2()\n");

        arch_init(); // 空

        // XXX put this somewhere else
#if WITH_LIB_BIO
        bio_init();
#endif
#if WITH_LIB_FS
        fs_init();
#endif

        // initialize the rest of the platform
        dprintf(SPEW, "initializing platform\n");
        platform_init(); // 启动模式选择电池、显示 Logo、背光打开、设置软件的环境变量

        // initialize the target
        dprintf(SPEW, "initializing target\n");
        target_init(); // 空

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

        return 0;
}

apps_init //\bootable\bootloader\lk\app\app.c 
start_app 
mt_boot_init //bootable\bootloader\lk\app\mt_boot\mt_boot.c 
如果 g_boot_mode 为 FASTBOOT 就走 fastboot 模式 
否则 boot_linux_from_storage()

boot_linux_from_storage() 是关键 
char g_CMDLINE[200] = COMMANDLINE_TO_KERNEL;

这个 COMMANDLINE_TO_KERNEL 定义在 \lk\include\platform\mt_reg_base.h

 

三、Linux 内核启动

Linux 内核启动一般由外部 bootloader 引导,也可以在头部嵌入一个 loader,这部分和硬件结合紧密,一般由汇编编写。

3.1 zImage 解压
内核 zImage 解压缩 
head.S 首先初始化自解压相关的如内存等环境,接下来调用 decompress_kernel 进行解压(./arch/arm/boot/compressed/misc.c)

3.2 start_kernel 启动
start_kernel 启动内核(./init/main.c) 
start_kernel 是任何版本 Linux 内核的通用初始化函数,它会初始化很多东西,输出 Linux 版本信息、设置体系结构相关的环境,页表结构初始化,设置系统自陷入口,初始化系统 IRQ,初始化核心调度器等。 
最后调用 rest_init

3.3 rest_init 调用 kernel_init
启动 init 进程 
执行 schedule 开始任务调度。这个 init 是由 android 的 ./system/core/init 下的代码编译出来的,由此进入了 android 代码。
 


http://www.ppmy.cn/news/749218.html

相关文章

MTK 6737 android6.0 user版本打开root权限(adb root权限和 apk root权限)

系列文章 MTK 6735/6739/6755/6763 android8.1 user版本打开root权限(adb root权限和 apk root权限) 相比较 android8.1 而言,6.0 的要简单很多 1、首先 6.0 不需要关闭 DM-verity,只需开发 adb root 后就能成功 remount,对 system 分区 rw 操作 2、6.0 无需添加在 init…

mtk android高级工具,Android6.0 MTK6737 DCT 工具介绍 · Younix’s Studio

8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? OS:Android6.0 Hardware:MTK6737 [TOC] MTK 的 DCT Driver Customization Tool MTK 为 GPIO、I2C 等配置制作了一个工具叫做 DCT , 可以直接在 UI 里…

MTK6737功能展示

MT6737核心板处理器: QL168(6737) 具备低功耗特色的四核系统单芯片,是一款4G LTE 主要针对移动、联通、电信版本的全网通模块,SMT 封装。其性能稳定,外形紧凑,性价比高,功能强大&am…

android 7.0 MTK MT6737 添加GT1XX TP驱动

1.kernel-3.18/arch/arm64/configs/ax6737_65_n_defconfig CONFIG_TOUCHSCREEN_MTK_GT1XXy.... #下发驱动 -#CONFIG_GTP_DRIVER_SEND_CFGy -#CONFIG_GTP_CUSTOM_CFGy CONFIG_GTP_DRIVER_SEND_CFGy CONFIG_GTP_CUSTOM_CFGy#CONFIG_GTP_HOTKNOTy -#CONFIG_GTP_AUTO_UPDATEy -#CO…

Ubuntu16.04搭建mtk6737 安卓7.0 MTK 编译环境搭建

安装Ubuntu16.04 安装远程ssh 安装java 8 sudo apt-get update sudo apt-get install openjdk-8-jdk java -versionsudo apt-get install git-core gnupg flex bison ccache gperf libsdl1.2-dev libesd0-dev libwxgtk2.8-dev build-essential zip curl libncurses5-dev zlib1…

MT6737芯片功能介绍+MT6737芯片资料分享

MT6737芯片功能介绍MT6737芯片资料分享 MT6737是什么呢? MT6737是联发科技极具成本效益的R.9 Cat-4 LTE解决方案,不但能将模块及内存成本降至最低,符合中低端市场需求,同时具备超越同级产品的性能与电源效能表现。此外,MT6737能…

MT6737模块编译方法

前提是提前编译整个系统。 Preloader模块: rm -rf out/target/product/len6737t_66_sh_n/obj/PRELOADER_OBJ 编译命令变为:(不再是PDF文档的命令) mmm vendor/mediatek/proprietary/bootable/bootloader/preloader:pl 编译成…

MT6737芯片尾缀资料介绍

MT6737处理器还是比较新的,大家说说它一共有哪几种尾缀型号? 在这里,我呢,就用一张图表示吧。 这样看,大家都明白了解了吧。它的每种型号的性能都不一样,有比 MT6737性能强的 ,也有比它弱的。不…

MTK芯片平台,MT6737烧录工具资料(SP_Flash_Tool_exe_Windows_v5.1712.00.000)

MTK芯片平台,MT6737烧录工具资料分享,希望能对开发者有所帮助。 资料下载,可到我的下载资源界面下载,也可点击下载(MT6737) 另外,附送 一份MT6737的规格书资料----MT6737 datasheet MT6737是联发科技极具成本效益的R.9 Cat-4 LT…

MT6737核心板资料,MT6737芯片模块性能介绍

MT6737核心板资料 全网通8核联发科MTK6755核心板MT6755主板物联网方案LTE模块 http://bbs.16rd.com/shop_product-2-9.html MT6737参数规格: 主频架构:2.0GHz,八核ARM Cortex-A53 系统:Android 6.0 网络: GSM/ED…

MT6737芯片平台处理器功能介绍资料

MT6737处理器: 简介: MT6737是联发科技极具成本效益的R.9 Cat-4 LTE解决方案,不但能将模块及内存成本降至最低,符合中低端市场需求,同时具备超越同级产品的性能与电源效能表现。此外,MT6737能在全球范围内…

mt6737充电不满

MT6737 高压电池 开机充电充到96% 之后就充不了电了 关机量电池电压为4.24v 请问这怎么解?详细资料,请到一牛网论坛阅读(可搜索MT6737阅读)答案链接:http://bbs.16rd.com/thread-455417-1-1.html

Selenium自动化的JUnit参数化实践

目录 前言 为什么需要JUnit参数化测试? JUnit参数化的类型 使用Parameters批注进行参数化 使用Excel进行参数化 总结: 前言 作为自动化测试人员,经常会遇到这样Selenium测试自动化场景:需要一次又一次地执行相同的测试用例&a…

java 接口中的方法只能是抽象的吗?

抽象方法,没有方法体,可以省略public和abstract的修饰符 接口中除了抽象方法,还可以有: 默认方法(default)【jdk8 新特性】静态方法(static)【jdk8 新特性】私有方法(private)【jdk9…

给手机充电时,边充边玩会爆炸?夸大其词哗众取宠

手机界谣言之一就是说给手机充电的时候会爆炸,这种说法其实是夸张了,只不过是别人想得到关注点,夸大其词来哗众取宠。那么到底正解的答案是什么呢?下面我们来了解一下。 首先,手机充电的时候,检查一下看看你…

爆炸三角形如何用计算机实现,爆炸三角形原理

原标题:爆炸三角形原理 国家石油化学工业的高速发展为企业带来巨大经济效益与社会效益的同时,各种安全隐患及事故也随之不断产生,给社会带来了极大的危害。作为保护生产安全的设备——— 安全栅 ,以前只在重要的场合应用, 现在已经…

智能爆炸的真实(上)

在人工智能的流行度因为前一年alphaGO登顶围棋高峰而如火如荼的2017年,Franois Chollet (人工智能专家,Keras的创建者)在Medium上发出一篇长文,详细反驳了当时许多带节奏的自媒体宣扬的跨过“奇点”后的“智能爆炸”威…

智能爆炸的真实(下)

前面说到,智能技术的发展的前提是要搞清智能的本质,以及什么东西支撑了一个智能体的运行。所以我并不是在反驳Chollet的观点,而是列出了一些为了搞清楚智能原理,值得深入探讨的问题。 虽然距离我们搞清楚这种本质和核心规律可能还…

锂电池为啥会爆炸

前段时间,三星公司的旗舰智能手机GalaxyNote 7一直牢牢占据着新闻头条,这倒不是因为它的性能或是设计有多么出众(当然Note7的性能和设计的确很好),而是因为其在上市后的短时间内,即被发现内置电池存在重大安…

汽油车是否会爆炸

汽车燃烧导致油箱爆炸,这是影视剧中常常出现的镜头。大家还记得《速度与激情》电影里汽车爆炸的场景吗?震撼!惊险!元贝驾考小编默默的告诉大家:真想只有一个!大家都被电影骗了!不信?…