树莓派镜像制作

树莓派镜像制作

    • 大致思路
    • 准备必要工具
    • 创建工作文件夹
    • 1.创建空白镜
    • 2.TF卡挂载
    • 3.空白镜像挂载并格式化
    • 4.拷贝至镜像
    • 5.更改PARTUUID
    • 6.导入自分区脚本
    • 结束

大致思路

创建空白镜像
TF卡挂载
空白镜像挂载
分区并格式化
拷贝至镜像
更改PARTUUID
导入自启分区脚本
刷入镜像

准备必要工具

sudo apt-get install dosfstools dump parted kpartx

创建工作文件夹

mkdir makeimg
cd ./makeimg
mkdir src_boot src_root tgt_boot tgt_root

1.创建空白镜

~/makeimg$ sudo dd if=/dev/zero of=raspberrypi.img bs=1M count=4600
通过count更改创建的空白镜像大小(按照自己树莓派TF卡已用空间更改)

2.TF卡挂载

/dev/sda 为TF卡源路径

~/makeimg$ sudo mount -t vfat -o uid=lhs,gid=lhs,umask=0000 /dev/sda1 ./src_boot/
~/makeimg$ sudo mount -t ext4 /dev/sda2 ./src_root/

3.空白镜像挂载并格式化

~/makeimg$ sudo parted raspberrypi.img --script – mklabel msdos
~/makeimg$ sudo parted raspberrypi.img --script – mkpart primary fat32 8192s 122479s
~/makeimg$ sudo parted raspberrypi.img --script – mkpart primary ext4 122880s -1

~/makeimg$ sudo losetup -f --show raspberrypi.img
/dev/loop0
按照上面显示出的loop设备地址替换下面出现的loop设备地址
~/makeimg$ sudo kpartx -va /dev/loop0
~/makeimg$ sudo mkfs.vfat -n boot /dev/mapper/loop0p1
~/makeimg$ sudo mkfs.ext4 /dev/mapper/loop0p2
~/makeimg$ sudo mount -t vfat -o uid=lhs,gid=lhs,umask=0000 /dev/mapper/loop0p1 ./tgt_boot/
~/makeimg$ sudo mount -t ext4 /dev/mapper/loop0p2 ./tgt_root/

4.拷贝至镜像

拷贝/boot

