在aboot.c 中
APP_START(aboot)
.init = aboot_init,
APP_END
会为aboot_init new 一个thread(前面已经讲过了)
void aboot_init(const struct app_descriptor *app)
{
if (keys_get_state(KEY_BACK) != 0)
goto fastboot;

boot_linux_from_flash();
dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
"to fastboot mode.\n");

fastboot:
}

这个函数首先判断用户是否按下back key,如果按下就进入fastboot ,否则就从flash上copy bootimg到dram中。其中fastboot 中有个continue的命令也是调用boot_linux_from_flash 来从flash上将booting copy到dram。
fastboot_register("continue", cmd_continue);
void cmd_continue(const char *arg, void *data, unsigned sz)
{
boot_linux_from_flash();
}
看到了吧
我们继续看boot_linux_from_flash

int boot_linux_from_flash(void)
{
struct boot_img_hdr *hdr = (void*) buf;
unsigned n;
struct ptentry *ptn;
struct ptable *ptable;
unsigned offset = 0;
const char *cmdline;

首先得到flashlayout
ptable = flash_get_ptable();
if (ptable == NULL) {
dprintf(CRITICAL, "ERROR: Partition table not found\n");
return -1;
}
从flashlayout 中找到boot partition
ptn = ptable_find(ptable, "boot");
if (ptn == NULL) {
dprintf(CRITICAL, "ERROR: No boot partition found\n");
return -1;
}
先读取bootimg 2k的head
if (flash_read(ptn, offset, buf, 2048)) {
dprintf(CRITICAL, "ERROR: Cannot read boot image header\n");
return -1;
}
offset += 2048;
看bootimg是否有Android这个字样
if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
dprintf(CRITICAL, "ERROR: Invaled boot image heador\n");
return -1;
}
从bootimg中的得到kernel size
n = ROUND_TO_PAGE(hdr->kernel_size);
if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) {
dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
return -1;
}
offset += n;

从bootimg中的得到ramdisk size,并copy到dram中

n = ROUND_TO_PAGE(hdr->ramdisk_size);
if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, n)) {
dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
return -1;
}
offset += n;

dprintf(INFO, "\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr,
hdr->kernel_size);
dprintf(INFO, "ramdisk @ %x (%d bytes)\n", hdr->ramdisk_addr,
hdr->ramdisk_size);

检查bootimg中是否包含cmdline

if(hdr->cmdline[0]) {
cmdline = (char*) hdr->cmdline;
} else {
cmdline = DEFAULT_CMDLINE;
}
dprintf(INFO, "cmdline = '%s'\n", cmdline);

/* TODO: create/pass atags to kernel */

dprintf(INFO, "\nBooting Linux\n");
boot_linux((void *)hdr->kernel_addr, (void *)TAGS_ADDR,
  (const char *)cmdline, LINUX_MACHTYPE,
  (void *)hdr->ramdisk_addr, hdr->ramdisk_size);

return 0;
}

调用boot_linux 继续boot kernel
void boot_linux(void *kernel, unsigned *tags, 
const char *cmdline, unsigned machtype,
void *ramdisk, unsigned ramdisk_size)
{
unsigned *ptr = tags;
给entry赋值,就等于hdr->kernel_addr。
void (*entry)(unsigned,unsigned,unsigned*) = kernel;
struct ptable *ptable;

/* CORE */
*ptr++ = 2;
*ptr++ = 0x54410001;

传递ramdisk 给的size 和 address 给kernel,其中0x54410001是个magic number.

if (ramdisk_size) {
*ptr++ = 4;
*ptr++ = 0x54420005;
*ptr++ = (unsigned)ramdisk;
*ptr++ = ramdisk_size;
}

传递flashlayout给kernel,其中0x4d534d70是个magic number.

if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
int i;
*ptr++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
      sizeof(unsigned)));
*ptr++ = 0x4d534d70;
for (i = 0; i < ptable->count; ++i)
ptentry_to_tag(&ptr, ptable_get(ptable, i));
}

传递(cmdline 给kernel,类似uboot的bootargs 。其中0x54410009是个magic number.

if (cmdline && cmdline[0]) {
unsigned n;
/* include terminating 0 and round up to a word multiple */
n = (strlen(cmdline) + 4) & (~3);
*ptr++ = (n / 4) + 2;
*ptr++ = 0x54410009;
memcpy(ptr, cmdline, n);
ptr += (n / 4);
}

/* END */
*ptr++ = 0;
*ptr++ = 0;

dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d)\n",
kernel, ramdisk, ramdisk_size);
if (cmdline)
dprintf(INFO, "cmdline: %s\n", cmdline);

