u-boot版本:v2009.08

u-boot利用了env里的cmd来实现调用boot linux的接口, 效果等同于在u-boot中敲"booti xxx..."

start_armboot -> board_late_init:

int board_late_init(void)
{int ret = 0;
#ifdef MX6Q_SABRESD_ANDROID_Hswitch (get_boot_device()) {case SD_BOOT:if (!getenv("fastboot_dev"))setenv("fastboot_dev", "mmc2");/*本例的boot device是SD,并且device number是2*/if (!getenv("bootcmd"))setenv("bootcmd", "booti mmc2");break;
......}
#endif
......return 0;
}

start_armboot ->main_loop:

void main_loop (void)
{
....../*获取前面set的bootcmd,值是"booti mmc2"*/s = getenv ("bootcmd");debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");/*如果u-boot开机阶段没有收到按键事件,那么就去启动kernel*/if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
......
# ifndef CONFIG_SYS_HUSH_PARSER/*调用booti mmc2去boot linux*/run_command (s, 0);
# else
......
}

booti命令对应的定义如下:

U_BOOT_CMD(booti,    3,  1,  do_booti,"booti   - boot android bootimg from memory\n","[<addr> | mmc0 | mmc1 | mmc2 | mmcX] [<partition>] \n    - boot application image stored in memory or mmc\n""\t'addr' should be the address of boot image which is zImage+ramdisk.img\n""\t'mmcX' is the mmc device you store your boot.img, which will read the boot.img from 1M offset('/boot' partition)\n""\t 'partition' (optional) is the partition id of your device, if no partition give, will going to 'boot' partition\n"
);

do_booti:

int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
......if (mmcc != -1) {
#ifdef CONFIG_MMC
....../*获取device信息*/mmc = find_mmc_device(mmcc);if (!mmc) {printf("booti: cannot find '%d' mmc device\n", mmcc);goto fail;}
......
#ifdef CONFIG_ANDROID_BOOT_PARTITION_MMC
#ifdef CONFIG_ANDROID_RECOVERY_PARTITION_MMC/*开机可能是进入正常boot模式,也可以是进入recovery模式,取决于传进来的参数,本例是kernel*/if (!strcmp(ptn, "boot"))partno = CONFIG_ANDROID_BOOT_PARTITION_MMC;if (!strcmp(ptn, "recovery"))partno = CONFIG_ANDROID_RECOVERY_PARTITION_MMC;/*获取kernel对应的partition info*/if (get_partition_info(dev_desc, partno, &info)) {printf("booti: device don't have such partition:%s\n", ptn);goto fail;}
#endif
#endif#ifdef CONFIG_FASTBOOT
......
#else/*获取kernel的hdr,此信息是在编译boot.img的时候就存放在它起始的某个固定位置。*/if (mmc->block_dev.block_read(mmcc, info.start,1, (void *)hdr) < 0) {printf("booti: mmc failed to read bootimg header\n");goto fail;}
......sector = info.start + (hdr->page_size / 512);
#endif/*读取kernel到RAM中的kernel_addr*/if (mmc->block_dev.block_read(mmcc, sector,(hdr->kernel_size / 512) + 1,(void *)hdr->kernel_addr) < 0) {printf("booti: mmc failed to read kernel\n");goto fail;}/* flush cache after read */flush_cache((ulong)hdr->kernel_addr, hdr->kernel_size); /* FIXME */sector += ALIGN_SECTOR(hdr->kernel_size, hdr->page_size) / 512;/*读取ramdisk到kernel的ramdisk_addr*/if (mmc->block_dev.block_read(mmcc, sector,(hdr->ramdisk_size / 512) + 1,(void *)hdr->ramdisk_addr) < 0) {printf("booti: mmc failed to read kernel\n");goto fail;}/* flush cache after read */flush_cache((ulong)hdr->ramdisk_addr, hdr->ramdisk_size); /* FIXME */
#elsereturn -1;
#endif} else {......}
....../*根据hdr信息来boot linux*/do_booti_linux(hdr);
......
}
void do_booti_linux (boot_img_hdr *hdr)
{ulong initrd_start, initrd_end;
#ifdef CONFIG_SERIAL_TAGchar appended_cmd_line[512];
#endifvoid (*theKernel)(int zero, int arch, uint params);bd_t *bd = gd->bd;
#ifdef CONFIG_CMDLINE_TAGchar *commandline = getenv("bootargs");/* If no bootargs env, just use hdr command line *//*本例bootargs没有定义*/if (!commandline) {/*获取cmdline,此值在device/fsl/imx6/BoardConfigCommon.mk中定义。*/commandline = (char *)hdr->cmdline;
......}
#endif/*kernel address就是boot kernel的函数指针地址了*/theKernel = (void (*)(int, int, uint))(hdr->kernel_addr);/*获取ramdisk start 和 end地址*/initrd_start = hdr->ramdisk_addr;initrd_end = initrd_start + hdr->ramdisk_size;/*将memory,serial,revision,commandline等都放在各自的struct tag中,kernel启动之后会解析它们。*/
#if defined (CONFIG_SETUP_MEMORY_TAGS)setup_start_tag(bd);
#ifdef CONFIG_SERIAL_TAGsetup_serial_tag (¶ms);
#endif
#ifdef CONFIG_REVISION_TAGsetup_revision_tag (¶ms);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGSsetup_memory_tags (bd);
#endif
#ifdef CONFIG_CMDLINE_TAGsetup_commandline_tag (bd, commandline);
#endif
#ifdef CONFIG_INITRD_TAGif (hdr->ramdisk_size)setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
......setup_end_tag (bd);
#endif
....../*启动kernel, never return back!*/theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
}