~/makeimg$ sudo cp -rfp ./src_boot/* ./tgt_boot/

拷贝/rootfs
方法一(dump/restore方法)

~/makeimg$ sudo chmod 777 tgt_root
~/makeimg$ sudo chown lhs.lhs tgt_root
~/makeimg$ sudo rm -rf ./tgt_root/*
~/makeimg$ cd tgt_root/
~/makeimg/tgt_root$ sudo dump -0uaf - ../src_Root/ | sudo restore -rf -

方法二 (tar方法)

~/makeimg$ sudo chmod 777 tgt_root
~/makeimg$ sudo chown lhs.lhs tgt_root
~/makeimg$ sudo rm -rf ./tgt_root/*
~/makeimg$ cd src_root/
/makeimg/src_root $ sudo tar pcf ../backup.tar .
~/makeimg$ cd ../tgt_root/
/makeimg/tgt_root$ sudo tar pxf ../backup.tar
~/makeimg/tgt_root$ sudo rm ../backup.tar
~/makeimg/tgt_root$ cd ..

5.更改PARTUUID

查看img文件对应的loop device的两个分区的PARTUUID

~/makeimg$ sudo blkid
/dev/mapper/loop0p1: SEC_TYPE=“msdos” LABEL=“boot” UUID=“755C-C29C” TYPE=“vfat” PARTUUID=“af2f8761-01”
/dev/mapper/loop0p2: UUID=“a174c97e-049f-4fbd-abb7-0b9098dae24a” TYPE=“ext4” PARTUUID=“af2f8761-02”

这里可以看到/boot对应的是af2f8761-01 , / 对应的是af2f8761-02
修改 cmdline.txt ,fstab 文件对应的PARTUUID

~/makeimg$ sudo vim ./tgt_boot/cmdline.txt
~/makeimg$ sudo vim ./tgt_root/etc/fstab

6.导入自分区脚本

镜像刷入TF卡后,/rootfs是跟镜像中的/rootfs一样大小,我们可以手动在树莓派raspi-config中expand_filesystem,扩展分区。下面是利用树莓派raspi-config源码的自启分区脚本
1)创建脚本

~/makeimg$sudo vim ./tgt_root/etc/my_expand_filesystem.sh

2)添加下面my_expand_filesystem.sh内容

#!/bin/sh
do_expand_rootfs() {
  ROOT_PART=$(mount | sed -n 's|^/dev/\(.*\) on / .*|\1|p')

  PART_NUM=${ROOT_PART#mmcblk0p}
  if [ "$PART_NUM" = "$ROOT_PART" ]; then
    whiptail --msgbox "$ROOT_PART is not an SD card. Don't know how to expand" 20 60 2
    return 0
  fi

  # NOTE: the NOOBS partition layout confuses parted. For now, let's only 
  # agree to work with a sufficiently simple partition layout
  if [ "$PART_NUM" -ne 2 ]; then
    whiptail --msgbox "Your partition layout is not currently supported by this tool. You are probably using NOOBS, in which case your root filesystem is already expanded anyway." 20 60 2
    return 0
  fi

  LAST_PART_NUM=$(parted /dev/mmcblk0 -ms unit s p | tail -n 1 | cut -f 1 -d:)
  if [ $LAST_PART_NUM -ne $PART_NUM ]; then
    whiptail --msgbox "$ROOT_PART is not the last partition. Don't know how to expand" 20 60 2
    return 0
  fi

  # Get the starting offset of the root partition
  PART_START=$(parted /dev/mmcblk0 -ms unit s p | grep "^${PART_NUM}" | cut -f 2 -d: | sed 's/[^0-9]//g')
  [ "$PART_START" ] || return 1
  # Return value will likely be error for fdisk as it fails to reload the
  # partition table because the root fs is mounted
  fdisk /dev/mmcblk0 <<EOF
p
d
$PART_NUM
n
p
$PART_NUM
$PART_START

p
w
EOF
  ASK_TO_REBOOT=1

  # now set up an init.d script
cat <<EOF > /etc/init.d/resize2fs_once &&
#!/bin/sh
### BEGIN INIT INFO
# Provides:          resize2fs_once
# Required-Start:
# Required-Stop:
# Default-Start: 3
# Default-Stop:
# Short-Description: Resize the root filesystem to fill partition
# Description:
### END INIT INFO

. /lib/lsb/init-functions

case "\$1" in
  start)
    log_daemon_msg "Starting resize2fs_once" &&
    resize2fs /dev/$ROOT_PART &&
    update-rc.d resize2fs_once remove &&
    rm /etc/init.d/resize2fs_once &&
    rm /etc/my_expand_filesystem.sh &&
    log_end_msg \$?
    ;;
  *)
    echo "Usage: \$0 start" >&2
    exit 3
    ;;
esac
EOF
  chmod +x /etc/init.d/resize2fs_once &&
  update-rc.d resize2fs_once defaults &&
  if [ "$INTERACTIVE" = True ]; then
    whiptail --msgbox "Root partition has been resized.\nThe filesystem will be enlarged upon the next reboot" 20 60 2
  fi
}
do_expand_rootfs
reboot

rm /etc/init.d/resize2fs_once &&
rm /etc/my_expand_filesystem.sh &&
log_end_msg \$?
注意需要将其中rm /etc/my_expand_filesystem.sh更改为自己存放的脚本路径
注意 $PART_START 下面有两行换行符

在~/makeimg/tgt_root/etc/rc.local的exit 0前添加

sudo sh /etc/my_expand_filesystem.sh

结束

删除loop device
~/makeimg$ sudo umount src_boot src_root tgt_boot tgt_root
删除loop device
~/makeimg$ sudo kpartx -d /dev/loop0
~/makeimg$ sudo losetup -d /dev/loop0
删除挂载点目录
~/makeimg$ rmdir src_boot src_root tgt_boot tgt_root

最后剩下img文件就是制作完成的镜像了

参考链接:
[1]: https://blog.csdn.net/zhufu86/article/details/78821056
[2]: http://www.cnblogs.com/haochuang/p/6066532.html

你可能感兴趣的:(树莓派镜像制作)