OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12612|回复: 8

IMX6ULL eMMC启动流程以及分区表分析

[复制链接]

5

主题

120

帖子

0

精华

高级会员

Rank: 4

积分
813
金钱
813
注册时间
2021-2-26
在线时间
117 小时
发表于 2021-3-2 11:24:58 | 显示全部楼层 |阅读模式
拿到一块新板子,或者新平台,势必要对他的启动过程以及分区表进行分析,才可以进行后续的修改以及开发。我这边是eMMC的板子,我们就来看eMMC的启动流程。
1. eMMC启动流程
参见IMX6ULL参考手册8.5.3.2 MMC and eMMC boot章节,简单的来说,上电的时候,ROM code会根据拨码开关去判定启动介质,当拨码开关打到eMMC的时候,会走eMMC启动流程。ROM code会朝eMMC芯片发送指令询问eMMC芯片是否指出boot mode,如果得到的回复是支持,那就会从eMMC的boot分区启动,如果得到的回复是不支持,那就会从eMMC的UDA启动,此时和正常的SD卡启动没区别。详细的过程,有兴趣的同学可以去看参考手册。
eMMC_boot.jpg
板子上所使用的eMMC是三星的 KLM8G1GETF,参见芯片手册可以知道,这是一颗eMMC 5.1规格的芯片,并且支持boot mode,芯片内部包含2个boot分区,boot1和boot2,每个boot分区4MB大小。就以这颗芯片还说,boot时会使用到他的boot分区。
samsung_boot_op.jpg
boot_size.jpg