enter_critical_section();
platform_uninit_timer();
关掉cache和mmu
arch_disable_cache(UCACHE);
arch_disable_mmu();
调到entry开始执行kernel,传递三个参数,第一个固定为0,第二个machtype被定义成LINUX_MACHTYPE,一般在对应平台的init.c中定义,第三个参数tags,就是传给给kernel的参数.
entry(0, machtype, tags);
}

lk boot bootimg相关推荐

  1. MTK 驱动(67)---深入MTK平台bootloader启动之【 lk -amp;gt; kernel】分析笔记

    Pre-loader 运行在ISRAM,待完成 DRAM 的初始化后,再将lk载入DRAM中,最后通过特殊sys call手段实现跳转到lk的执行入口,正式进入lk初始化阶段. 一.lk执行入口: 位 ...

  2. 深入MTK平台bootloader启动之【 lk -> kernel】分析笔记

    接上一篇分析: <深入MTK平台bootloader启动之[ Pre-loader -> Lk]分析笔记> Pre-loader 运行在ISRAM,待完成 DRAM 的初始化后,再将 ...

  3. Android OrangePi 4G IOT(四) - MTK LK分析

    一.MTK启动流程 1-3:设备上电起来后,跳转到Boot ROM(不是flash)中的boot code中执行把pre-loader加载起到ISRAM, 因为当前DRAM(RAM分SRAM跟DRAM ...

  4. 《最强Android书 架构大剖析》读书笔记

    文章目录 第一章 Android 体系结构的变革之路 1.2 Android系统源码目录 与Linux的异同 Android的框架 原生二进制可执行文件 Android 的原生库 核心(core)库 ...

  5. Android Nand Flash 分区

    一般的嵌入式Linux开发人员是要清晰区分不同器材的作用和名称的.比如系统,内核所有保存在Nand Flash之上,断电后仍然存在,而运行后程序是装入SDRAM或Mobile DDR之类的内存设备运行 ...

  6. MTK 驱动开发(5)---bootloader

    1.框架 MTK 平台的启动过程经过四个模块,分别是BootRom,Preloader,LK,Kernel. 2 .bootloader到kernel启动总逻辑流程图 3.Boot ROM Boot ...

  7. 高通msm8996启动流程

    摘自"80-nv396-1_c_msm8996_boot_and_corebsp_architecture_overview.pdf" 系统上电并且把Kryo应用处理器退出rese ...

  8. 什么是Android性能,如何分析性能问题?

    我们常说的性能通常包括如下几个方面 1.应用的启动速度 这个无论是基于用户体验的角度还是基于产品 宣传的角度这个越来越受到主流厂商的重视: a.基于用户体验的角度,这一点不难理解,随着手机硬件的不断升 ...

  9. mtk log系统详解

    Log总览 Android Log Android java层和native层 log main log.system log.radio log.event log Kernel Log Linux ...

最新文章

  1. fastDFS同步问题讨论
  2. AOP的两种实现方式
  3. boost::mpi::cartesian_communicator相关用法的测试程序
  4. 23 | 基础篇:Linux 文件系统是怎么工作的?
  5. w3m linux,Linux 终端浏览器 w3m
  6. java执行程序默认多线程吗_Java多线程 执行程序(1)
  7. 19个AI热门应用领域,你确定不了解一下?
  8. CROC-MBTU 2012, Elimination Round (ACM-ICPC) H DP题目
  9. 命令行运行命令时报错You don#39;t have write permissions for the /Library/***
  10. Mysql rpm包安装
  11. Windows10升级失败怎么办?赶快用微软官方的升级工具:Windows10易升
  12. 【步步为赢】如何使用手机号码批量归属地查询分拣并且分类批量导出TXT文本EXCEL
  13. 雅虎 (YAHOO)相册下载工具 Beta1 发布
  14. nginx 加上ssl配置
  15. route和bridge是什么意思_桥接模式与路由模式区别
  16. SpringSecurity之CSRF漏洞保护
  17. 几何光学学习笔记(18)- 5.1光阑在光学系统中的作用
  18. TCP/IP详解:TCP——超时和重传
  19. 安装应用需要打开未知来源权限_OPPO手机未知来源权限在哪 OPPO手机未知来源权限设置方法...
  20. 2012最具有技术影响力本版图书评选

热门文章

  1. 遇到mybatis面试问题应该怎么回答
  2. 计算机语言里面的斜杠,编程中常见的斜杠(/和\)问题
  3. 正面管教读书笔记 01 正面的方法
  4. 「Java面试」将线程安全讲的如此清新脱俗:你对线程安全性的理解
  5. 【Fast RCNN】《Fast-RCNN》
  6. 痛定思痛,开启算法之路(一)
  7. servlet中init,service,destory方法描述
  8. C++ 负数转二进制形式
  9. 国际创新专题:含WDI、WGI、创新创业指数 - 更新至2020年
  10. clickhouse分析:zookeeper减压概述