zoukankan      html  css  js  c++  java
  • [uboot]uboot如何引导系统

    转自:http://bbs.elecfans.com/jishu_455028_1_1.html


     如6410的bootcmd和bootargs默认存在于uboot1.1.6/include/configs/smdk6410.h

    the older version's of u-boot used boot.scr to set boot parameter

    setenv bootargs 'console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait omapfb.mode=dvi:1280x1024MR-32 at 60 vram=12M' setenv bootcmd 'mmc init; fatload mmc 0 80000000 uImage; bootm 80000000'
    
    boot

    Newer version's of u-boot now look for a uEnv.txt file to set boot parameter

    mpurate=1000
    dvimode=800x600MR-16@60 
    vram=4MB 
    bootargs "console=ttyS2,115200n8 root=/dev/mmcblk0p2 rootwait ro 
    vram=${vram} omapfb.mode=dvi:${dvimode} omapfb.vram=0:2M,1:2M mem=208M@0x80000000"
    boot 

    By default, the frame buffer is only allocated for /dev/fb0. Option vram should be specified in u-boot bootargs variable to allocate frame buffer for /dev/fb1. For example:   vram=8M omapfb.vram=4M,4M

    ---------------------------------------------------------------------------------------------------------------------------------------------

    1.bootcmd和bootargs

    通过串口连接BeagleBone Black,参见http://elinux.org/Beagleboard:Terminal_Shells
    启动到U-Boot的时候,会看到

    Hit any key to stop autoboot:0

    按下任意键则放弃自动引导,从而进入了U-Boot的命令行, 在这里你可以手动进行接下来系统的引导。

    下面来了解U-Boot是如何引导系统的。


    在U-Boot的官网手册中看到了2个关键的环境变量和1个命令。
    bootcmd: This variable defines a command string that is automatically executed 
             when the initial countdown is not interrupted.
             This command is only executed when the variable bootdelay is also defined!
    bootargs: The contents of this variable are passed to the Linux kernel as boot 
              arguments (aka "command line"). 

    run    - run commands in an environment variable


    bootcmd中的命令就是出现“Hit any key to stop autoboot”提示后,不按任意键,会自动运行的命令
    bootargs是传递给Linux内核的参数。
    run是运行环境变量中的命令,bootcmd中包含run命令。

    所以分析引导过程要从bootcmd开始。
    在U-Boot的命令行中输入printenv可显示所有的环境变量,我已经把相关的粘贴到了下面。
    为方便阅读我添加了换行。

    bootcmd=
      run findfdt;
      run mmcboot;
      setenv mmcdev 1;
      setenv bootpart 1:2;
      run mmcboot;
      run nandboot;

    下面就分别从bootcmd内容说起:

    2.1.findfdt

    首先是运行findfdt中的命令,目的是通过board_name来设置fdtfile,结果是fdtfile的值为am335x-boneblack.dtb

    findfdt=
      if test $board_name = A335BONE;
      then
        setenv fdtfile am335x-bone.dtb;
      fi;
      if test $board_name = A335BNLT;
      then
        setenv fdtfile am335x-boneblack.dtb;
      fi;
      if test $board_name = A33515BB;
      then
        setenv fdtfile am335x-evm.dtb;
      fi;
      if test $board_name = A335X_SK;
      then
        setenv fdtfile am335x-evmsk.dtb;
      fi;
      if test $fdtfile = undefined;
      then
        echo WARNING: Could not determine device tree to use;
      fi;
    board_name=A335BNLT

    2.2.mmcboot

    "mmc dev 0"是将设备切换到0,通常有2个设备一个是SD卡,一个是eMMC

    mmcboot=
      mmc dev ${mmcdev};
      if mmc rescan;
      then
        echo SD/MMC found on device ${mmcdev};
        if run loadbootenv;
        then
          echo Loaded environment from ${bootenv};
          run importbootenv;
        fi;
        if test -n $uenvcmd;
        then
          echo Running uenvcmd ...;
          run uenvcmd;
        fi;
        if run loadimage;
        then
          run mmcloados;
        fi;
      fi;
    mmcdev=0

    2.2.1.loadbootenv

    这应该是从设备0的第1个分区装载uEnv.txt到地址0x80200000
    当默认的环境变量不符合要求时,可以用uEnv.txt设置新的环境变量。没有它也可以,先不用管,后面说。

    loadbootenv=load mmc ${mmcdev} ${loadaddr} ${bootenv}
    loadaddr=0x80200000
    bootenv=uEnv.txt

    2.2.2.importbootenv

    这是把uEnv.txt中的环境变量导入到U-Boot的环境变量中。“filesize”没有指定。

    importbootenv=echo Importing environment from mmc ...; env import -t $loadaddr $filesize

    由于我没有“uenvcmd”这个环境变量,所以那个条件语句中的内容没有执行。我记着Arch Linux好像用了那个,那个变量应该在uEnv.txt中。

    2.2.3.loadimage

    于是直接到了loadimage,这里和载入uEnv.txt是相似的,“0:2”的意思是设备0的第2个分区,而载入uEnv.txt时没有指定分区,就默认第1分区了。
    loadimage目的是将Linux内核载入内存。

    loadimage=load mmc ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
    bootpart=0:2
    bootdir=/boot
    bootfile=zImage

    2.2.4.mmcloados

    mmcloados=
        run mmcargs;
        if test ${boot_fdt} = yes || test ${boot_fdt} = try;
        then
            if run loadfdt;
            then
                bootz ${loadaddr} - ${fdtaddr};
            else
                if test ${boot_fdt} = try;
                then
                    bootz;
                else
                    echo WARN: Cannot load the DT;
                fi;
            fi;
        else
            bootz;
        fi;

    2.2.5.mmcargs

    这个就是设置bootargs这一个环境变量而已,用于向内核传递参数。

    mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype}
    console=ttyO0,115200n8
    mmcroot=/dev/mmcblk0p2 ro
    mmcrootfstype=ext4 rootwait

    之前载入了Linux内核,这里载入了设备树文件。
    最后通过bootz后接2个地址就启动了系统。

    boot_fdt=try
    loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
    fdtaddr=0x80F80000

    3.总结如下

    这是默认环境变量的行为。而我们的系统可能与其不同。这就要修改环境变量。
    我知道有2种方式,一种是在U-Boot的命令行中通过命令修改,另一种就是通过uEnv.txt了。

    • uboot命令方式
    mmc dev 0;
    load mmc 0:2 0x80200000 /boot/zImage
    setenv bootargs concole=ttyO0,115200n8 root=mmcroot=/dev/mmcblk0p2 ro rootfstype=ext4 rootwait
    load mmc 0:2 0x80F80000 /boot/am335x-boneblack.dtb
    bootz 0x80200000 - 0x80F80000
    • uEnv.txt方式

    这里介绍uEnv.txt的方式。先列出我uEnv.txt的内容,不用详细看,看我下面的说明。

    bootfile=uImage
    loadfdt=load mmc ${bootpart} ${fdtaddr} ${bootdir}/dts/${fdtfile}
    mmcloados=run mmcargs; 
    if test ${boot_fdt} = yes || test ${boot_fdt} =try;
    then
    if run loadfdt;
    then
    bootm ${loadaddr} - ${fdtaddr};
    else if test ${boot_fdt} = try;
    then
    bootz;
    else
    echo WARN: Cannot load the DT; fi;
    fi;
    else
    bootz;
    fi; mmcroot
    =/dev/mmcblk0p2 rw mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype} init=/usr/lib/systemd/systemd

    一共6行,最后一行空白。
    bootfile: 修改了内核名字,
    loadfdt: 中只是在目录中加了“dts/”,
    mmcloados: 主要是把bootz改成bootm。
    mmcroot: 把只读改成了读写。
    mmcargs: 只是在后面指定了init为systemd,也有其他方法,如init为指向systemd的软链接。

    这里是从设备0启动系统,怎样知道自己的系统位于哪个设备呢,也许有某种约定,比如如果有SD卡,那么SD卡是0
    我不知道的话,可以在U-Boot的命令行中通过命令判断。如,

    U-Boot# mmc list
    OMAP SD/MMC: 0
    OMAP SD/MMC: 1

    列出mmc设备

    U-Boot# mmc dev
    mmc0 is current device

    显示当前是那个设备

    U-Boot# mmc part
    Partition Map for MMC device 0  --   Partition Type: DOS
    Part    Start Sector    Num Sectors     UUID            Type
      1     2048            131072          29942d7e-01     0c Boot
      2     133120          15390720        29942d7e-02     83

    显示当前设备的分区信息

    U-Boot# ls mmc 0:1
       100688   mlo
       308232   u-boot.img
          510   uenv.txt
    3 file(s), 0 dir(s)

    列出设备0第1个分区“/”目录的文件,我没有指定,默认为“/”。

    附录:printenv内容

    OpenJTAG> printenv
    bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0
    bootdelay=2
    baudrate=115200
    ethaddr=08:00:3e:26:0a:5b
    netmask=255.255.255.0
    mtdids=nand0=nandflash0
    mtdparts=mtdparts=nandflash0:256k@0(bootloader),128k(params),2m(kernel),-(root)
    ipaddr=192.168.1.66 //开发板ip地址 
    
    bootargs=root=/dev/nfs rw nfsroot=192.168.1.88:/home/book/Videos/rootfs/ ip=192.168.1.66 console=ttySAC0 mem=64M     //uboot中nfs文件系统参数192.168.1.88ubuntu系统ip地址
    serverip=192.168.1.100 //xp中的ip地址
    
    stdin=serial 
    stdout=serial
    stderr=serial
    partition=nand0,0
    mtddevnum=0
    mtddevname=bootloader
  • 相关阅读:
    IO编程
    File类
    对于Java集合理解
    Java泛型
    多线程编程
    异常处理
    Static.final修饰符、super关键字及常量与变量
    java类的基本结构
    数组
    二叉树后序遍历 递归 非递归
  • 原文地址:https://www.cnblogs.com/aaronLinux/p/6629376.html
Copyright © 2011-2022 走看看