制作imx6ull Linux系统的img镜像

  • Post author:
  • Post category:linux


制作imx6ull Linux系统的img镜像

参考链接:

https://blog.csdn.net/qingtian11112/article/details/99825257

相信玩过树莓派或者香橙派的人都知道,我们利用SD卡启动Linux系统的时候,是将官网提供的img镜像通过Win32 Disk Imager软件将img镜像烧写到SD卡,然后启动系统的。imx6ull我们常用的就是通过USB刷机,也就是通过mfgtools工具将uboot kernel dtb rootfs这些文件烧写到emmc nandflash sd卡等存储介质上面。但是这种方法的缺点是烧写比较慢,而且只能一个一个刷写,官方推荐的量产烧写方式是通过SD卡刷机,就是把SD卡做成启动盘,然后启动系统,再把内容烧录到emmc或者nand flash里面。

我们看到官方提供的SD卡烧录方式有两种,一是通过USB把系统刷到SD卡里面,另一种方法是通过读卡器将SD卡插入到Linux主机,然后对SD卡进行分区建立文件系统等操作,从而制作一个可以启动的SD卡,这里介绍一种将uboot kernel dtb rootfs打包成img镜像,然后通过Win32 Disk Imager烧录的方法。

如果需要通过读卡器将SD卡接入Linux主机进行烧录,请看

野火


img文件可以简单理解为一个磁盘,可以存放二进制数据,可以进行分区,可以建立文件系统等操作。

我们从NXP的SD卡固件里面可以提取到分区信息,不同分区里面存储了不同的文件,有的分区还有文件系统。利用USB将系统刷到SD卡里面,然后用读卡器插到电脑上,打开电脑的 磁盘管理 ,就可以看到分区信息了,也可以看一下,下面用表格列:

分区序号 起始地址 大小 内容 文件系统
1 0 10M u-boot.imx
2 10x1024x1024 500M zImage imx6ull-14×14-evk.dtb fat
3 600x1024x1024 总大小减去600M rootfs ext4

为什么内核和设备树需要500M的空间?为什么uboot和内核设备树只占用510M,文件系统要从600M开始?这里暂时不讨论。

了解了 SD 卡系统的分区结构以后,我们的要做的工作其实就很显而易见了。

1,根据固件的大小建立一个合适的 img 空文件

2,对 img 文件进行分区

3,将 img 文件虚拟挂载在 /dev/loopx 下面(这样我们就可以像 /dev/mmcblk 一样操作了)

4,在/dev/loopx下面建立文件系统并且 mount 上来

5,使用 dd 命令烧录 uboot,使用文件复制命令将 zImage dtb rootfs 放到指定的文件系统

6,取消挂载,复制文件,烧录到 SD 卡

下面开始制作img镜像



准备工作

需要安装的软件

sudo apt-get install dosfstools dump parted kpartx

建立工作目录

mkdir myimg
cd myimg
mkdir boot #这个文件夹用于挂载内核的分区
mkdir root #这个文件夹用于挂载文件系统分区

复制需要的文件

u-boot.imx  #uboot文件
zImage		#内核hernel 文件名必须是这个
imx6ull-14x14-evk.dtb	#设备树文件 文件名必须是这个 因为uboot中需要读取这个文件,我们可以将自己的设备树文件复制过来然后改成这个名字
rootfs.tar.bz2	#文件系统 文件名不限

复制完文件后我们的工作目录下面的内容

在这里插入图片描述



创建空白 img 文件

首先要知道系统固件的大小,计算方式为 600M+rootfs大小,如果我们的文件系统是压缩包的话,需要先知道文件系统的大小,可以先解压到一个文件夹,然后使用 du rootfs_dir -s -h 命令查看文件夹大小。

在这里插入图片描述

我这里文件系统大小为 243M ,所以 img 镜像文件最小为 600M+243M=843M,我们在创建的时候要比这个大,笔者这里创建 1G 大小的镜像文件。

dd if=/dev/zero of=imx6ull.img bs=512 count=2097152

在这里插入图片描述

