以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除。

参考资料:http://www.cnblogs.com/biaohc/p/6403863.html

总结:uboot启动linux内核的整个流程

开机时会出现倒计时,当没有按键按下的时候,uboot会读取出bootcmd这个环境变量,并使用rum_command函数来执行这个命令;

  • 实质是执行了movi read kernel 30008000;bootm 30008000。
  • movi read kernel,把sd卡中的kernel分区赋值到30008000内存处;
  • bootm 30008000,真正的传参以及跳转到linux内核中执行(实际执行do_bootm()函数)。
  • bootm(do_bootm()函数)首先要做的事情是判断这个内核镜像类型(zImage、uImage、设备树);
  • 通过对镜像文件的头文件的验证,以确定是哪种内核镜像,然后再把必须的信息储存起来(linux操作系统、ep的值等)。
  • 确定好以后调用do_bootm_linux函数来对内核传参并且启动内核。

一、uboot作用简介

uboot的主要作用是用来启动linux内核。

  • 因为CPU不能直接从块设备中执行代码,需要把块设备中的程序复制到内存中,而复制之前还需要进行很多初始化工作,如时钟、串口、dram等;
  • 如要想让CPU启动linux内核,只能通过另外的程序,进行必要的初始化工作,在把linux内核中代码复制到内存中,并执行这块内存中的代码,即可启动linux内核;
  • 一般情况下,linux镜像储存在块设备中(SD卡、iNand、Nandflash等)。首先执行uboot代码,把块设备中的内核代码复制到内存地址0x30008000地址处,然后再执行bootm 0x30008000命令以启动内核代码。

二、基础知识

vmlinuz、Image、zImage、uImage的区别与联系

(1)linux内核代码经过编译链接,生成一个elf格式的可执行文件,即vmlinuz或者vmlinux;

  • 此文件不能直接烧录。

(2)vmlinuz文件经过arm-linux-objcopy以后,生成一个Image镜像文件。

  • vmlinuz.elf文件大小为70M以上,而Image镜像文件为7M左右。

(3)Image文件在进一步经过压缩,并添加解压缩代码,形成zImage文件。

  • 当zImage文件作为启动镜像来启动时,首先要解压这个文件,这个解压过程可以由uboot解压或者zImage文件本身自解压。
  • zImage中除了linux内核的镜像以外,还有一些头文件以及这部分解压代码,所以内核实际上在addr地址中再加一个偏移量的位置。

(5)uImage是uboot自己专用的启动内核镜像,相对于zImage他们之间头文件有一定区别。

  • uImage现在基本上要属于过时的技术了,新一点的技术为设备树的启动方式;

三、UBOOT启动内核的代码分析

在启动UBOOT时,出现倒计时,如果没有按键按下,则会自动启动内核。

1、start_armboot()函数末尾的main_loop

下面这段代码在此main_loop函数中,作用是执行完倒计时函数之后,启动linux内核。

  • 启动方式是s = getenv ("bootcmd");;
  • 假定不使用HUAH_PARSER,则run_command (s, 0);实际上就是读取环境变量bootcmd,然后执行这个命令。

2、bootcmd命令

  • bootcmd=movi read kernel 30008000; movi read rootfs 30B00000 300000; bootm 30008000 30B00000
  • 这两个命令完成linux内核启动。
  • movi read kernel 30008000,把sd卡中kernel分区复制到30008000内存地址处;
  • bootm 30008000,到内存地址处执行代码;
  • 执行bootm命令,实际执行do_bootm函数。

3、do_bootm()函数

(1)因为bootm 0x30008000,参数为2,因此有addr = simple_strtoul(argv[1], NULL, 16)

  • 此时addr中的值为0x30008000。

(2)接着判断0x30008000偏移36字节以后的地址中的值

  • 如果为0x016f2818,说明启动镜像为zImage,则输出boot with zImage。

(3)内核的操作系统类型,和内核真正的入口

  • hdr->ih_os = IH_OS_LINUX;zImage header中ih_os赋值为 IH_OS_LINUX;
  • hdr->ih_ep = ntohl(addr);ih_ep中存放的是point address,这个值是真正内核代码的地址(起始执行入口地址);