2. 分区表
eMMC启动流程知道了个大概,那么如何知道分区表呢?一般SoC厂商都会提供空板子烧录code的工具,在这个工具在,会存在分区工具或者分区表的信息。IMX6ULL为例,我们可以从他的mfgtool中的ucl2.xml得到答案。文件路径在<mfgtool/Profiles/Linux/OS Firmware/ucl2.xml>
以下还是eMMC为例,参见注释:
  1. <LIST name="eMMC" desc="Choose eMMC as media">
  2.     <!-- <font color="Red">====> 发送 uboot, kernel zImage, dtb and ramfs 到设备里,然后启动</font> -->
  3.         <CMD state="BootStrap" type="boot" body="BootStrap" file ="firmware/u-boot-imx6ull-14x14-emmc.imx" ifdev="MX6ULL">Loading U-boot</CMD>
  4.                
  5.         <CMD state="BootStrap" type="load" file="firmware/zImage" address="0x80800000"
  6.                 loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6ULL">Loading Kernel.</CMD>

  7.         <CMD state="BootStrap" type="load" file="firmware/fsl-image-mfgtool-initramfs-imx_mfgtools.cpio.gz.u-boot" address="0x83800000"
  8.                 loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6ULL">Loading Initramfs.</CMD>

  9.         <CMD state="BootStrap" type="load" file="firmware/imx6ull-14x14-emmc.dtb" address="0x83000000"
  10.                 loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" ifdev="MX6ULL">Loading device tree.</CMD>

  11.         <CMD state="BootStrap" type="jump" > Jumping to OS image. </CMD>


  12.         <!-- create partition -->
  13.     <!-- <font color="Red">====> 创建分区,可以看到使用的是mksdcard.sh脚本, 该脚本在 <mfgtool/Profiles/Linux/OS Firmware/mksdcard.sh.tar>, 稍后分析他</font> -->
  14.         <CMD state="Updater" type="push" body="send" file="mksdcard.sh.tar">Sending partition shell</CMD>
  15.         <CMD state="Updater" type="push" body="$ tar -xf $FILE "> Partitioning...</CMD>
  16.         <CMD state="Updater" type="push" body="$ sh mksdcard.sh /dev/mmcblk1"> Partitioning...</CMD>

  17.         <!-- burn uboot -->
  18.     <!-- <font color="Red">====> 烧录bootloader(uboot.imx), 分以下几个步骤:
  19.                 1. 清除uboot env, 总归8K,并且跳过了前面768 bytes, 这里是UDA区域,并不是boot1,boot2
  20.                 2. 打开boot1区域的写入权限, 把uboot.imx写进去,并且跳过了前面1024 bytes(1K),最后关闭boot1区域的写入权限
  21.                 3. 打开boot1分区的boot功能
  22.                 可以看到,这里是以RAW data的形式写入的,并没有做任何分区格式化。</font> -->
  23.         <CMD state="Updater" type="push" body="$ dd if=/dev/zero of=/dev/mmcblk1 bs=1k seek=768 conv=fsync count=8">clear u-boot env</CMD>
  24.         <CMD state="Updater" type="push" body="$ echo 0 > /sys/block/mmcblk1boot0/force_ro">access boot partition 1</CMD>
  25.         <CMD state="Updater" type="push" body="send" file="files/boot/u-boot-imx6ull-14x14-ddr%ddr%-emmc.imx" ifdev="MX6ULL">Sending u-boot.bin</CMD>
  26.         <CMD state="Updater" type="push" body="$ dd if=$FILE of=/dev/mmcblk1boot0 bs=512 seek=2">write U-Boot to sd card</CMD>
  27.         <CMD state="Updater" type="push" body="$ echo 1 > /sys/block/mmcblk1boot0/force_ro"> re-enable read-only access </CMD>
  28.         <CMD state="Updater" type="push" body="$ mmc bootpart enable 1 1 /dev/mmcblk1">enable boot partion 1 to boot</CMD>

  29.         <!-- format and mount boot partition -->
  30.     <!-- <font color="Red">====> 烧录kernel和dtb,分以下几个步骤:
  31.                 1. 等待/dev/mmcblk1p1就绪
  32.                 2. 将/dev/mmcblk1p1格式化成FAT32
  33.                 3. 挂载/dev/mmcblk1p1 到 /mnt/mmcblk1p1
  34.                 4. 复制 zImage和dtbs 到 /mnt/mmcblk1p1
  35.                 5. 同步写入,并且取消挂载
  36.                 可以看到,boot分区,存放了kernel和dtb,该分区是FAT32格式。</font> -->
  37.         <CMD state="Updater" type="push" body="$ while [ ! -e /dev/mmcblk1p1 ]; do sleep 1; echo "waiting..."; done ">Waiting for the partition ready</CMD>
  38.         <CMD state="Updater" type="push" body="$ mkfs.vfat -F 32 /dev/mmcblk1p1">Formatting rootfs partition</CMD>
  39.         <CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk1p1"/>
  40.         <CMD state="Updater" type="push" body="$ mount -t vfat /dev/mmcblk1p1 /mnt/mmcblk1p1"/>

  41.         <!-- burn zImage -->
  42.         <CMD state="Updater" type="push" body="send" file="files/boot/zImage">Sending kernel zImage</CMD>
  43.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/zImage">write kernel image to sd card</CMD>

  44.         <!-- burn dtb -->
  45.         <CMD state="Updater" type="push" body="send" file="files/boot/imx6ull-alientek-emmc.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
  46.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-alientek-emmc.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>
  47.       
  48.         <CMD state="Updater" type="push" body="send" file="files/boot/imx6ull-14x14-emmc-4.3-800x480-c.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
  49.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-14x14-emmc-4.3-800x480-c.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>

  50.         <CMD state="Updater" type="push" body="send" file="files/boot/imx6ull-14x14-emmc-7-800x480-c.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
  51.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-14x14-emmc-7-800x480-c.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>

  52.         <CMD state="Updater" type="push" body="send" file="files/boot/imx6ull-14x14-emmc-7-1024x600-c.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
  53.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-14x14-emmc-7-1024x600-c.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>

  54.         <CMD state="Updater" type="push" body="send" file="files/boot/imx6ull-14x14-emmc-10.1-1280x800-c.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
  55.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-14x14-emmc-10.1-1280x800-c.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>
  56.       
  57.         <CMD state="Updater" type="push" body="send" file="files/boot/imx6ull-14x14-emmc-hdmi.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
  58.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-14x14-emmc-hdmi.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>
  59.       
  60.         <CMD state="Updater" type="push" body="send" file="files/boot/imx6ull-14x14-emmc-vga.dtb" ifdev="MX6ULL">Sending Device Tree file</CMD>
  61.         <CMD state="Updater" type="push" body="$ cp $FILE /mnt/mmcblk1p1/imx6ull-14x14-emmc-vga.dtb" ifdev="MX6ULL">write device tree to eMMC card</CMD>
  62.       
  63.         <CMD state="Updater" type="push" body="$ sleep 1">delay</CMD>
  64.         <CMD state="Updater" type="push" body="$ sync">Sync...</CMD>
  65.         <CMD state="Updater" type="push" body="$ umount /mnt/mmcblk1p1">Unmounting vfat partition</CMD>

  66.         <!-- format and mount rootfs partition -->
  67.     <!-- <font color="Red">====> 烧录根文件系统,这里和上面kernel,dtb一样,只不过分区格式换成了ext3/4</font> -->
  68.         <CMD state="Updater" type="push" body="$ mkfs.ext3 -F -E nodiscard /dev/mmcblk1p2">Formatting rootfs partition</CMD>
  69.         <CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk1p2"/>
  70.         <CMD state="Updater" type="push" body="$ mount -t ext3 /dev/mmcblk1p2 /mnt/mmcblk1p2"/>

  71.         <!-- burn rootfs -->
  72.         <CMD state="Updater" type="push" body="pipe tar -jxv -C /mnt/mmcblk1p2" file="files/filesystem/rootfs.tar.bz2" ifdev="MX6ULL">Sending and writting rootfs</CMD>
  73.         <CMD state="Updater" type="push" body="frf">Finishing rootfs write</CMD>
  74.         <CMD state="Updater" type="push" body="send" file="files/modules/modules.tar.bz2" ifdev="MX6ULL">Sending Modules file</CMD>
  75.         <CMD state="Updater" type="push" body="$ mkdir -p /mnt/mmcblk1p2/lib/modules">Mkdir -p /mnt/mmcblk1p2/lib/modules</CMD>
  76.         <CMD state="Updater" type="push" body="$ tar jxf $FILE -C /mnt/mmcblk1p2/lib/modules/" ifdev="MX6ULL">tar Modules file</CMD>
  77.         <CMD state="Updater" type="push" body="$ sleep 1">delay</CMD>
  78.         <CMD state="Updater" type="push" body="$ sync">Sync...</CMD>
  79.         <CMD state="Updater" type="push" body="$ umount /mnt/mmcblk1p2">Unmounting rootfs partition</CMD>
  80.         <CMD state="Updater" type="push" body="$ echo Update Complete!">Done</CMD>
  81.   </LIST>