of=imx6ull.img 表示输出文件为 imx6ull.img

bs=512 扇区是 512 字节

count=2097152 表示扇区的数量 1G/512Byte=2097152

到这里我们的空镜像文件就已经创建好了



对 img 文件进行分区

分区的大小现在已经确定了

sudo parted imx6ull.img --script -- mklabel msdos
sudo parted imx6ull.img --script -- mkpart primary fat32 20480s 1044479s
sudo parted imx6ull.img --script -- mkpart primary ext4 1228800s -1

fat32 文件系统类型为 fat32 这是内核设备树的文件系统

20480s 这个表示内核设备树扇区的起始地址(注意不是实际地址,扇区地址x扇区大小=实际地址),这个分区紧跟在 10M 的 u-boot 空间后面,地址为 10x1024x1024/512 = 20480

1044479s 内核设备树扇区的结束地址=扇区起始地址+扇区大小-1,20480+500

1024

1024/512-1 = 1044479

ext4 文件系统为 ext4 这是根文件系统的

1228800s 文件系统的扇区起始地址 600x1024x1024/512 = 1228800

文件系统的结束地址不填

检查分区是否成功

sudo parted imx6ull.img

输入命令后在终端输入 print free 进行打印,输入 q 退出

在这里插入图片描述



将镜像文件虚拟成块设备

sudo losetup -f --show imx6ull.img

在这里插入图片描述

我们需要将这里的 loop0 记录下来,在后面会使用,如果读者这里不是 loop0 ,以自己电脑的实际情况为准

这里我们的 /dev/loop0 就是我们的镜像文件,可以进行操作,但是这里还看不到我们的分区信息,没法对里面的分区进行操作,所以还需要挂载虚拟文件系统

sudo kpartx -va /dev/loop0

以上命令执行完成后,就会看到 /dev/mapper/ 下面出现了 loop1 的两个分区内容

在这里插入图片描述

这里 loop0p1 就是内核设备树的分区 loop0p2 就是根文件系统分区



格式化块设备并且挂载

格式化分区

sudo mkfs.vfat /dev/mapper/loop0p1	#建立文件系统 存放 kernel dtb
sudo mkfs.ext4 /dev/mapper/loop0p2	#建立文件系统 存放 rootfs

在这里插入图片描述

mount 挂载

我们在之前已经创建了 boot 和 root 文件夹,将两个分区挂载到对应的文件夹

sudo mount /dev/mapper/loop0p1 ./boot/
sudo mount /dev/mapper/loop0p2 ./root/

想退出的话,可以使用 kpartx -dv /dev/loopX 写卸载刚才挂接的东西。然后再使用losetup -d /dev/loopX断掉和映像文件的挂接关系。



烧录和复制对应的文件



u-boot.imx

u-boot 由于没有文件系统,所以需要使用 dd 命令,我们使用 dd 命令操作 /dev/loop0 就可以了

sudo dd if=u-boot.imx of=/dev/loop0 bs=512 seek=2 conv=fsync

在这里插入图片描述



zImage imx6ull-14×14-evk.dtb

sudo cp zImage imx6ull-14x14-evk.dtb ./boot/

在这里插入图片描述



rootfs

如果是打包的文件系统,我们直接解压到对应文件夹即可

sudo tar -jvxf rootfs.tar.bz2 -C ./root/

在这里插入图片描述



取消挂载

取消挂载有两部分,一是 boot 和 root 文件夹的取消挂载,二是 /dev/mapper/loop0p* 和 /dev/loop0 的取消挂载,删除loopdevice

sudo umount ./boot ./root
sudo kpartx -d /dev/loop0
sudo losetup -d /dev/loop0



复制文件并烧录

将 SD 卡通过读卡器接入到电脑,然后打开 Win32 Disk Imager 软件,打开我们刚刚创建的 img 文件,选择 SD 卡对应的磁盘,然后烧录。

烧录完成将 SD 卡插入板卡,选择 SD 启动即可。

大功告成。



版权声明:本文为mzy2364原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。