• tiny4412Uboot启动分析 Hello


    一、从本质上将,引导转载程序至少应提供以下功能

      (1)设置和初始化RAM

      (2)初始化一个串口

      (3)检测机器类型(machine type)

      (4)设置内核标签列表(tag list)

      (5)调用内核映像

    二、.Uboot引导Linux内核时的启动状态

      zImage可以放在RAM的任意位置被调用,但是通常放在32KB处,因为前16KB用于存放Linux页表,不能占用。

      (1)停止所有的DMA

      (2)CPU寄存器配置:

        r0 = 0;

        r1 = 机器类型码

        r2 = 标签列表在系统RAM中的物理地址,或者设备树块(dtb)在系统RAM中的物理地址

      (3)CPU模式:必须在SVC模式,而且必须禁止所有类型的中断(irq和fiq)

      (4)缓存和MMU:MMU必须关闭,数据缓存必须关闭,指令缓存可关可不关

      引导加载程序应通过直接跳转到LInux镜像的第一条代码处来调用内核镜像

    三、相关的bootm命令讲解

        在常用的 uboot 中完成一系列的初始化后最后通过 bootm 命令加载 linux 内核。bootm 将内核镜像从各种媒介中读出,存放在指定的位置;然后设置标记列表给   内核,传递参数;最后跳到内核的入口点去执行。

    u-boot中每个命令都是通过 U_BOOT_CMD 宏来定义的,格式如下:

       U_BOOT_CMD(name,maxargs,repeatable,command,"usage","help")

    各项参数的意义如下:

      (1) -- name:命令的名字,注意,它不是一个字符串(不要用双引号括起来);

      (2)-- maxargs:最大的参数个数;

      (3)-- repeatable:命令是否可以重复,可重复是指运行一个命令后,下次敲回车即可再次运行;

      (4)-- command:对应的函数指针,类型为(*cmd)(struct cmd_tbl_s *, int, int, char *[]);

      (5) -- usage:简单的使用说明,这是个字符串;

      (6)-- help:较详细的使用说明,这是个字符串。

    bootm命令的源码路径为:u-boot源码路径/common/cmd_bootm.c,入口函数为d_bootm,(参考1中有对它的稍具体分析),该函数主要的工作流程是,通过bootm_start来获取内核镜像文件的信息,然后通过bootm_load_os函数来加载内核,

    最后通过boot_fn来启动内核(这三个函数参考1中有对它的稍具体分析)。

    四、kernel_entry函数

    真正将控制权交给内核, 启动内核;满足arm架构linux内核启动时的寄存器设置条件:第一个参数为0 ;第二个参数为板子id需与内核中的id匹配,第三个参数为启动参数地址bi_boot_params 。主要操作:

    (1)首先取出环境变量bootargs,这就是要传递给内核的参数。( u-boot 是通过标记列表向内核传递参数,标记在定义为tag,是一个结构体,在 arch/arm/include/asm/setup.h 中定义)

    (2)调用setup_XXX_tag

    参考1中有自己实现的6410的启动内核的例子

    五、与启动系统相关的环境变量

      有bootcmd和bootargs,可保证在Uboot不重新编译的情况下可以以不同的方式启动

        ①bootcmd命令可以是好几个命令的集合,主要负责内核的引导工作,例如:bootcmd=movi read kernel 30008000;bootm 30008000,将内核拷贝到0x30008000的地方,然后从内存的0x30008000的地方启动内核;

        Uboot在完成一系列的初始化后,就开始加载内核到DRAM中,加载到的地址可由bootcmd命令指定这个30008000是由内核的链接地址所确定的。

        ②bootargs命令主要是负责向内核传递参数,例如:bootargs=console=ttySAC2,115200 root=dev/mmcblk0p2 rw init=/linuxrc rootfstype=ext3,表示引导后控制台使用串口2,波特率115200,根文件系统在SD卡(0号

        设备)的第2分区,并且可读可写;进程1(init进程)的地址为/linuxrc,使用的根文件系统是ext3类型。

    六、判断镜像的种类

      Uboot将Linux内核加载到DRAM的链接地址处后,就开始读镜像的头信息,找到MAGIC_NUM,以此来判断镜像的类型,镜像有两种格式:在Image和uImage

        zImage:Linux内核编译出来后,最先生成的是.elf格式的可执行文件,类似Windows下的.exe文件,其中包含了在操作系统下运行的大量信息,但是Linux内核是个逻辑程序,不需要这些信息,删掉他们后大小变为Image(.bin,

      已经可以直接运行了)文件,大小为原来的1/10,然后再对其进行压缩,就形成了zImage文件。这个zImage是自解压的,解压操作由其头部的解压程序来完成,不需要Uboot的参与。

        uImage是Uboot发明的一种镜像类型。它是在zImage的前面加上一些信息和一些校验信息,64字节。将zImage加工为uImage的工具在U-boot根目录下/tools中的mkimage程序,只需将其复制到/usr/local/bin/,编译内核时输

      入make uImage,然后就能产生uImage了。

      判断完镜像种类后 ,Uboot将对镜像头进行校验,然后再次读取头信息,从头信息中读取这个镜像的各种信息(比如镜像长度,镜像种类,入口地址等)。

    七、新版的Uboot与内核之间的传参引导

      近年来的内核在启动时还需要设备树的dts文件,于是比较新的uboot都实现了传递dtb的功能,为了使能设备树,需要在编译U-boot的时候在config文件中加入:#define CONFIG_OF_LIBFDT

      一般分为三种情况:

      (1)利用U-boot的命令,在引导kernel时将dts传入。这种方式需要将dtb的地址写到uboot中(一般是环境变量),比如:首先将kernel载入内存,然后fdt addr ${fdtaddr}命令将dtb载入内存

       最后使bootz ${loadaddr} ${initrdaddr} ${fdtaddr}来引导内核,(其中initrd是临时文件系统,嵌入式中用得极少)实际使用时用“-”代替:bootz ${loadaddr} - ${fdtaddr}

      (2)将dts和kernel打包为pImage。这种方式无需将dtb的地址写到uboot中(但uboot中要实现读pImage头部的功能),uboot可以去pImage的头部信息处读取到dtb的地址,然后传给传递给kernel。

      (3)启用kernel中”ARM_APPENDED_DTB”选项,该选项的意思是将dtb和kernel打包在一起,如此一来kernel启动时会去紧挨着它的地方寻找dtb,这样就不需要uboot来传递dtb地址了。

    八、引导内核时可能出现的问题

      如果U-boot确认无误可以启动起来,而kernel的启动却出现了问题,那么一般是以下几种情况:

    1. 对于老版本的U-boot,有大概率是U-boot传给kernel参数的时候出了问题,着重注意一下创建tag的宏有没有正常定义,如CONFIG_CMDLINE_TAG、CONFIG_MTDPARTITION等
    2. kernel的链接地址与加载地址不符,链接地址可以通过kernel的head.S获知,详见kernel启动汇编阶段分析
    3. kernel的自解压地址与链接地址不符,zImage这类kernel格式必须把自己解压到自己的链接地址,自解压地址在kernel源码目录arch/arm/mach-xxxx/Makefile.boot文件中
    4. 环境变量未被正常设置

    参考1:http://www.cnblogs.com/CoderTian/p/6006400.html

    参考2:http://blog.csdn.net/qq_28992301/article/details/51873201

  • 相关阅读:
    Sign Distance Field 2
    矩阵相乘优化
    Editor GUI 的 Gamma Correction
    GPUSkinning 5
    GPUSkinning 2
    RenderTextureFormat.ShadowMap
    战争迷雾
    Texture2DArray(2)
    软件渲染器 YwSoftRenderer
    将 Unity5.3 的老项目升级到 Unity 2018.3 遇到的些许问题。
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/7402044.html
Copyright © 2020-2023  润新知