zoukankan      html  css  js  c++  java
  • Imx6DL使用uboot2015.04更新uboot,kernel和rootfs

     

    Imx6DL使用uboot2015.04更新uboot,kernel和rootfs

    转载请说明出处。

    参考链接地址:

    https://blog.csdn.net/u014645605/article/details/52212622

    http://blog.sina.com.cn/s/blog_9864c64a0102xpte.html

    https://blog.csdn.net/abcamus/article/details/59705763

    https://blog.csdn.net/zuoyioo7/article/details/74529255

    1.首先,使用的是emmc作为存储介质,需要先大概了解emmc的物理分区。

    从下图可以看出来,分为四个区Boot Area Partitions、RPMB Partition、General Purpose Partitions和User Data Area。

    Boot Area Partitions:主要用来存放bootloader(分区1和分区2可以看成两个完全一致的分区)。

    RPMB Partition:未使用。

    General Purpose Partitions:未使用。

    User Data Area:主要用来存放linux内核和rootfs。

    为了更合理的管理数据,满足不同的应用需求,UDA 在实际产品中,会进行软件再分区。目前主流的软件分区技术有 MBR(Master Boot Record)和 GPT(GUID Partition Table)两种。这两种分区技术的基本原理类似,如下图所示

    2. 查看ucl2.xml文件,了解程序在emmc中的分区

    1.  
      <!-- create partition -->
    2.  
      <CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD>
    3.  
      <CMD state="Updater" type="push" body="$ tar xf $FILE "> Partitioning...</CMD>
    4.  
      <CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk%mmc%"> Partitioning...</CMD>
    通过分析,可以知道使用mksdcard.sh.tar来建立文件分区,打开mksdcard.sh
    #!/bin/sh
    
    # partition size in MB
    BOOT_ROM_SIZE=10
    
    # call sfdisk to create partition table
    # destroy the partition table
    node=$1
    dd if=/dev/zero of=${node} bs=1024 count=1	
    
    sfdisk --force -uM ${node} << EOF
    ${BOOT_ROM_SIZE},500,0c			    //分区1从10M开始,大小为500M,为FAT分区
    600,,83					    //分区2从600M开始,到最后,为Linux分区		
    EOF

    需要说明一下,emmc中的所有的物理分区(boot1, boot2,RPMP,General Purpose,UDA)都可以认为是独立的,地址都是从0x00000000开始。而mksdcard.sh是对UDA进行软件分区。

    在uboot的命令窗口中输入:

     mmc dev;mmc part

    mmc  dev:使能emmc的UDA分区。

    mmc part:显示UDA的软件分区。

    窗口输出如下:

    switch to partitions #0, OK
    mmc2(part 0) is current device
    
    Partition Map for MMC device 2  --   Partition Type: DOS
    
    Part    Start Sector    Num Sectors     UUID            Type
      1     20480           1024000         00000000-01     0c
      2     1228800         14041088        00000000-02     83

    20480表示20480个块,每个块的大小为512B,就可以得到20480 * 512B = 10M,

    1024000 * 512B = 500M, 1228800 * 512B = 600M,这些数据和我们在mksdcard.sh中设置的相同。


    3. 继续查看ucl2.xml文件,分析uboot的位置

    1.  
      <!-- burn uboot -->
    2.  
      <CMD state="Updater" type="push" body="send" file="files/linux/sabresd/u-boot.imx" ifdev="MX6D">Sending u-boot.bin</CMD>
    3.  
      <CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk%mmc%boot0/force_ro">access boot partition 1</CMD>
    4.  
      <CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk%mmc%boot0 bs=512 seek=2">write U-Boot to sd card</CMD>

    将u-boot.imx烧进mmc boot0(这里指的就是emmc的boot1分区),bs = 512 seek=2 是读写时跳过 2 * 512个Bytes,就是跳过前面1K的分区表。可以通过下面的方法验证一下。

    在uboot的命令敞口中输入命令:

     mmc dev 2 1;mmc read 20000000 2 100;md.b 20000000 100

    mmc dev 2 1:使能emmc的boot1分区(emmc是设备2,可以通过mmc list查看)。

    mmc read 20000000 2 100:将boot1分区的第2个块开始,读取100个块到内存0x20000000开始的内存当中(跳过1K的分区表)。

    md.b 20000000 100 :显示内存中的数据,数据如下:

    20000000: d1 00 20 40 00 00 80 17 00 00 00 00 2c f4 7f 17    .. @........,...
    20000010: 20 f4 7f 17 00 f4 7f 17 00 00 00 00 00 00 00 00     ...............
    20000020: 00 f0 7f 17 00 20 05 00 00 00 00 00 d2 02 f0 40    ..... .........@
    20000030: cc 02 ec 04 02 0e 07 74 00 0c 00 00 02 0e 07 54    .......t.......T
    20000040: 00 00 00 00 02 0e 04 ac 00 00 00 30 02 0e 04 b0    ...........0....
    20000050: 00 00 00 30 02 0e 04 64 00 00 00 30 02 0e 04 90    ...0...d...0....
    20000060: 00 00 00 30 02 0e 07 4c 00 00 00 30 02 0e 04 94    ...0...L...0....
    20000070: 00 00 00 30 02 0e 04 a0 00 00 00 00 02 0e 04 b4    ...0............
    20000080: 00 00 00 30 02 0e 04 b8 00 00 00 30 02 0e 07 6c    ...0.......0...l
    20000090: 00 00 00 30 02 0e 07 50 00 02 00 00 02 0e 04 bc    ...0...P........
    200000a0: 00 00 00 30 02 0e 04 c0 00 00 00 30 02 0e 04 c4    ...0.......0....
    200000b0: 00 00 00 30 02 0e 04 c8 00 00 00 30 02 0e 04 cc    ...0.......0....
    200000c0: 00 00 00 30 02 0e 04 d0 00 00 00 30 02 0e 04 d4    ...0.......0....
    200000d0: 00 00 00 30 02 0e 04 d8 00 00 00 30 02 0e 07 60    ...0.......0...`
    200000e0: 00 02 00 00 02 0e 07 64 00 00 00 30 02 0e 07 70    .......d...0...p
    200000f0: 00 00 00 30 02 0e 07 78 00 00 00 30 02 0e 07 7c    ...0...x...0...|

    查看u-boot.imx的二进制文件,数据如下



     

    对比一下,数据相同。

    4. 继续查看ucl2.xml文件,分析kernel的位置

    1.  
      <CMD state="Updater" type="push" body="$ mkfs.vfat /dev/mmcblk%mmc%p1">Formatting rootfs partition</CMD>
    2.  
      <CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p1"/>
    3.  
      <CMD state="Updater" type="push" body="$ mount -t vfat /dev/mmcblk%mmc%p1 /mnt/mmcblk%mmc%p1"/>
    4.  
      <CMD state="Updater" type="push" body="send" file="files/linux/sabresd/uImage" ifdev="MX6D">Sending and writting uImage</CMD>
    5.  
      <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/uImage">write kernel image to sd card</CMD>
    6.  
      <CMD state="Updater" type="push" body="send" file="files/linux/sabresd/zImage" ifdev="MX6D">Sending and writting uImage</CMD>
    7.  
      <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/zImage">write kernel image to sd card</CMD>

    通过之前的emmc的分区可以知道,UDA分区1为FAT分区,这段的目的就是将zImage,uImage(提供的例程使用的是zImage)拷贝到FAT文件系统中。

    输入命令:

    mmc dev;fatls mmc 2

    mmc dev:使能emmc的UDA区域。

    Fatls mmc 2:查看UDA区域的FAT文件。

    窗口输出:

    switch to partitions #0, OK
    mmc2(part 0) is current device
      3984556   uimage 
      3984492   zimage 
    
    2 file(s), 0 dir(s)

    可以看到uImage和zImage文件。


    5. 继续查看ucl2.xml文件,分析rootfs的位置

    1.  
      <CMD state="Updater" type="push" body="$ mkfs.ext3 -j /dev/mmcblk%mmc%p2">Formatting rootfs partition</CMD>
    2.  
      <CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p2"/>
    3.  
      <CMD state="Updater" type="push" body="$ mount -t ext3 /dev/mmcblk%mmc%p2 /mnt/mmcblk%mmc%p2"/>
    4.  
      <CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk%mmc%p2" file="files/linux/sabresd/console/rootfs.tar.bz2">Sending and writting rootfs</CMD>
    5.  
      <CMD state="Updater" type="push" body="frf">Finishing console rootfs write</CMD>
    6.  
      <CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p2">Unmounting rootfs partition</CMD>
    7.  
      <CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>

    这段的目的就是将ext3类型的文件系统放到emmc的UDA的分区2。


    7. 上述分析可以得到如下的文件位置表

    partition

    起始地址(以block为单位)

    对象

    Boot partition 1

    2

    u-boot.imx

    Boot partition 2

    未使用

     

    RPMB partition

    未使用

     

    GPP

    未使用

     

    UDA partition1

    20480

    uImage、 zImage

    UDA partiton2

    1228800

    rootfs

    有几点需要说明:

    A. emmc的物理分区,起始的2个块都是用来存放分区表。

    B. emmc的物理分区,地址是独立的,都是从0开始。


    7. 使用uboot更新uboot

    eMMC的每一个硬件分区都是独立编址的,所以在访问前要先指定访问哪一个分区,具体访问哪一个分区由Extended CSD寄存器决定的。


    每个字段的说明如下:


    有三个区域可以用来存放我们的u-boot,分别是Boot partition1  Boot partition2和UDA区域

    通过mmc dev和mmc partconf来选择我们操作的区域和使能哪个区作为启动分区。


    说明一下mmc dev和mmc partconf的用法:

    mmc dev 2 1

    用户当前可以访问设备2(emmc)的boot partition1分区。

    mmc dev 2 2

    用户当前可以访问设备2(emmc)的boot partition2分区。

    mmc dev 2 0

    用户当前可以访问设备2(emmc)的UDA分区。


    mmc partconf  dev  boot_ack  boot_partition  partition_access

    mmc partconf   2        1                   7                           0

    第一个参数:当前的设备(2对应的是emmc)

    第二个参数:是否需要响应(1对应的返回响应)

    第三个参数:选择启动分区(7对应的时UDA分区)

    第四个参数:当前访问的分区(0对应的是UDA)

    参考Extended CSD寄存器。


    分别使用三个区来存放uboot。

    A. 用boot partition1作为启动分区。

    输入命令:tftp 20000000 u-boot.imx(将文件拷贝到内存的0x20000000起始的地址)

    输入命令:mmc dev 2 1(访问boot1分区)

    输入命令:mmc write 20000000 2 400(将文件写入到boot1分区中)

    输入命令:mmc partconf 2 1 1 1(设置boot1为启动分区)

    测试一下,输入reset,窗口有uboot信息。

    B. 用boot partition2作为启动分区。

    输入命令:tftp 20000000 u-boot.imx(将文件拷贝到内存的0x20000000起始的地址)

    输入命令:mmc dev 2 2(访问boot2分区)

    输入命令:mmc write 20000000 2 400(将文件写入到boot2分区中)

    输入命令:mmc partconf 2 1 2 2(设置boot2为启动分区)

    测试一下,输入reset,窗口有uboot信息。

    C. 用UDA作为启动分区。

    输入命令:tftp 20000000 u-boot.imx(将文件拷贝到内存的0x20000000起始的地址)

    输入命令:mmc dev 2 0(访问UDA分区)

    输入命令:mmc write 20000000 2 400(将文件写入到UDA分区中)

    输入命令:mmc partconf 2 1 7 0(设置UDA为启动分区)

    测试一下,输入reset,窗口有uboot信息。


    对于使用UDA分区需要说明一下,我们已将UDA分区分成两个区,而uboot没有放到这两个区中,而是放到了UDA的起始地址,之前分区的时候,UDA的前面10M的区域没有分区,uboot就是存放在这前面的10M中。

    8. 使用uboot更新kernel

    之前分区的时候将UDA的第一个去分成了FAT,现在修改mksdcard.sh

    1.  
      # partition size in MB
    2.  
      BOOT_ROM_SIZE=10
    3.  
       
    4.  
      # call sfdisk to create partition table
    5.  
      # destroy the partition table
    6.  
      node=$1
    7.  
      dd if=/dev/zero of=${node} bs=1024 count=1
    8.  
       
    9.  
      sfdisk --force -uM ${node} << EOF
    10.  
      ${BOOT_ROM_SIZE},500,0c //分区1从10M开始,大小为500M,为FAT分区
    11.  
      600,,83 //分区2从600M开始,到最后,为Linux分区
    12.  
      EOF

    将0c改为83(将FAT分区改为Linux分区),重新烧写一下emmc。

    我们不使用文件系统来存放文件,直接在emmc中存放uImage。

    重新烧写完程序之后,输入命令:

    mmc dev;mmc part

    窗口输出:

    Partition Map for MMC device 2  --   Partition Type: DOS
    
     
    
    Part    Start Sector    Num Sectors     UUID            Type
    
      1     20480           1024000         00000000-01     83
    
      2     1228800         14041088        00000000-02     83

    可以看到此时的类型为83。


    下面开始烧写kernel:

    输入命令:

     

    tftp 20000000 uImage(将uImage拷贝到内存中)

    输入命令:

    mmc write 20000000 5000 1D90(将uImage烧写到emmc中)

    输入命令:

    setenv bootcmd mmc dev;setenv bootargs console=ttymxc0,115200 root=/dev/mmcblk0p2 rootwait rw;mmc read 18000000 5000 1D90;bootm 18000000(设置环境变量bootcmd,将uImage拷贝到内存18000000中,启动内核)

    最后烧写文件系统:

    https://blog.csdn.net/zuoyioo7/article/details/74529255

    按照上面的链接制作rootfs.ext4文件。

    输入命令:

    tftp 20000000 rootfs.ext4

    输入命令:

    mmc write 20000000 12C000 C8000(将文件系统烧写到UDA分区2)

    整个Linux现在都可以通过uboot来更新了。

  • 相关阅读:
    调试 camera 时记录点滴
    奇偶场的合并&yuv2rgb
    拓宽视野
    Eclipse中看不到jsp的页面效果
    极品函数
    Visual C# 2005中让ComboBox控件显示出多个数据源属
    C#——如何使tableLayoutPanel 不闪烁
    ASP.NET中JSON的序列化和反序列化
    有钱慷慨的管理者,有钱吝啬的管理者,无钱思想慷慨的管理者,无钱思想吝啬的管理者都有各自的下场白
    C# WinForm开发系列 ComboBox
  • 原文地址:https://www.cnblogs.com/fire909090/p/10858201.html
Copyright © 2011-2022 走看看