文章目录

  • 目的
  • 原理
  • 环境准备
  • 系统镜像制作
    • 从现有SD卡备份
    • 从空白文件开始制作
  • 系统镜像使用
  • 其它补充
  • 总结

目的

嵌入式Linux在开发过程中对于软件方面通常是 bootloader、linux kernel、rootfs、applications
分开进行处理的,但到了生产阶段这样就不方便了。比较常见的做法是将所有内容整合到一起制作成系统镜像,这样在生产的时候只要烧录系统进行即可。这篇文件将介绍基于SD卡的系统镜像制作方法。

原理

制作系统镜像的原理非常简单: 系统等内容无非就是一堆放在SD卡上的数据,那么只要保持这些数据在SD卡上分布,原模原样拷贝成一个文件,那这个文件就是系统镜像了。使用时只要将该文件原模原样写入到SD卡上就行。

原理就是上面那样,对于SD卡而言想要更好的制作系统镜像了解一下SD卡的数据分布会更加好:

通常嵌入式Linux系统比较常见的会有两个分区: boot分区 和 root分区。

对于SD卡而言通常从头开始的1M空间是预留的,不会用作分区,并且其中最开头的512字节是主引导区,千万不要随意修改其中内容。主引导区后面的(1M - 512)字节空间很多时候会被用来存放 bootloader(uboot) 。当然这个是看芯片的,很多芯片如果从SD卡启动的话,会从SD卡指定地址读取程序并启动,通常这个地址介于 512~1M 之间的。

boot分区通常从1M往后分布,一般不需要很大,并且通常都是FAT32格式的。boot分区用于存放内核镜像、设备树、内核启动参数文件等。有些芯片的 bootloader(uboot) 也是放在这个分区上的。

root分区通常挨着boot分区往后分布,这个分区一般会设置的大一些,分区格式用到也比广泛,比较常见的使用EXT4格式。root分区用于存放根文件系统和用户应用程序等。

根据上面的原理通常制作基于SD卡的嵌入式Linux系统镜像制作可以分为两种方式:

  • 从现有SD卡备份
    先把所有要用到的内容都烧录到SD卡上,使之可以在设备上正常运行。然后取出SD卡,从头开始备份数据生成镜像文件。
  • 从空白文件开始制作
    从空白文件开始对其分区,然后导入各部分对应内容来制作系统镜像。

环境准备

下载安装Ubuntu Desktop(这里使用版本为20.04.4):
https://ubuntu.com/download/desktop

安装完成后进行基础环境安装与设置:

sudo apt update
sudo apt install -y build-essential
sudo apt install -y kpartx
sudo apt install -y gparted

以下根据需求安装:

sudo apt install -y openssh-server

如果使用虚拟机的话为了方便可以开启共享粘贴板、共享目录以及桥接网络。


如果是 从现有SD卡备份 ,并且所有数据都是在boot分区和root分区中的话,可以直接在Windows上操作,主要需要用到下面两个软件:
DiskGenius:http://www.diskgenius.cn
Win32 Disk Imager:https://win32diskimager.org/

系统镜像制作

从现有SD卡备份

首先将SD卡插入电脑上,使用 dh -h 命令或是 GParted 工具查看SD卡分区分布:


上面是两个不同的嵌入式Linux设备的SD卡内容分布。

对于第一个图的SD卡而言,在备份前要稍作调整。从图上可以看到该SD卡中rootfs分区占满了SD卡剩余的空间(14.58GiB),但是实际上才使用了(2.50GiB)。这种情况下使用备份方式制作的系统镜像体积会很大。所以需要对该分区大小进行调整。

(注意该操作可能会不可逆的损坏系统!!!)在 GParted 工具中选中rootfs分区,(如已挂载,右键 Unmount 卸载该分区),右键 Resize/Move 调整分区大小,大小根据需要而定,也不能设置的太小,对于上面清明而言设置为5GiB大小基本就够用了。调整大小后需要点击上面的 来套用更改

接下来就可以在终端中通过 dd 命令来备份制作系统镜像了:

# 先将SD卡插入Ubuntu中
# 使用 lsblk 查看SD卡设备号sdX
# 我这里显示为sdb,下面均以此进行说明# 如果已经分过区了那么Ubuntu可能会自动挂载
# 逐条使用 sudo umount /dev/sdbn 进行卸载
# 比如上面只有两个分区就用 sudo umount /dev/sdb1 和 sudo umount /dev/sdb2 # 创建镜像文件
touch image.bin
# 将SD卡中有用的数据写入到镜像文件中
# 对于上面第一个SD卡而言大小可以设置为如下
# 1M + 4M + 256M(boot) + 5*1024M(rootfs调整后大小) + 2M(多拷贝点,防止不明意外)
# 对于上面第二个SD卡而言大小可以设置为如下
# 1M + 40M(boot) + 160M(rootfs) + 2M(多拷贝点,防止不明意外)
# 将if后设备中数据从头开始拷贝到of后文件中,count表示拷贝大小,单位由bs指定
# 数据比较大会花点时间
sudo dd if=/dev/sdb of=image.bin bs=1M count=203 status=progress# 系统镜像比较大,可以压缩为zip格式来减少大小
# zip image.zip image.bin
# 有些时候使用xz方式压缩体积可能会小很多

这个方法操作比较简单,不过有时候可能会有问题,特别是前面哪种需要调整分区大小的情况下出现问题的概率会更加频繁些。


如果所有数据都是在boot分区和root分区中的话,可以直接在Windows上操作,使用 DiskGenius 来调整分区大小,使用 Win32 Disk Imager 读取已分配分区来创建系统镜像。

从空白文件开始制作

从空白文件制作主要过程如下:

  • 建立一个空文件;
  • 作为块设备挂载;
  • 进行分区;
  • 向各个分区拷贝需要的文件;
  • 根据需求向头部添加bootloader;
# 创建镜像文件
touch image.bin
# 向镜像文件写入空数据固定大小
dd if=/dev/zero of=image.bin bs=1M count=235# 查看可用的设备挂载点
sudo losetup -f
# 我这里显示 /dev/loop13,接下来都以此进行说明# 将镜像文件挂载到 /dev/loop13
sudo losetup /dev/loop13 image.bin # 对挂载的设备进行分区
sudo fdisk /dev/loop13
# 下面是我新建的两个分区的输入情况
# n回车  回车(p)  回车(1)  回车(2048)  +32M回车  (如果有额外提示则Y回车)
# n回车  回车(p)  回车(2)  回车(67584) +200M回车  (如果有额外提示则Y回车)
# 接着 a回车 1回车 (将分区1设置为可启动)
# 输入 w 回车保存退出,会有点问题提示不用管# 更新分区表
sudo kpartx -av /dev/loop13# 格式化分区建立文件系统
sudo mkfs.vfat /dev/mapper/loop13p1 -n boot
sudo mkfs.ext4 /dev/mapper/loop13p2 -L rootfs# 挂载boot分区
sudo mount /dev/mapper/loop13p1 /mnt/
# 用喜欢的方式向里拷贝内核镜像、设备树、内核启动参数文件等
# sudo rsync -a src/ /mnt/ --progress
# sudo cp -rfp src/* /mnt/
sync
sudo umount /dev/mapper/loop13p1# 挂载root分区
sudo mount /dev/mapper/loop13p2 /mnt
# 用喜欢的方式向里拷贝根文件系统、用户应用程序等
# sudo rsync -a src/ /mnt/ --progress
# sudo cp -rfp src/* /mnt/
sync
sudo umount /dev/mapper/loop13p2# 卸载设备
sudo kpartx -d /dev/loop13
sudo losetup -d /dev/loop13# 如果头部有bootloader,则写入bootloader
# bs=512 seek=1用于跳过头部512字节(具体需要跳过多少是需要根据芯片而定的)
# sudo dd if=bootloader.bin  of=image.bin bs=512 seek=1 conv=notrunc
# 也可以从现有的SD卡复制bootloader
# 有的芯片bootloader默认需要使用官方提供的工具来烧写,因为会在头部加入DDR参数等内容,这种时候用这个方法就比较合适
# sudo dd if=/dev/sdb of=image.bin bs=512 seek=1 count=2047 conv=notrunc
# 注意conv=notrunc选项参数一定不能漏# 系统镜像比较大,可以压缩为zip格式来减少大小
# zip image.zip image.bin
# 有些时候使用xz方式压缩体积可能会小很多

系统镜像使用

在Linux上可以直接使用 dd 命令将镜像文件写入SD卡中:

# 如果分区已挂载到别的地方先进行卸载
# sudo umount /dev/sdb1
# sudo umount /dev/sdb2# 解压镜像文件压缩包
# unzip image.zip
# 将镜像文件写入SD卡,写入可能较慢
sudo dd if=image.bin of=/dev/sdb bs=1M

当然我更加推荐使用工具来烧录,这里 推荐使用 BalenaEtcher 工具 ,这个工具支持windos、macos、linux,其官方页面和项目地址分别如下:
https://www.balena.io/etcher/
https://github.com/balena-io/etcher

其它补充

有时候可能完全按照上面方式操作可能镜像烧录后无法正常运行,比如树莓派CM4模块使用目前版本的系统(Raspberry Pi OS Lite(32-bit) 2022-04-04),不管用上面哪种方式操作都有问题,启动后无法挂载分区。检查相关位置发现现在系统中使用PARTUUID来指定要挂载的分区,我是用 sudo blkid 查看PARTUUID,然后修改相关位置( /boot/cmdline.txt/etc/fstab ),结果也没法正常启动。

上面情况下目前发现可行的方案是不调整分区大小的情况下使用 Win32 Disk Imager 整卡备份,生成的镜像烧录到同型号的或是更大容量规格的SD卡上使用就没问题。如果觉得镜像大的话可以对镜像文件进行压缩, BalenaEtcher 可以直接使用压缩包来烧录。

总结

上面介绍了基于SD卡的嵌入式Linux系统镜像制作,了解原理后其实过程并不复杂。
如果是基于Flash情况,制作镜像的过程也差不多,主要的差异是空间分布的不同,完全可以根据各自的情况来制作。