(4)image变量

  • static bootm_headers_t images;
  • images为uboot内定义的一个bootm_header_t格式的全局变量,用来完成启动过程的。
  • bootm_header_t类型为一个结构体,如下图:
  • 包含一个image_header_t类型的指针,这个指针最后指向了0x30008000处的zImage header。
  • 包含一个image_header_t类型的结构体,后面会把0x30008000处的zImage header复制一份到此结构体;
  • 包含一个标志位 legacy_hdr_valid。如果上面两个赋值以后,把legacy_hdr_valid赋值为1;

(5)memmove (&images.legacy_hdr_os_copy, hdr, sizeof(image_header_t));

  • 把hdr中的值复制一份到 image.legacy_hdr_os_copy中,即把内存地址0x30008000处设置好的zImage头复制一份到uboot的data段。

(6)直接跳转到after_header_check处,os为IH_OS_LINUX。



4、after_header_check

  • 判断操作系统,然后调用do_bootm_linux函数

5、do_bootm_linux()函数

(1)获取环境变量bootargs;

(2)判断全局变量images中的legacy_hdr_valid是否为1,如果为1获取ep值,如果不为1则error。

(3)把ep强制类型换换为函数指针类型赋值给thekernel;

(4)从环境变量中读取machid的值,赋值给s,如果s不空则machid = 环境变量中machid的值,并打印machid;

----------------------------------uboot给内核传参-----------------------------------------------

6、uboot给内核传参

  • 传参主要是uboot把与硬件有关的信息传给linux内核,如memory信息(多少bank、size、起始地址)、命令行信息、lcd 串口、initrd、MTD等信息。
  • 如要定义了任意一个CONFIG_XXXXX,则执行setup_start_tag(bd)

一、setup_start_tag函数

  • 初始化第一块参数tag

(1)params = (struct tag *) bd->bi_boot_params;

  • gd->bd->bi_boot_params = (PHYS_SDRAM_1+0x100);
  • 这句代码,把uboot中的全局变量(即gd)的bi_boot_params内存地址,强制转换为stuct tag* 类型,然后赋值给params;
  • 把PHYS_SDRAM_1+0x100这个地址设置为传参的起始地址;

(2)struct tag结构体

  • 此结构体由一个stuct tag_header类型的结构体,加上一个由一系列结构体组成的union联合体组成;
  • 这一系列结构体中存放的就是与board有关的参数;

(3)hdr.tag 与hdr.size赋值

  • params->hdr.tag = ATAG_CORE; params->hdr.size = tag_size (tag_core);

(4)对联合体中的结构体参数赋值

  • params->u.core.flags = 0;
  • params->u.core.pagesize = 0;
  • params->u.core.rootdev = 0;

(5)对下一个params进行初始化

  • params = tag_next (params);
  • //#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size)),把params移动sizeof(tag_core)大小继续赋值

二、传递内存参数,setup_memory_tags函数

  • 把内存每个bank的信息放到这里:第一个扇区的起始地址和大小,第二个扇区的起始地址和大小……
 

三、传递命令行参数,setup_commandline_tag函数

  • commandline是一个char *类型,指向环境变量中的bootargs的值,即:
  • #define CONFIG_BOOTARGS  "root=/dev/mtdblock4 rootfstype=yaffs2 init=/init console=ttySAC0,115200"

四、setup_end_tag (bd):结束传参

-----------------------------------------uboot给内核传参结束-----------------------------------------------



 7、uboot中最后一句代码

  • 通过执行thekernel函数直接启动linux内核,传递三个参数:0、machid、传参的首地址;
  • 这三个参数是通过r0、r1、r2三个寄存器来传递,r0传递0、r1传递machid、r2传递传参的首地址。
  • 这样就把内核启动起来了。
 