注意theKernel()的参数,第二个是machine type,kernel会去匹配,如果没有找到对应的type id,那么就无法正常启动kernel.

int board_init(void)
{
....../* board id for linux */gd->bd->bi_arch_number = MACH_TYPE_MX6Q_SABRESD;
......
}

第三个参数就是前面的那些tags.

到此,kernel就启动起来了。

[IMX6Q]u-boot启动kernel流程相关推荐

  1. 基于IMX6Q的uboot启动流程分析(3):_main函数之relocate_code与board_init_r

    基于IMX6Q的uboot启动流程分析(1):uboot入口函数 基于IMX6Q的uboot启动流程分析(2):_main函数之board_init_f 基于IMX6Q的uboot启动流程分析(3): ...

  2. [uboot] uboot启动kernel篇(二)——bootm跳转到kernel的流程

    转自 https://blog.csdn.net/ooonebook/article/details/53495021 一.bootm说明 bootm这个命令用于启动一个操作系统映像.它会从映像文件的 ...

  3. Spring Boot————Spring Boot启动流程分析

    一.引言 Spring Boot 的启动虽然仅仅是执行了一个main方法,但实际上,运行流程还是比较复杂的,其中包含几个非常重要的事件回调机制.在实际生产开发中,有时候也会利用这些启动流程中的回调机制 ...

  4. 全志 android 编译,全志A20启动代码流程分析 ——Android

    现在的CPU都固化了内部 ROM,内部 ROM中有一般都有一段程序,一般有如下几个功能: 1,初始化,部分外设,如USB,SDCARD 2,初始化DDR(内存)和NandFlash 3,加载boot( ...

  5. 全志android 编译,全志A20启动代码流程分析 ——Android

    现在的CPU都固化了内部 ROM,内部 ROM中有一般都有一段程序,一般有如下几个功能: 1,初始化,部分外设,如USB,SDCARD 2,初始化DDR(内存)和NandFlash 3,加载boot( ...

  6. uboot之u盘启动kernel

    AT91SAM9260 U-BOOT OHCI 对于 U 盘启动 kernel, 先通过了解整个框架,在细说 USB 枚举(包括 HUB ) ,OHCI 等内容 一.            总体流程 ...

  7. springboot 自动装配_Spring Boot 自动装配流程

    Spring Boot 自动装配流程 本文以 mybatis-spring-boot-starter 为例简单分析 Spring Boot 的自动装配流程. Spring Boot 发现自动配置类 这 ...

  8. os引导程序boot从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)

    [0]README 0.1) 本代码旨在演示 在boot 代码中,如何 通过 loader文件所在根目录条目 找出该文件的 在 软盘所有全局扇区号(簇号),并执行内存中的 loader 代码: 0.2 ...

  9. spring boot 启动类

    做项目用到spring boot 感觉spring boot用起来比较流畅.想总结一下,别的不多说,从入口开始. spring boot启动类Application.class 不能直接放在main/ ...

最新文章

  1. minicom使用总结
  2. [k8s]elk架构设计-k8s集群里搭建
  3. 算法—2,记一个自己的算法题 计算数字k在0到n中的出现的次数,k可能是0~9的一个值
  4. Android-用ListView显示SDCard文件列表
  5. 享元模式源码解析(jdk+tomcat)
  6. 难题:嵌套computeIfAbsent
  7. LeetCode 875. 爱吃香蕉的珂珂(二分查找)
  8. matlab 最优化编程,Matlab最优化编程例子
  9. 移动数据通信网络工作原理(SGSNGGSN)
  10. jQuery图片LightBox插件 点击图片放大 支持移动手机
  11. 深信服面试智力题-------三人求平均工资
  12. IE无法打开internet网站已终止操作的解决的方法
  13. c盘减肥//请在阅读本文之前查看你C盘的可用空间
  14. 篮球c语言程序,源程序C代码:篮球比赛应用系统
  15. mac 剪切移动文件
  16. Labview实现简单知乎日报客户端
  17. 简明python教程五----数据结构(下)
  18. V语言(Vlang)初探
  19. 癌症与各种微量元素的关系
  20. 【JavaEE】图书管理系统-简易版

热门文章

  1. 天联助力畅捷通T+实现远程访问说明
  2. 零序电流、零序电压与脱扣器
  3. IM即时通讯开发如何解决大量离线消息导致客户端卡顿的
  4. 研发新员工培训流程(待续)
  5. 微信小程序-地图map使用,周边公交地铁查询
  6. 推荐几个jquery实用的插件
  7. 一套手机点餐收银系统源码,系统功能完善、页面美观,开源分享!
  8. macOS BigSur有哪些变化值得升级
  9. 「知识点分享」结构光式激光视觉传感器的焊缝跟踪系统
  10. 【产品经理】常用需求优先级评估模型