转载地址:https://blog.youkuaiyun.com/u011371090/article/details/80816449
参考链接地址:
https://blog.youkuaiyun.com/u014645605/article/details/52212622
http://blog.sina.com.cn/s/blog_9864c64a0102xpte.html
https://blog.youkuaiyun.com/abcamus/article/details/59705763
https://blog.youkuaiyun.com/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 KaTeX parse error: Expected 'EOF', got '&' at position 14: FILE "</span>&̲gt;</span> Part… 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
<
/
s
p
a
n
>
d
d
<
s
p
a
n
c
l
a
s
s
=
"
h
l
j
s
−
k
e
y
w
o
r
d
"
>
i
f
<
/
s
p
a
n
>
=
/
d
e
v
/
z
e
r
o
o
f
=
<
s
p
a
n
c
l
a
s
s
=
"
h
l
j
s
−
v
a
r
i
a
b
l
e
"
>
1</span> dd <span class="hljs-keyword">if</span>=/dev/zero of=<span class="hljs-variable">
1</span>dd<spanclass="hljs−keyword">if</span>=/dev/zeroof=<spanclass="hljs−variable">{node} bs=1024 count=1
sfdisk --force -uM KaTeX parse error: Expected 'EOF', got '&' at position 15: {node}</span> &̲lt;< EOF <sp…{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=KaTeX parse error: Expected 'EOF', got '&' at position 10486: …p><p><strong>4.&̲nbsp;<span styl… 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
F
I
L
E
/
m
n
t
/
m
m
c
b
l
k
FILE /mnt/mmcblk%mmc%p1/uImage"</span>&gt;</span>write kernel image to sd card<span class="hljs-tag">&lt;/<span class="hljs-name">CMD</span>&gt;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">CMD</span> <span class="hljs-attr">state</span>=<span class="hljs-string">"Updater"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"push"</span> <span class="hljs-attr">body</span>=<span class="hljs-string">"send"</span> <span class="hljs-attr">file</span>=<span class="hljs-string">"files/linux/sabresd/zImage"</span> <span class="hljs-attr">ifdev</span>=<span class="hljs-string">"MX6D"</span>&gt;</span>Sending and writting uImage<span class="hljs-tag">&lt;/<span class="hljs-name">CMD</span>&gt;</span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">CMD</span> <span class="hljs-attr">state</span>=<span class="hljs-string">"Updater"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"push"</span> <span class="hljs-attr">body</span>=<span class="hljs-string">"
FILE/mnt/mmcblk 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
<
/
d
i
v
>
<
/
d
i
v
>
<
/
l
i
>
<
l
i
>
<
d
i
v
c
l
a
s
s
=
"
h
l
j
s
−
l
n
−
n
u
m
b
e
r
s
"
>
<
d
i
v
c
l
a
s
s
=
"
h
l
j
s
−
l
n
−
l
i
n
e
h
l
j
s
−
l
n
−
n
"
d
a
t
a
−
l
i
n
e
−
n
u
m
b
e
r
=
"
7
"
>
<
/
d
i
v
>
<
/
d
i
v
>
<
d
i
v
c
l
a
s
s
=
"
h
l
j
s
−
l
n
−
c
o
d
e
"
>
<
d
i
v
c
l
a
s
s
=
"
h
l
j
s
−
l
n
−
l
i
n
e
"
>
d
d
i
f
=
/
d
e
v
/
z
e
r
o
o
f
=
1</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">dd if=/dev/zero of=
1</div></div></li><li><divclass="hljs−ln−numbers"><divclass="hljs−ln−linehljs−ln−n"data−line−number="7"></div></div><divclass="hljs−ln−code"><divclass="hljs−ln−line">ddif=/dev/zeroof={node} bs=1024 count=1
-
-
sfdisk --force -uM
KaTeX parse error: Expected 'EOF', got '&' at position 31: …ass="hljs-tag">&̲lt;< <span c…{
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.youkuaiyun.com/zuoyioo7/article/details/74529255
按照上面的链接制作rootfs.ext4文件。
输入命令:
tftp 20000000 rootfs.ext4
输入命令:
mmc write 20000000 12C000 C8000(将文件系统烧写到UDA分区2)
整个Linux现在都可以通过uboot来更新了。