复制代码


继续,我们来分析mksdcard.sh

  1. #!/bin/sh

  2. <font color="Red">#  ====> 下面都是一些准备工作,可以略过</font>
  3. # partition size in MB
  4. BOOT_ROM_SIZE=10

  5. # wait for the SD/MMC device node ready
  6. while [ ! -e $1 ]
  7. do
  8. sleep 1
  9. echo “wait for $1 appear”
  10. done

  11. <font color="Red"># ====> 从这里开始,才是真正的分区动作</font>
  12. # call sfdisk to create partition table
  13. # destroy the partition table
  14. node=$1                <font color="Red"># ====> 以eMMC为例,这里是 /dev/mmcblk1</font>
  15. dd if=/dev/zero of=${node} bs=1024 count=1 <font color="Red">       #  ====> 将eMMC的前面1K全部写0,实际上是清空分区表</font>

  16. # ====> <font color="Red">这里使用了sfdisk工具来进行分区</font>
  17. sfdisk --force ${node} << EOF
  18. ${BOOT_ROM_SIZE}M,128M,c        <font color="Red"># 分区1, 从10M位置开始, 分区大小128M, 这里是一个W96 FAT32(LBA)分区</font>
  19. 138M,,83                                        <font color="Red"># 分区2, 从138M开始, 用完所剩余的容量, 这里是一个Linux分区, 83表示MBR下的Linux分区</font>
  20. write
  21. EOF

复制代码
可以看到,在分区的时候,跳过了头上10M的位置,这10M为不支持boot mode的芯片准备的。然后分了一个128M的FAT32分区,这个分区会被格式化长FAT32,存放kernel和dtb,一个剩余全部空间的Linux分区,这个linux分区,最终会被格式化成ext3/4,存放rootfs


3. 最终的分区表
emmc_partition.jpg




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

50

主题

385

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1126
金钱
1126
注册时间
2014-8-24
在线时间
146 小时
发表于 2021-3-10 06:57:42 | 显示全部楼层
找一份喜欢的工作,这样每天工作的8个小时是快乐的。 找一个喜欢的人,这样每天工作之外的16个小时也是快乐的。
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
309
金钱
309
注册时间
2013-6-19
在线时间
111 小时
发表于 2021-6-15 13:38:40 | 显示全部楼层
大牛,顶顶顶起,请问你有相关的工作号之类的东西么,想持续关注跟着您的脚步学习。
回复 支持 反对

使用道具 举报

2

主题

712

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2178
金钱
2178
注册时间
2018-8-27
在线时间
258 小时
发表于 2021-6-16 09:51:15 | 显示全部楼层
顶一波!
回复 支持 反对

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2021-3-15
在线时间
5 小时
发表于 2021-6-18 17:27:55 | 显示全部楼层
请问大牛,如果想把EMMC加大,比如从8G扩到16G,需要做那些工作
回复 支持 反对

使用道具 举报

5

主题

120

帖子

0

精华

高级会员

Rank: 4

积分
813
金钱
813
注册时间
2021-2-26
在线时间
117 小时
 楼主| 发表于 2021-6-21 14:51:05 | 显示全部楼层
Emo 发表于 2021-6-18 17:27
请问大牛,如果想把EMMC加大,比如从8G扩到16G,需要做那些工作

eMMC和SD一样,把板载eMMC吹下来,吹一颗新的上去。进到下载模式下载固件,启动。
回复 支持 反对

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
30
金钱
30
注册时间
2021-3-15
在线时间
5 小时
发表于 2021-6-22 14:43:13 | 显示全部楼层
jckimi 发表于 2021-6-21 14:51
eMMC和SD一样,把板载eMMC吹下来,吹一颗新的上去。进到下载模式下载固件,启动。

UBOOT不用修改吗?
回复 支持 反对

使用道具 举报

5

主题

120

帖子

0

精华

高级会员

Rank: 4

积分
813
金钱
813
注册时间
2021-2-26
在线时间
117 小时
 楼主| 发表于 2021-6-23 09:43:07 | 显示全部楼层
Emo 发表于 2021-6-22 14:43
UBOOT不用修改吗?

不用,emmc和sd卡一样,换不同品牌,不同容量的SD卡需要修改uboot吗?
回复 支持 反对

使用道具 举报

1

主题

6

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2019-8-8
在线时间
5 小时
发表于 2022-12-31 20:38:02 | 显示全部楼层
mark!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 07:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表