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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM