制作SD启动卡,从SD卡启动系统

简介: 制作SD启动卡,从SD卡启动系统

  • 芯片需要支持SD卡这种启动方式。
  • 准备好u-boot.imx,dtb,zImage,rootfs压缩包

使用fdisk命令对sd卡分区

输入fdisk /dev/mmcblk0.按照提示输入相关选项进行操作。

/#fdisk/dev/mmcblk0
Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPT disklabel Building a new Dos disklabel. Changes will remain in memory only, until you decide to write them. After that the previous content won't be recoverable.
The number of cylinders for this disk is set to 486192.
There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of Lilo)2) booting and partitioning software from other 0Ss
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): help  输入help提示  
he unknown command  带助信息  
Command Action
a toggle a bootable flag  
edit bsd disklabel
toggle the dos compatibility flag delete a partition
list known partition types add a new partition
create a new empty D0S partition table print the partition table quit without saving changes
create a new empty Sun disklabel change a partition's system id change display/entry units verify the partition table write table to disk and exit
extra functionality (experts only)
Command (m for help): p 输入p打印分区表信息  
Disk /dev/mmcblk0: 15 GB,15931539456 bytes, 31116288 sectors
486192 cylinders, 4 heads, 16 sectors/track
Units: cylinders of 64 * 512 = 32768 bytes

可以看到我这张SD卡的相关信息,总容量为15931539456字节,31116288个sectors,即一个sector为512字节。

创建第一个分区

Command (m for help):n  
Command action
extended
e
p primary partition (1-4)
Partition number (1-4):1
First cylinder (1-486192,default 1):32
Last cylinder or +size or +sizeM or +sizeK (32-486192,default 486192):2080
Command (m for help): p
Disk/dev/mmcblk0: 15 GB, 15931539456 bvtes, 31116288 sectors486192 cylinders, 4 heads, 16 sectors/track Units: cylinders of 64 * 512 = 32768 bytes
Device  Boot StartCHS EndCHS  StartLBA  EndLBA  Sectors Size Id Type  
/dev/mmcblk0p1  31,0,1  1023,3,16 1984  133119  131136 64.0M 83 Linux
Command (m for help): 0

输入n,添加一个新分区,这里提示输入分区号,范围1 ~ 4. 然后输入1,提示我们选择第一个柱面(一个柱面的大小是32KB)。 这里我选择32 ~(32+2048)作为第一个分区作boot分区(用来烧写dtb和kernel分区)。即32KB * 2048 = 64M大小。之所以从32开始,是把前1M(32K*32=1M)空间留给uboot,uboot是裸分区

创建第二个分区

Command (m for help): n Command action
e extended  
p primary partition (1-4)
Partition number (1-4):2
First cvlinder (1-486192,default 1): 2081
Last cylinder or +size or +sizeM or +sizek (2081-486192, default 486192):486192
Command (m for help): p
Disk/dev/mmcblk0: 15 GB,15931539456 bytes, 31116288 sectors486192 cylinders, 4 heads, 16 sectors/track Units: cylinders of 64 * 512 = 32768 bytes
Device  Boot StartCHS EndCHS  StartLBA  EndLBA  Sectors Size Id Type  
/dev/mmcblk0p1  31,日,1  1023,3,16 1984  133119  131136 64.0M 83 Linux 
/dev/mmcblk0p2  1023,3,16 1023,3,16 133120  31116287  30983168 14.7G 83 Linux 
Command (m for help): 1

同样地,创建第二个分区,从2081~486192都划分给第二个分区。 以下是我设置的分区。

分区名 分区号 大小
boot 1 64M
文件系统分区 2 剩余空间

640.png

设置p1为boot分区