uboot源码——内核启动分析相关推荐

  1. u-boot源码配置原理分析

    作者:杨老师,华清远见嵌入式学院讲师. u-boot的源代码默认是不针对任何目标平台的,当我们要移植u-boot到一个特定的目标平台时,需要生成针对目标平台的配置文件.u-boot目前已经支持的芯片可 ...

  2. uboot源码——主Makefile分析

    以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 一.配置编译初体验 1.uboot来源于官方(uboot官网下载),或者SoC官方(研发s5pv210芯片的公司推出的开发板,SMDKV21 ...

  3. uboot源码——mmc驱动分析

    以下内容源于朱有鹏<物联网大讲坛>课程的学习,以及博客http://www.cnblogs.com/biaohc/p/6409197.html的学习整理,如有侵权,请告知删除. 一.ubo ...

  4. 嵌入式之uboot源码分析-启动第二阶段学习笔记(下篇)

    接上部分---->嵌入式之uboot源码分析-启动第二阶段学习笔记(上篇) 注:如下内容来自朱老师物联网大讲堂uboot课件 3.2.14 CFG_NO_FLASH (1)虽然NandFlash ...

  5. uboot源码分析(基于S5PV210)之启动第一阶段

    目录 一.start.S引入 1.u-boot.lds中找到start.S入口 2.SourceInsight中如何找到文件 3.SI中找文件技巧 二.start.S解析 1.不简单的头文件包含 2. ...

  6. 开发板与虚拟机组网、uboot源码makefile分析、uboot安全启动与非安全启动方式、uboot源码配置与编译流程、制作TF启动盘

    开发板与虚拟机组网. 局面:开发板.PC(Ubuntu系统).网线直连PC:设置Ubuntu系统:1.设置桥接模式,桥接到PC的有线网卡上:2.手动配置IP V4的地址信息,注意和开发板保持在同一网段 ...

  7. U-Boot源码目录分析(VScode工程创建及文件夹过滤)

    参考:U-Boot工程目录介绍 作者:一只青木呀 发布时间: 2020-10-21 14:47:30 网址:https://blog.csdn.net/weixin_45309916/article/ ...

  8. linux uboot 源码分析,UBoot源码分析1.pdf

    UBoot源码分析1 • UBoot源码解析(一) 主要内容 • 分析UBoot是如何引导Linux内核 • UBoot源码的一阶段解析 BootLoader概念 • Boot Loader 就是在操 ...

  9. 编译FriendlyDesktop的Uboot源码、内核,修改开机图片logo

    1. 安装依赖包 参照官网wiki教程 - 12章节:Nanopi 教程wiki 安装以下依赖包. sudo apt-get -y install bison g++-multilib git gpe ...

最新文章

  1. Linux下程序崩溃dump时的 core文件的使用方法
  2. ASP.NET2.0 文本编辑器FCKeditor的冰冷之心 【月儿原创】
  3. android ocr识别源码_身份证识别OCR解决手动输入繁琐问题
  4. pythonrandom函数_python之random函数
  5. 2019斯坦福CS224n深度学习自然语言处理笔记(1)Word2Vec与Glove
  6. LEFT OUTER JOIN
  7. 计算指定人数班级的班级平均成绩(计数器控制控制的循环)
  8. [Python] GAMP结果文件批量统计与绘图
  9. 数据分析--企业的贤内助 附下载地址
  10. iOS 唤起APP之Universal Link(通用链接)
  11. AI工具究竟是帮手还是对手?你怎么看,一起来聊聊吧!
  12. JAVA编程习题及答案_完美版
  13. Intel+Nvidia双显卡笔记本Linuxmint18下安装CUDA+OpenCV+Caffe的安装记录
  14. ftp文件盘服务器回档,企业网盘和FTP服务器对比
  15. unity 调用外部相机拍照
  16. GIS空间分析 叠加分析与缓冲区分析2 房产开发适宜性制图
  17. seo每日一贴_2020年seo优化应该注意哪些细节?新手必看
  18. 一文详解深度相机之双目成像
  19. Java swing写五子棋小游戏(分析)
  20. 如何提升企业级PMO协调能力?

热门文章

  1. zabbix-02-CentOS7.4安装zabbix4.0
  2. C#关键字的个人理解与注释
  3. Javascipt数组去重的几种方式
  4. 对session的理解
  5. 云栖社区云栖号(团队博客)攻略【2018版】
  6. [零基础学JAVA]Java SE应用部分-34.Java常用API类库
  7. 一起看一下主流应用使用了哪些三方库
  8. 更改阿里云域名解析台里某个域名绑定的IP之后不能解析到新IP
  9. web.xml(8)_jsp-config
  10. mysql导入sql文件过大或连接超时的解决办法