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来更新了。

原文地址:https://www.cnblogs.com/fire909090/p/10858201.html