Command (m for help): m Command Action
a toggle a bootable flag  
b edit bsd disklabel  
toggle the dos compatibility flag delete a partition
list known partition types add a new partition
create a new empty Dos partition table print the partition table quit without saving changes
create a new empty Sun disklabel change a partition's system id change display/entry units verify the partition table
W write table to disk and exit  
X extra functionality (experts only)  
Command (m for help): t 
Partition number (1-4):1
Hex code  (type list  codes): 
日 Empty 1b Hidden Win95 FAT32 9f BSD/0S 
FAT12 1c Hidden W95 FAT32 (LBA) a0 Thinkpad hibernation 
4 FAT16 <32M  le Hidden W95 FAT16 (LBA) a5 FreeBSD  
5 Extended  3c Part.Magic recovery  a6 0penBSD  
6 FAT16 41 PPC PReP Boot  a8 Darwin UFS 
7 HPFS/NTFS 42 SFS  a9 NetBSD 
a 0S/2 Boot Manager 63 GNU HURD or SysV ab Darwin boot  
b Win95 FAT32 80 0ld Minix  b7 BSDI fs  
Win95FAT32(LBA) 81 Minix / old Linux  b8 BSDI swap  
e Win95 FAT16 (LBA) 82 Linux swap be Solaris boot 
f Win95 Ext'd(LBA)  83 Linux  eb BeOS fs  
11 Hidden FAT12 84 0S/2 hidden C: drive ee EFI GPT  
12 Compag diagnostics 85 Linux extended ef EFI (FAT-12/16/32) 
14 Hidden FAT16 <32M  86 NTFS volume set  f0 Linux/PA-RISC boot 
16 Hidden FAT16 87 NTFS volume set  f2 DOS secondary  
17 Hidden HPES/NTES 8e Linux LVM  fd Linux raid autodetect  
Hex code (type L to list codes): c
Changed system type of partition 1 to c (Win95 FAT32 (LBA)
Command (m for help): m Command Action
toggle a bootable flag edit bsd disklabel
toggle the dos compatibility flag delete a partition
list known partition types
n add a new partition 
create a new empty D0S partition table print the partition table quit without saving changes
S create a new empty Sun disklabel  
change a partition's system id change display/entry units
U
verify the partition table write table to disk and exit
extra functionality (experts only)
Command (m for help): a
Partition number (1-4):1  

使用t选项,选择第一个分区,然后选择c,把分区system id类型设置为fat。然后使用a,选择第一个分区为boot类型。

Command (m for help): p
Disk/dev/mmcblk0: 15 GB,15931539456 bytes, 31116288 sectors486192 cylinders, 4 heads, 16 sectors/track Units: cylinders of 64 * 512 = 32768 bytes
Device/dev/mmcblk0p1 Boot31,日,1 StartCHS EndCHS1023,3,16 StartLBA1984133119 EndLBA Secto1311 Size Id Type哆哆的Lnux存储杂记
/dev/mmcblk0p2  1023,3,16 1023,3,16 13312日  31116287  30983168 14.7G 83 Linux

可以看到p1后面boot那列多了个*。

格式化p1 p2

创建完分区之后,还需要对分区进行格式化。把p1的fstype格式化为fat,p2的fstype格式化为ext3分区。mke2fs可以用-t选项指定为ext3或者ext4。

mkfs.vfat -F 32 -n "boot" /dev/mmcblk0p1
mke2fs -t ext4 -F -L "rootfs" /dev/mmcblk0p2

烧录uboot.imx

dd if=u-boot.imx of=/dev/mmcblk0 bs=1024 seek=1 conv=fsync

通过dd命令烧录uboot.imx到SD卡。这里需要使用seek跳过前1K,这个跟这款芯片有关。

640.png

640.png做到这一步,已经可以从SD启动u-boot了,不过里面还没有kernel和根文件系统。

烧录kernel

mkdir -p /tmp/kernel
mount /dev/mmcblk0p1 /tmp/kernel
cp -r /mnt/dfos.dtb /tmp/kernel
cp -r /mnt/zImage /tmp/kernel
umount /tmp/kernel

烧录根文件系统

mkdir -p /tmp/rootfs
mount /dev/mmcblk0p2 /tmp/rootfs
tar -vxf /mnt/rootfs.tar.bz2 -C /tmp/rootfs/
umount /tmp/rootfs

至此,就可以从SD卡启动系统了。

关于根文件系统打包

压缩

sudo tar -cvzf rootfs.tar.gz *  
sudo tar -cvjf rootfs.tar.bz2 *

解压

tar -vxf /mnt/rootfs.tar.gz -C /tmp/rootfs/ --strip-components 1
tar -vxf /mnt/rootfs.tar.bz2 -C /tmp/rootfs/

做成shell脚本一键烧录

使用方法:sd_burn.sh /dev/mmcblk0

#!/bin/sh
#execute执行语句成功与否打印
execute ()
{
    $* >/dev/null
    if [ $? -ne 0 ]; then
        echo
        echo "错误: 执行 $*"
        echo
        exit 1
    fi
}
device=$1
dfos_dtb=imx6ull-14x14-evk.dtb
uboot='u-boot.imx'
rootfs_img=rootfs.tar.bz2
#rootfs_img=rootfs.tar.gz
#执行格式化$device
execute "dd if=/dev/zero of=$device bs=1024 count=1024"
#cat << END | fdisk -H 255 -S 63 $device
cat << END | fdisk $device
n
p
1
32
2080
n
p
2
2081  
486192
t
1
c
a
1
w
END
PARTITION1=${device}p1
PARTITION2=${device}p2
#第一个分区创建为Fat32格式
echo "格式化${device}p1 ..."
if [ -b ${PARTITION1} ]; then
  echo "${PARTITION1} ..."
  mkfs.vfat -F 32 -n "boot" /dev/mmcblk0p1
else
  echo "error: no ${PARTITION1}"
fi
#第二个分区创建为ext4格式
echo "格式化${device}p2 ..."
if [ -b ${PARITION2} ]; then
  echo "${PARTITION2} ..."
  /mnt/mke2fs -F -L "rootfs" /dev/mmcblk0p2
else
  echo "错误: /dev下找不到 SD卡 rootfs分区"
fi
echo "正在烧写${Uboot}到${device}"
execute "dd if=/mnt/${uboot} of=$device bs=1024 seek=1 conv=fsync"
sync
echo "烧写${Uboot}到${device}完成!"
echo "正在准备复制..."
echo "正在复制设备树与内核到${PARTITION1},请稍候..."
execute "mkdir -p /tmp/kernel"
execute "mount ${PARTITION1} /tmp/kernel"
execute "cp -r /mnt/${dfos_dtb} /tmp/kernel"
execute "cp -r /mnt/zImage /tmp/kernel"
sync
echo "复制设备树与内核到${device}p1完成!"
echo "卸载${PARTITION1}"
execute "umount /tmp/kernel"
sleep 1
#解压文件系统到文件系统分区
#挂载文件系统分区
execute "mkdir -p /tmp/rootfs"
execute "mount ${PARTITION2} /tmp/rootfs"
echo "正在解压文件系统到${PARTITION2} ,请稍候..."
#execute "tar -vxf /mnt/${rootfs_img} -C /tmp/rootfs/ --strip-components 1"
execute "tar -vxf /mnt/${rootfs_img} -C /tmp/rootfs/"
sync
echo "解压文件系统到${PARTITION2}完成!"
echo "卸载${PARTITION2}"
execute "umount /tmp/rootfs"
execute "rm -rf /tmp/rootfs"
sync
echo "SD卡启动系统烧写完成!"

号主:一枚机械专业本科生,经历了转行,从外包逆袭到芯片原厂的Linux驱动开发工程师,深入操作系统的世界,贯彻终身学习、终身成长的理念。平时喜欢折腾,寒冬之下,抱团取暖,期待你来一起探讨技术、搞自媒体副业,程序员接单和投资理财。【对了,不定期送闲置开发板、书籍、键盘等等】。

如果你想了解我的转行经验,欢迎找我交流~gongzhong号【哆哆jarvis】

一起不断探索自我、走出迷茫、找到热爱,希望和你成为朋友,一起成长~

相关文章
|
存储 传感器 Linux
Linux应用开发基础知识——I2C应用编程(十二)
Linux应用开发基础知识——I2C应用编程(十二)
621 0
Linux应用开发基础知识——I2C应用编程(十二)
|
JSON API 持续交付
逐步指南:使用FastAPI部署YOLO模型的步骤
逐步指南:使用FastAPI部署YOLO模型的步骤
|
安全 Shell Android开发
Android系统 init.rc开机执行shell脚本
Android系统 init.rc开机执行shell脚本
3183 0
|
存储 负载均衡 Java
Jetty技术深度解析及其在Java中的实战应用
【9月更文挑战第3天】Jetty,作为一款开源的、轻量级、高性能的Java Web服务器和Servlet容器,自1995年问世以来,凭借其卓越的性能、灵活的配置和丰富的扩展功能,在Java Web应用开发中占据了举足轻重的地位。本文将详细介绍Jetty的背景、核心功能点以及在Java中的实战应用,帮助开发者更好地理解和利用Jetty构建高效、可靠的Web服务。
836 2
|
存储 Kubernetes API
使用Kubernetes管理容器化应用的深度解析
【5月更文挑战第20天】本文深度解析Kubernetes在管理容器化应用中的作用。Kubernetes是一个开源平台,用于自动化部署、扩展和管理容器,提供API对象描述应用资源并维持其期望状态。核心组件包括负责集群控制的Master节点(含API Server、Scheduler、Controller Manager和Etcd)和运行Pod的工作节点Node(含Kubelet、Kube-Proxy和容器运行时环境)。
|
传感器 芯片
STM32外设系列—HC-SR04(超声波)
本文主要介绍了超声波测距的原理,常用的超声波传感器。并且针对HC-SR04给出了使用思路和程序设计。最后,简单进行了思路拓展。
765 1
STM32外设系列—HC-SR04(超声波)
|
传感器 算法 C语言
基于无线传感器网络的节点分簇算法matlab仿真
该程序对传感器网络进行分簇,考虑节点能量状态、拓扑位置及孤立节点等因素。相较于LEACH算法,本程序评估网络持续时间、节点死亡趋势及能量消耗。使用MATLAB 2022a版本运行,展示了节点能量管理优化及网络生命周期延长的效果。通过簇头管理和数据融合,实现了能量高效和网络可扩展性。
267 10
STM32速成笔记(三)—按键检测
本文介绍了如何利用STM32进行按键检测,先介绍了原理,后面给出了配置步骤和应用例程。此外,本文还叙述了如何利用一个按键单独控制一个LED亮灭,以及如何检测按键长短按。
2053 0
STM32速成笔记(三)—按键检测
|
运维 Kubernetes 持续交付
构建高效自动化运维体系:基于容器技术的持续集成与部署实践
【5月更文挑战第13天】 在现代软件开发周期中,持续集成(CI)和持续部署(CD)已成为提升开发效率、保障产品质量的关键环节。随着云计算和微服务架构的普及,容器技术如Docker和Kubernetes为运维领域带来了革命性的变革。本文旨在探讨如何利用容器技术构建一个高效、可靠的自动化运维体系,实现从代码提交到产品发布的全过程自动化管理。通过深入分析容器化技术的核心原理,结合实际案例,我们将阐述如何优化持续集成流程、确保自动化测试的覆盖率、以及实现无缝的持续部署。
246 2
|
SQL 关系型数据库 MySQL
关系型数据库mysql跨平台兼容性
【6月更文挑战第13天】
732 4