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

article/2025/11/3 15:17:40

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

属于 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 的功能

  1. 负责在芯片组平台准备好可执行环境
  2. 如果检测到外部工具,会试图通过 uart 或者 usb 与外部工具握手
  3. 从 NAND/EMMC 加载 u-boot ,并跳转到 u-boot
  4. 使用工具握手,设备能够触发进入下载模式来下载需要的镜像,或是进入工厂/测试模式,比如 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 */

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 contextthread_init_early();// early arch stuffarch_early_init();  // 使能 MMU、cache// do any super early platform initializationplatform_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 initializationtarget_early_init(); // 空,可以在这里实现一些定制的超级初始化dprintf(INFO, "welcome to lk\n\n");// deal with any static constructorsdprintf(SPEW, "calling constructors\n");call_constructors();// bring up the kernel heapdprintf(SPEW, "initializing heap\n");heap_init();// initialize the threading systemdprintf(SPEW, "initializing threads\n");thread_init();// initialize the dpc systemdprintf(SPEW, "initializing dpc\n");dpc_init();// initialize kernel timersdprintf(SPEW, "initializing timers\n");timer_init();#ifdef  MTK_LK_IRRX_SUPPORTmtk_ir_init(0);
#endif#if (!ENABLE_NANDWRITE)// create a thread to complete system initializationdprintf(SPEW, "creating bootstrap completion thread\n");thread_resume(thread_create("bootstrap2", &bootstrap2, NULL, DEFAULT_PRIORITY, DEFAULT_STACK_SIZE));// enable interruptsexit_critical_section();// become the idle threadthread_become_idle();
#elsebootstrap_nandwrite();
#endif
}

这里会创建一个 bootstrap2 线程

static int bootstrap2(void *arg)
{dprintf(SPEW, "top of bootstrap2()\n");arch_init(); // 空// XXX put this somewhere else
#if WITH_LIB_BIObio_init();
#endif
#if WITH_LIB_FSfs_init();
#endif// initialize the rest of the platformdprintf(SPEW, "initializing platform\n");platform_init(); // 启动模式选择电池、显示 Logo、背光打开、设置软件的环境变量// initialize the targetdprintf(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://chatgpt.dhexx.cn/article/PRvEZC8G.shtml

相关文章

4G全网通MTK6737开发板-安卓核心板通信LTE模块方案

新移科技的XY001开发板(安卓智能核心板评估套件),主要用于新移科技3G/4G/5G智能核心板的功能开发与测试。适用:XY6761、XY6853、XY8735 、XY6580、 XY6762、XY6763、XY6765、XY6771、XY8788 、XY6737全系列核心板。 核心板产品介绍: MT6737…

MTK6737功能展示

MT6737核心板处理器: QL168(6737) 具备低功耗特色的四核系统单芯片,是一款4G LTE 主要针对移动、联通、电信版本的全网通模块,SMT 封装。其性能稳定,外形紧凑,性价比高,功能强大,拥有良好的可扩展性和设计灵活性,能适用于各种产品设计需求 模块内置64 位4 核A53 架构…

HTML+CSS做登录注册界面

在登录界面点注册会进入注册界面 登录界面代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title></head> <body><div style"width:500px;float: …

HTML+CSS 登录界面设计

一、界面源代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>登录</title><style>bo…

HTML(css+div)登录界面

&#xff08;1&#xff09;这是当时做的一个课程设计&#xff0c;很多人想要图片&#xff0c;在这里我把用到的所有图片资源分享下 &#xff08;2&#xff09;链接&#xff1a;https://pan.baidu.com/s/1nUX1DQe_aDZQMf2Zbblm_A 提取码&#xff1a;twcp <!doctype…

HTML登录界面的实现详解

前言序锦 https://blog.csdn.net/HuaCode/article/details/81413387前阵子参加学校的暑期实习&#xff0c;我作为项目负责人&#xff0c;除了进行统筹规划&#xff0c;整体运营以及进度安排等工作外呢&#xff0c;我还负责了前端模块&#xff0c;参与并编写了前端页面&#xff…

html后台登录界面网页设计界面

一款简单的html后台登录界面网页设计界面带给大家。 效果图&#xff1a; html代码&#xff1a; <!DOCTYPE html> <html> <head><title>某某公司后台登录系统</title><link rel"stylesheet" href"css/style.css">&l…

HTML 实现好看的登录注册界面(一)

1. 效果图展示 2. 代码 2.1 HTML部分 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name"viewport" con…

HTML制作用户登录界面

1、index代码 <!doctype html> <html><head><meta charset"utf-8"><title>login</title><link rel"stylesheet" type"text/css" href"css/index.css"/></head><body><div&…

登录界面html源代码_网页制作:一个简易美观的登录界面

登录界面html源代码_网页制作&#xff1a;一个简易美观的登录界面 效果图 在我们做一个页面之前&#xff0c;要先想好他的一个整体布局&#xff0c;也就是我们这里面的login.html主页面&#xff0c;大致结构如下&#xff1a; 接下来&#xff0c;我们先上代码&#xff0c;看一…

HTML+CSS登陆界面实例

登录界面截图 项目代码仓库地址 项目的代码放在了github的代码仓库当中&#xff1a;点我 项目访问地址 将登录界面项目部署在了github上面&#xff1a;点我 项目代码解析 项目的界面简析 主要部分是Login的模块&#xff0c;包括username文本框和password文本框以及Login的…

HTML+CSS登录注册界面

目录 一、效果演示二、代码实现2.1、HTML主页面2.2、CSS代码2.3、JS代码 一、效果演示 [注]: 这里需要我们创建三个文件&#xff0c;一个是index.html文件&#xff0c;一个是style.css文件还有一个是login.js文件&#xff0c;把代码copy上去 只要路径找好就能正常运行了。 演示…

HTML+CSS登录界面

今天学习了一个HTML+CSS登录界面 效果图如下: 背景图片可以选取自己喜欢的,以下是实现代码: login.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> <link rel="stylesheet&quo…

HTMLCSS登录界面及讲解

PS:该源码非原创&#xff0c;原文章来自(2条消息) HTMLCSS登录界面_桐艾的博客-CSDN博客_登录页面 这里只做源码讲解 页面效果如下&#xff1a; 首先是login.html <!DOCTYPE html> <html> <head> <meta charset"UTF-8"> <title>登…

好看的html登录界面,

界面效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html><head><title>Login Page</title><style>body {background-color: #f2f2f2;font-family: Arial, sans-serif;}form {background-color: #fff;border-radius: 5px;box-shado…

HTML简单登录界面的实现

简单登录界面的实现&#xff1a; 直接一个实例上代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"&…

html好看的登录界面2(十四种风格登录源码)

文章目录 1.登录风格效果说明1.1 凹显风登录界面1.2 大气简洁风登录界面1.3 弹出背景风登录界面1.4 动态左右切换风登陆界面1.5 简洁背景切换登录界面1.6 可关闭登录界面1.7 蒙蒙山雨风登录界面1.8 苹果弹框风登录界面1.9 上中下青春风登录界面1.10 夏日风登录界面1.11 星光熠熠…

html+css唯美登录页面,代码提供(效果展示)

文章目录 效果图所有代码 效果图 所有代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" co…

使用 ELK 收集日志

在当前分布式、微服务架构下&#xff0c;各个应用都部署在不同的服务器上&#xff0c;每个应用都在记录着自己重要或者不重要的日志信息。当我们要通过日志信息来排查错误时&#xff0c;可以根据出错应用在对应的机器上找报错相关的日志信息。但是&#xff0c;可能我们不具有相…

ELK日志分析

目录 一、概述 ELK工作原理 二、Elasticsearch 1.介绍 2.基础核心概念 (1)接近实时&#xff08;NRT&#xff09; (2)集群&#xff08;cluster&#xff09; (3)节点&#xff08;node&#xff09; (4)索引&#xff08;index&#xff09; (5)类型&#xff08;type&…