嵌入式Linux系统镜像制作(基于SD卡)相关推荐

  1. 嵌入式Linux磁盘(硬盘、SD卡)读写性能测试

    背景 在Windows下有一些磁盘基准测试工具,用于测试硬盘/SD卡的读写速度,如ATTO Disk Benchmark(注:单词「benchmark」就是基准检查的意思). 上一篇文章「市面常见存储 ...

  2. 《嵌入式Linux系统开发:基于 Yocto Project》笔记

    写在前面 这本书的"译者序"里面有这么一句话: 市面上不缺乏适用于各种开发语言的开发.编译和打包工具,但在Yocto项目出现前,这些零散的工作需要嵌入式开发者自己串起来以交付最终的 ...

  3. 荔枝派Zero | 全志V3s 开发教程(一) 烧录系统镜像的方法以及如何烧录主线Linux系统镜像

    荔枝派Zero | 全志V3s 开发教程(一) 荔枝派Zero的开发教程: http://zero.lichee.pro/系统开发/type.html 刚开始尝试编译Camdroid官方SDK,最终浪 ...

  4. Jetson Xavier NX 的SD卡系统镜像制作

    Jetson Xavier NX 的SD卡系统镜像制作 一.SD卡系统查看 二.系统镜像制作 三.系统镜像烧录 一.SD卡系统查看 现有的SD卡的内存为128G,其中64G内存并未分配. # 安装gp ...

  5. 详解基于busybox、dropbear、ngnix制作完整的嵌入式Linux系统

    说明:         <一>:查看此博文,建议查看笔者上一篇博文(Linux启动过程),因为只有在完全了解Linux系统启动流程及一些配置文件的相关性,在阅读此博文才能有思路,理解起来更 ...

  6. 嵌入式Linux串口终端的定制,基于PC/104平台嵌入式Linux系统定制方法

    基于PC/104平台的嵌入式Linux技术在海洋自动观测系统中具有广泛的应用前景,Linux定制方法的研究是嵌入式Linux系统研制的关键工作.本文结合PC/104平台嵌入式Linux系统的研制,详细 ...

  7. 为荔枝派Zero制作Linux系统镜像[转]

    最近购入了一块LicheePi Zero开发板,使用全志V3s作为主控芯片.本文介绍如何从零开始为荔枝派制作一个可以启动的Linux系统镜像. 配置编译环境 本文所有编译工作均基于Ubuntu 20. ...

  8. 基于qemu-riscv从0开始构建嵌入式linux系统ch10. qemu之virtio与fw_cfg

    基于qemu-riscv从0开始构建嵌入式linux系统ch10. qemu之virtio与fw_cfg 上一节我们已经基本完成了uboot的移植,下一步自然就是移植linux kernel.在真实的 ...

  9. sock 文件方式控制宿主机_基于嵌入式Linux系统实现YAFFS2文件系统存储方案的设计...

    随着嵌入式技术的不断发展,嵌入式系统的应用越来越广泛,人们对于嵌入式系统功能的要求也越来越高,相应地其大容量数据存储和管理变得越来越重要.相对硬盘而言,FLASH等非易失性存储器具有体积小.功耗低.成 ...

最新文章

  1. PHP函数--var_dump
  2. 浏览器打不开网页,但是还可以聊qq?
  3. WinHEC(Windows硬件project产业创新峰会)将2015回归
  4. 划分数据集代码(按照4:1的比例)以及根据各自文件名写入txt文件
  5. git reset, git checkout, git revert 区别 (译)
  6. 50-00-010-配置-kylin-2.6.0官网配置
  7. 普中科技51单片机_【笔记】普中科技-51单片机-静态数码管显示
  8. 浅析Hibernate映射(五)——集合映射
  9. visual studio可以开发app吗_做好APP定制开发的计划,可以让你的应用开发事半功倍...
  10. kali linux 自动登录,Kali Linux SSH登录故障处理
  11. Linux如何创建makefile文件,如何在Linux上为gcc创建简单的makefile?
  12. c语言运行的快捷键是什么,c语言执行命令快捷键是什么??
  13. 知识付费的内容变现有哪些方式?
  14. Onedrive不限速还有5T空间,且行且珍惜
  15. 计算机组成原理_选择
  16. 2014.7.14 有用的网址
  17. Type-c引脚定义
  18. Python - JS逆向破解实现翻译软件
  19. ImageMagick将多张图片拼接成一张图片_怎么免费把图片转成PDF?教你4种实用方法...
  20. Neat Video Pro插件如何在Flame 2020中使用

热门文章

  1. 【邱锡鹏-神经网络与深度学习】第一章绪论 知识点汇总
  2. JavaScript: 多维数组的几个注意点
  3. 集成友盟第三方实现QQ微信登录遇到的坑
  4. Ubuntu查看Cuda是否全部安装成功
  5. 不得不说,这19个程序员兼职平台让我1年收入60w
  6. 如何关闭windows电脑里的休眠
  7. 吴恩达OpenAI最新课程:prompt-engineering-for-developers读书笔记
  8. 用od、ce实现植物大战僵尸自动收集阳光
  9. pdf转成jpg或png的方法
  10. 浅显解释 人工智能 vs 机器学习