备注:
META mode:Mobile Engineering Test Architecture,移动工程师测试架构
ATE factory mode:automatic test environment,自动测试环境
ISRAM:internal system RAM
SPU:
MP:mass product,批量生产
DSI:display serial interface,显示串行接口--->high speed serialIF
DPI:display pixel interface,显示像素接口--->RGB IF
DBI:display bus interface,显示总线接口,也就是通常所讲的MCU接口,俗称80 system接口--->CPU BUS IF
MTD(memorytechnology device内存技术设备)是用于访问memory设备(ROM、flash)的Linux的子系统。
MSDC:memory stick and SD card controller,记忆棒和SD卡控制器
Bootloader能够准备一个至关重要的执行环境和引导linux操作系统及Android框架(framework)。
bootloader主要包括设置处理器和内存的频率、调试信息端口、可引导的存储设备等等。在可执行环境创建好之后,接下来把software装载到内存并执行。除了装载software,一个外部工具也能和bootloader握手(handshake),可指示设备进入不同的操作模式,比如USB下载模式和META模式。就算没有外部工具的握手,通过外部任何组合或是客户自定义按键,bootloader也能够进入这些模式。
因为bootloader的一部分和系统有关,所以MTK为了不同的应用将它分为两部分的bootloader:
(1) 第1部分bootloader,也就是MTK内部(in-house)的pre-loader,这部分依赖平台。
(2) 第2部分bootloader,也就是u-boot,这部分依赖操作系统,负责引导linux操作系统和Android框架。
1. U-Boot源代码
1.1 源代码目录
(1) xxx\bootable\bootloader\uboot
图1
1) arch
主要包括CPU具体信息,比如cpu.c、start.s(U-Bboot从这个文件开始启动)等。
Arch\arm\lib目录
文件 | 描述 |
Bootm.c | Boot memory,包含do_nand_boot的函数原型。 |
Board.c | 包含start_armboot()的实现 |
Arch\arm\cpu\arm_cortexa9
文件 | 描述 |
Start.s | U-Boot的入口,U-Boot从这个文件开始。 |
2) drivers
各种设备驱动程序,比如MTD、usbtty等等。
3) fs
文件系统目录和源代码,比如fat、yaffs2等等。
4) include
不同的头文件,include/configs包含了所有不同板的配置。
(2) xxx\mediatek\platform\mt6577\uboot
mediate BSP的uboot部分、驱动/模块代码、inc目录下的头文件。
文件 | 描述 |
lowlevel_init.s | 软件堆栈的底层设置(low level)和一些SPU设置 |
mt65xx_leds.c | U-Boot LED模块 |
mt6577.c | 提供基本的MT6577硬件环境 |
mt6577_bat.c | U-Boot电池模块 |
mt6577_board.c | 包含模块初始化入口 |
disp_assert_layer.c | LCM模块使用的一些显示相关函数,主要是表现层(assert layer) |
disp_drv.c | 显示驱动主控部分 |
disp_drv_dbi.c | 显示驱动的dbi接口控制部分 |
disp_drv_dpi.c | 显示驱动的dpi接口控制部分 |
disp_drv_dsi.c | 显示驱动的dsi接口控制部分 |
dpi_drv.c | 被disp_drv.c调用了实现dpi接口的功能 |
dsi_drv.c | 被disp_drv.c调用了实现dpi接口的功能 |
mt65xx_disp_drv.c |
|
mt6577_factory.c | 生产模式的支持 |
mt6577_gpio.c | U-Boot GPIO模块 |
mtk_key.c | U-Boot的按键模块 |
lcd_drv.c | U-Boot的LCM模块 |
mt65xx_disp_drv.c |
|
boot_mode.c | 处理加载镜像的过程 |
mt6577_meta.c | META模式支持 |
boot_mode.c | 模式检测入口 |
mt6577_nand.c | U-BOOT NAND模块的MTD支持 |
mt6577_pmic6329.c | U-Boot PMICmok |
mt6577_recovery.c | Recovery模块支持 |
mt6577_rtc.c | U-Boot RTC模块 |
Msdc.c | U-Boot MSDC模块 |
mtk_serial.c | 串口相关函数 |
mtk_timer.c | U-Boot计时器啊哈念书 |
mtk_wdt.c | U-Boot看门狗模块 |
Bmt.c | Boot memory table,NAND页表(page table) |
|
|
|
|
(3) xx\mediatek\custom\hsimobile77_ics2\uboot
uboot的自定义文件(custom files)。
1.2 编译命令
Pre-loader单独的编译命令:./mk <$PROJECT> n pl
U-Boot单独的编译命令:./mk <$PROJECT> n ub
2. bootloader的工作流程
2.1 bootloader正常的启动流程
先来看启动流程图:
图2
正常启动的主要工作如下:
(1) 设备上电后,Boot ROM开始运行。
(2) BootROM初始化软件堆栈(software stack)、通信端口和可引导存储设备(比如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内核和ramdisk(Android呢?)
(8) U-Boot跳转到linux内核并执行。
2.2 bootloader正常的下载流程
先来看正常的下载流程图:
图3
正常的下载主要工作如下:
(1) 设备上电后,Boot ROM开始运行。
(2) BootROM初始化软件堆栈(software stack)、通信端口和可引导存储设备(比如NAND/EMMC)。
(3) BootROM通过UART/USB和flash工具握手。
(4) BootROM通过UART下载pre-loader镜像到NAND flash/EMMC中,然后重启。
(5) BootROM加载pre-loader到内部SRAM汇总,因为DRAM还没有初始化。
(6) BootROM跳转到pre-loader并执行。
(7) Pre-loader初始化DRAM和通过USB与flash工具握手。
(8) Pre-loader通过USB下载其余镜像文件,比如U-Boot、boot image、recovery image、android system image、user data到NAND FLASH/EMMC中。
2.3 Bootloader备用的下载流程(emergency download procedure)
(1) 设备上电后,Boot ROM开始运行。
(2) BootROM初始化软件堆栈(software stack)、通信端口和可引导存储设备(比如NAND/EMMC)。
(3) BootROM在emergency DL按键按下后,通过USB和flash工具握手。
(4) BootROM通过USB把指定的镜像文件下载到NAND FLASH/EMMC中。
3. pre-loader的功能
4. Bootloader硬件环境
当设备上电后,bootloaders被加载到不同的内存区域并执行,如下图所示:
图4
Pre-loader在芯片内部系统(chipset’s internal system)RAM的0Xc2010000位置开始执行,U-Boot在外部RAM的0x01E00000处执行。当bootloaders执行时,初始化多种硬件模块来创建一个可执行的环境,具体是哪些硬件模块,下面有详细的描述。
4.1 U-Boot中涉及的硬件部分
U-Boot是第2个loader,它由pre-loader引导并执行。从根本上来说(basically),pre-loader已经初始化了相关的硬件模块,而不需要在U-Boot中重新配置这些模块了。但一些模块在U-Boot中被重新复位来配置硬件寄存器,这样可创造一个干净的环境。比如计时器模块,在U-Boot中,计时器重新复位清零硬件计数来对计时进行复位。所有在U-Boot中需要初始化的列在下面:
(1) 计时器模块
通过复位硬件寄存器来复位计时。
(2) 串口模块
U-Boot采用串口模块来配置它的输入/输出系统,在这个模块初始化后,我们可以使用U-Boot提供的“printf(…)”等函数来使用串口功能。
(3) I2C模块
(4) PWM模块
(5) PMIC模块
(6) RTC模块
和计时器模块一样,在U-Boot中,I2C/PMIC/RTC重新复位寄存器来复位这些模块。
(7) LED模块
通过这power off charging个模块,设备能够通知用户当前的充电状态。
(8) 充电模块
这个模块负责关机充电(power off charging)、低电压充电(lower charging in the system)。
(9) LCD模块
使用这个模块,设备能够显示logo或是任何通知的消息。
(10) NAND模块
因为U-Boot也需要从flash读取镜像(比如内核或是ramdisk),所以有必要在U-Boot中初始化NAND相关的功能。
(11) MSDC模块
支持MSDC启动
5. U-Boot的过程(procedure)和流程(flow)
5.1 U-Boot的开始程序(starting procedure)
图5
5.2 U-Boot的主程序(main procedure)
图6
这部分主要是执行寄存器初始化功能,下面涉及nand初始化、引导模式选择并跳转到死循环函数中main_loop。
图7
5.3 U-Boot的命令程序(command procedure)
图8
6. U-Boot的接口
6.1 上电情景(power on scenario)---长按启动(long press to boot)
当启动U-Boot,电池将检查是否有power按键已按下,如果当前的启动原因是USB充电器,而不是按power按键,电池模块将等待用户按下power按键来启动(请注意,如果充电器插入,设备会自动上电,这是因为RTC PWBB由HW自动锁存)
boolmt6577_detect_key(unsigned short key)
参数key表示要检查的按键码,返回值表示这个按键是否按下,此函数来判断指定的按键是否按下,此函数在xxx\mediatek\platform\mt6577\uboot\mt6577_key.c定义,power按键的按键码为0x08。
6.2 启动充电情景(boot charging scenario)
图9
6.3 U-Boot模式选择情景(mode selection scenario)
U-Boot支持3种主要的启动模式:
(1) 出厂/原厂模式(Factory mode)
用于批量生产(mass product)时的出厂测试。
(2) META模式(移动工程师测试架构模式)
用于批量生产时功能性测试。
(3) 恢复模式(recovery mode)
用于SD卡镜像升级(upgrade)(这是由Android提供的镜像升级方案,用户能够从SD卡升级Android系统镜像)。
(4) 高级的META模式(Advanced META mode)
批量生产时的功能性测试(不像META模式,这种模式和正常的android启动共存,一般用来测试多媒体功能)。
(5) 自动测试环境出厂模式(ATE Factory boot)
通过PC端的ATE工具发送命令来测试产品的特性(feature)。
(6) 闹钟启动(Alarm boot)
启动的原因是RTC闹钟。
6.4 一些重要的结构体或是寄存器
(1) MT6577启动类型定义
- /* MT6577 boottype definitions */
- typedef enum
- {
- NORMAL_BOOT = 0,
- META_BOOT = 1,
- RECOVERY_BOOT = 2,
- SW_REBOOT = 3,
- FACTORY_BOOT = 4,
- ADVMETA_BOOT = 5,
- ATE_FACTORY_BOOT = 6,
- ALARM_BOOT = 7,
- UNKNOWN_BOOT
- } BOOTMODE;
(2) 记录当前启动模式的全局变量(默认为正常启动)
- // global variablefor specifying boot mode (default = NORMAL)
- BOOTMODEg_boot_mode = NORMAL_BOOT;
7. U-Boot增加新的启动模式(boot mode)
我们可以通过下面的步骤来增加新的启动模式:
(1) 增加新的启动模式定义
比如:
- typedef enum
- {
- NORMAL_BOOT = 0,
- META_BOOT = 1,
- RECOVERY_BOOT = 2,
- SW_REBOOT = 3,
- FACTORY_BOOT = 4,
- ADVMETA_BOOT = 5,
- ATE_FACTORY_BOOT = 6,
- ALARM_BOOT = 7,
- NEW_BOOT = 8,
- UNKNOWN_BOOT
- } BOOTMODE;
(2) boot_mode_select()函数增加新的检查函数(check function)
比如:
- // check the bootmode : (1) meta mode or (2) recovery mode ...
- voidboot_mode_select(void)
- {
- #ifdef CFG_META_MODE
- if (meta_detection())
- {
- return;
- }
- #endif
- #ifdef CFG_FACTORY_MODE
- if (factory_detection())
- {
- return;
- }
- #endif
- #ifdef CFG_RECOVERY_MODE
- if(recovery_detection())
- {
- //**************************************
- //*CHECK IMAGE
- //**************************************
- if(DRV_Reg32(0x40002300)==0xE92D4800)
- {
- printf(" > do recovery_check\n");
- //jump(0x40002300);
- }
- else
- {
- printf(" > bypassrecovery_check\n");
- }
- return;
- }
- #endif
- if(new_mode_detection())
- {
- return;
- }
- }
(3) 如果检测到这个新的启动模式,需要填充全局启动模式变量的值
比如:
- g_boot_mode = NEW_BOOT;
(4) U-Boot将自动创建一个引导标记(boot tag)和传递这个引导模式号给linux内核。