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中的分區
-
<!-- create partition -->
-
<CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD>
-
<CMD state="Updater" type="push" body="$ tar xf $FILE "> Partitioning...</CMD>
-
<CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk%mmc%"> Partitioning...</CMD>
#!/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的位置
-
<!-- burn uboot -->
-
<CMD state="Updater" type="push" body="send" file="files/linux/sabresd/u-boot.imx" ifdev="MX6D">Sending u-boot.bin</CMD>
-
<CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk%mmc%boot0/force_ro">access boot partition 1</CMD>
-
<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的位置
-
<CMD state="Updater" type="push" body="$ mkfs.vfat /dev/mmcblk%mmc%p1">Formatting rootfs partition</CMD>
-
<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p1"/>
-
<CMD state="Updater" type="push" body="$ mount -t vfat /dev/mmcblk%mmc%p1 /mnt/mmcblk%mmc%p1"/>
-
<CMD state="Updater" type="push" body="send" file="files/linux/sabresd/uImage" ifdev="MX6D">Sending and writting uImage</CMD>
-
<CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk%mmc%p1/uImage">write kernel image to sd card</CMD>
-
<CMD state="Updater" type="push" body="send" file="files/linux/sabresd/zImage" ifdev="MX6D">Sending and writting uImage</CMD>
-
<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的位置
-
<CMD state="Updater" type="push" body="$ mkfs.ext3 -j /dev/mmcblk%mmc%p2">Formatting rootfs partition</CMD>
-
<CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk%mmc%p2"/>
-
<CMD state="Updater" type="push" body="$ mount -t ext3 /dev/mmcblk%mmc%p2 /mnt/mmcblk%mmc%p2"/>
-
<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>
-
<CMD state="Updater" type="push" body="frf">Finishing console rootfs write</CMD>
-
<CMD state="Updater" type="push" body="$ umount /mnt/mmcblk%mmc%p2">Unmounting rootfs partition</CMD>
-
<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
-
# 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
將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來更新了。