为V831制作dd镜像及扩容脚本的记录
需求
-
制作一个全平台通用的烧录镜像
-
用户可自行调整root空间大小
-
存在一个分区,可以全平台读写
解压镜像
tina系统一键打包后为Phoenix img, 不是常规的分区镜像,因此需要PhoenixCard解压镜像到sd卡中。
完成后分区情况如下
Device Start End Sectors Size Type
/dev/sdb1 49152 49663 512 256K Microsoft basic data
/dev/sdb2 49664 61951 12288 6M Microsoft basic data
/dev/sdb3 61952 225791 163840 80M Microsoft basic data
/dev/sdb4 225792 553471 327680 160M Microsoft basic data
/dev/sdb5 553472 980991 427520 208.8M Microsoft basic data
最后一个是phoenix烧录后自动拓展的UDISK分区,不管它。
由于gpt分区表存在于头部和尾部,所以gpt分区的克隆实际上十分麻烦,先慢慢尝试下吧,也许最后可以修复。
这里实际上需要的数据只有sda1到sda4,所以需要计算下复制的数据大小。
计算数据大小
可以看到sectors大小为bytes
Disk /dev/sdb: 480 MiB, 503316480 bytes, 983040 sectors
Disk model: SD Card Reader
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
扇区大小和磁盘大小换算:983040*512(Bytes)=503316480(Bytes)/1024(KiB)/1024(MiB)=480(MiB)
所以复制到sdb4末尾,所需的字节数为
553472*512=283377664bytes。并且还需要1024k大小储存gpt分区信息。
bs=bytes:同时设置读入/输出的块大小为bytes个字节。
count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。
块和字节数后可能带有以下的一个或多个后缀:
c =1, w =2, b =512, kB =1000, K =1024, MB =1000x1000, M =1024x1024, xM =M
GB =1000x1000x1000, G =1024x1024x1024, and so on for T, P, E, Z, Y.
如果将bs设置为1M,则count=283377664/1024/1024+1024K/1M=271.25,显然是不允许小数的,但是sdb5扇区上的数据是我们不需要的,多出一些扇区无关紧要,最后设置count为272。
克隆dd镜像
dd if=/dev/sdb bs=1M count=272 of=./image.img status=progress
克隆完毕后查看分区情况
fdisk -l image.img
Disk image.img: 272 MiB, 285212672 bytes, 557056 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
Device Boot Start End Sectors Size Id Type
image.img1 1 4294967295 4294967295 2T ee GPT
可以看到分区表已经损坏,需要重建分区表。
修复分区
新建gpt分区表
parted /dev/sdb
mklabel gpt
yes
quit
恢复分区
/home/lithromantic/Desktop]$ fdisk image.img
Command (m for help): n
Partition number (1-128, default 1):
First sector (34-557022, default 2048): 49152
Last sector, +/-sectors or +/-size{K,M,G,T,P} (49152-557022, default 557022): 49663
Created a new partition 1 of type 'Linux filesystem' and of size 256 KiB.
Command (m for help): n
Partition number (2-128, default 2):
First sector (34-557022, default 51200): 49664
Last sector, +/-sectors or +/-size{K,M,G,T,P} (49664-557022, default 557022): 61951
Created a new partition 2 of type 'Linux filesystem' and of size 6 MiB.
Command (m for help): n
Partition number (3-128, default 3):
First sector (34-557022, default 63488): 61952
Last sector, +/-sectors or +/-size{K,M,G,T,P} (61952-557022, default 557022): 225791
Created a new partition 3 of type 'Linux filesystem' and of size 80 MiB.
Command (m for help): n
Partition number (4-128, default 4):
First sector (34-557022, default 227328): 225792
Last sector, +/-sectors or +/-size{K,M,G,T,P} (225792-557022, default 557022): 553471
Created a new partition 4 of type 'Linux filesystem' and of size 160 MiB.
Partition #4 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: n
Command (m for help): p
Disk image.img: 272 MiB, 285212672 bytes, 557056 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 6024F1DE-D798-471C-AC53-16FD356C178C
Device Start End Sectors Size Type
image.img1 49152 49663 512 256K Linux filesystem
image.img2 49664 61951 12288 6M Linux filesystem
image.img3 61952 225791 163840 80M Linux filesystem
image.img4 225792 553471 327680 160M Linux filesystem
Command (m for help): w
The partition table has been altered.
Syncing disks.
然后挂载到loop下
losetup -P /dev/loop404 image.img
挂载分区查看信息是否一致
mkdir /tmp/test && mount /dev/loop404p4 /tmp/test
可见文件系统都在
[/home/lithromantic/Desktop]$ cd /tmp/test
[/tmp/test]$ ls
bin dev etc home lib lost+found mnt overlay proc pseudo_init rdinit rom root run sbin sys tmp usr var
卸载分区,卸载镜像
umount /tmp/test && losetup -D /dev/loop404
现在我们有了一个可用的dd镜像,在进行其他步骤前,需要先测试下镜像是否可用。
结果令人失望,V831没有任何反应。
猜测是重建gpt分区时破坏了启动文件。
为了防止设备不兼容gpt分区,通常gpt分区表会内嵌一个mbr分区表,尝试重构分区。
重构mbr分区
重新dd镜像,这次直接使用fdisk编辑分区
/home/lithromantic/Desktop]$ fdisk image.img
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk image.img: 272 MiB, 285212672 bytes, 557056 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 6024F1DE-D798-471C-AC53-16FD356C178C
Command (m for help): n
Partition number (1-128, default 1):
First sector (34-557022, default 2048): 49152
Last sector, +/-sectors or +/-size{K,M,G,T,P} (49152-557022, default 557022): 49663
Created a new partition 1 of type 'Linux filesystem' and of size 256 KiB.
Command (m for help): n
Partition number (2-128, default 2):
First sector (34-557022, default 51200): 49664
Last sector, +/-sectors or +/-size{K,M,G,T,P} (49664-557022, default 557022): 61951
Created a new partition 2 of type 'Linux filesystem' and of size 6 MiB.
Command (m for help): n
Partition number (3-128, default 3):
First sector (34-557022, default 63488): 61952
Last sector, +/-sectors or +/-size{K,M,G,T,P} (61952-557022, default 557022): 225791
Created a new partition 3 of type 'Linux filesystem' and of size 80 MiB.
Command (m for help): n
Partition number (4-128, default 4):
First sector (34-557022, default 227328): 225792
Last sector, +/-sectors or +/-size{K,M,G,T,P} (225792-557022, default 557022): 553471
Created a new partition 4 of type 'Linux filesystem' and of size 160 MiB.
Partition #4 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: n
Command (m for help): w
The partition table has been altered.
Syncing disks.
上电,正常启动
__ ___ _ __ _ / |/ /__ _(_)_ __ / / (_)__ __ ____ __ / /|_/ / _ `/ /\ \ / / /__/ / _ \/ // /\ \ //_/ /_/\_,_/_//_\_\ /____/_/_//_/\_,_//_\_\ ----------------------------------------------root@sipeed:/#
查看分区表:
root@sipeed:/# fdisk -l
Disk /dev/mmcblk0: 29.4 GiB, 31609323520 bytes, 61736960 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x4139124f
Device Boot Start End Sectors Size Id Type
/dev/mmcblk0p1 49152 49663 512 256K 83 Linux
/dev/mmcblk0p2 49664 61951 12288 6M 83 Linux
/dev/mmcblk0p3 61952 225791 163840 80M 83 Linux
/dev/mmcblk0p4 225792 553471 327680 160M 83 Linux
可见分区为dos能正常引导。
但是对该分区表修改没什么用,实际上还是没法修改任何信息。
重新dd镜像
这次尝试克隆完整镜像。dd if=/dev/sdb of=./img.img status=progress
创建一个大小为1G的镜像
dd if=/dev/zero bs=4M count=256 of=test.img status=progress
挂载,并克隆v831镜像
losetup -P /dev/loop404 test.img
dd if=img.img of=/dev/loop404 status=progress
检查镜像,会有错误提示
fdisk -l /dev/loop404GPT PMBR size mismatch (983039 != 2097151) will be corrected by write.The backup GPT table is not on the end of the device.Disk /dev/loop404: 1 GiB, 1073741824 bytes, 2097152 sectors
不管,烧录到镜像中查看结果
正常启动,但是会报GPT错误,也不管
root@sipeed:/# fdisk -lGPT PMBR size mismatch (983039 != 61736959) will be corrected by w(rite).Disk /dev/mmcblk0: 29.4 GiB, 31609323520 bytes, 61736960 sectorsUnits: sectors of 1 * 512 = 512 bytesSector size (logical/physical): 512 bytes / 512 bytesI/O size (minimum/optimal): 512 bytes / 512 bytesDisklabel type: gptDisk identifier: AB6F3888-569A-4926-9668-80941DCB40BC
新建分区后,磁盘恢复正常
root@sipeed:/# fdisk -l
Disk /dev/mmcblk0: 29.4 GiB, 31609323520 bytes, 61736960 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: AB6F3888-569A-4926-9668-80941DCB40BC
Device Start End Sectors Size Type
/dev/mmcblk0p1 49152 49663 512 256K Microsoft basic data
/dev/mmcblk0p2 49664 61951 12288 6M Microsoft basic data
/dev/mmcblk0p3 61952 225791 163840 80M Microsoft basic data
/dev/mmcblk0p4 225792 553471 327680 160M Microsoft basic data
/dev/mmcblk0p5 553472 61736956 61183485 29.2G Linux filesystem
尝试制作更小的镜像
497 /home/lithromantic » `dd if=img.img bs=1M count=272 of=/dev/loop404 status=progress`
498 /home/lithromantic » fdisk -l /dev/loop404
GPT PMBR size mismatch (983039 != 573439) will be corrected by write.
Disk /dev/loop404: 280 MiB, 293601280 bytes, 573440 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
果然,分区表错误,并且由于丢失了磁盘末尾的数据,分区也无法查看
Device Boot Start End Sectors Size Id Type/dev/loop404p1 1 573439 573439 280M ee GPT
既然知道数据存在于最后1M字节中,那也dd过来会如何?
515 /home/lithromantic » dd if=img.img skip=980992 of=/dev/loop404 seek=571392 status=progress
516 /home/lithromantic » fdisk /dev/loop404
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p
Disk /dev/loop404: 280 MiB, 293601280 bytes, 573440 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
没任何用。
看来gpt分区情况下,小的可以往大的克隆,大的不能往小的克隆。所以制作镜像时,切记使用小磁盘制作。
拓展root分区大小
文件系统存在于/dev/mmcblk0p4中,需要调整大小就需要修改此分区大小。
在此之前需要先删除/dev/mmcblk0p4和以后的分区
假设需要增加到1G,则end扇区为2048*1024+225792=2322944
或者直接+1G
root@sipeed:~# fdisk /dev/mmcblk0
Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1-4, default 4):
Partition 4 has been deleted.
Command (m for help): n
Partition number (4-8, default 4):
First sector (225792-61736956, default 227328): 225792
Last sector, +sectors or +size{K,M,G,T,P} (225792-61736956, default 61736956): +1G
Created a new partition 4 of type 'Linux filesystem' and of size 1023.8 MiB.
Command (m for help): W
W: unknown command
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
重启后发现进不去系统了。
在电脑上查看,文件系统没问题。
重新烧录一张卡,然后用电脑扩容,启动
root@sipeed:/# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 1014.0M 109.4M 888.7M 11% /
tmpfs 29.4M 12.0K 29.4M 0% /tmp
none 29.3M 0 29.3M 0% /dev
/dev/root 1014.0M 109.4M 888.7M 11% /root
基本没问题。
对比后发现fdisk删除分区时把Name也删掉了。
试试加上Name
root@sipeed:/# fdisk /dev/mmcblk0
Command (m for help): x
Expert command (m for help): n
Partition number (1-4, default 4):
New name: rootfs
Partition name changed from '' to 'rootfs'.
Expert command (m for help): r
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
重启后,正常启动。
查看分区大小
root@sipeed:/# fdisk -l
Disk /dev/mmcblk0: 29.4 GiB, 31609323520 bytes, 61736960 sectors
Device Start End Sectors Size Type
/dev/mmcblk0p1 49152 49663 512 256K Microsoft basic data
/dev/mmcblk0p2 49664 61951 12288 6M Microsoft basic data
/dev/mmcblk0p3 61952 225791 163840 80M Microsoft basic data
/dev/mmcblk0p4 225792 4419583 4193792 2G Linux filesystem
查看挂载情况
root@sipeed:/# df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 1038360 111984 909992 11% /
tmpfs 30100 12 30088 0% /tmp
none 30028 0 30028 0% /dev
/dev/root 1038360 111984 909992 11% /root
可以看到大小对不上。
resize一下
root@sipeed:/# resize2fs /dev/root
resize2fs 1.42.12 (29-Aug-2014)
Filesystem at /dev/root is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
resize2fs: Read-only file system While checking for on-line resizing support
有问题,失败。
实际上,这里提示Read-only file system
是因为之前umount过,分区变成了只读分区,重新挂载下即可。
试试修复下磁盘
root@sipeed:/# e2fsck -f /dev/mmcblk0p4
e2fsck 1.42.12 (29-Aug-2014)
Pass 1: Checking inodes, blocks, and sizes
Inode 7, i_size is 62963712, should be 67174400. Fix<y>? yes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mmcblk0p4: ***** FILE SYSTEM WAS MODIFIED *****
/dev/mmcblk0p4: ***** REBOOT LINUX *****
/dev/mmcblk0p4: 4005/24064 files (0.0% non-contiguous), 30550/262144 blocks
修复完成,重启测试下。
root@sipeed:/# resize2fs /dev/root
resize2fs 1.42.12 (29-Aug-2014)
Filesystem at /dev/root is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/root is now 524224 (4k) blocks long.
root@sipeed:/# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 2.0G 109.4M 1.9G 5% /
tmpfs 29.4M 12.0K 29.4M 0% /tmp
none 29.3M 0 29.3M 0% /dev
/dev/root 2.0G 109.4M 1.9G 5% /root
正常使用了。
警告!扩大root分区后不要直接减小分区,否则会导致块异常而导致无法启动!并且无法修复!
制作全平台通用分区
实际上就是新建一个Fat格式的分区。
新建分区,直接拉满。
root@sipeed:/# fdisk /dev/mmcblk0
Command (m for help): n
Partition number (5-8, default 5):
First sector (4419584-61736956, default 4419584):
Last sector, +sectors or +size{K,M,G,T,P} (4419584-61736956, default 61736956):
Created a new partition 5 of type 'Linux filesystem' and of size 27.3 GiB.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
格式化分区
root@sipeed:/# mkfs.vfat /dev/mmcblk0p5
mkfs.vfat: can't open '/dev/mmcblk0p5': No such file or directory
看样子需要重启生效下,reboot。
验证分区
插电脑上,可以看到windows成功读取了一个27.3G大小的U盘(H:),
但是同时会多出一个需要格式化的U盘 (G:),这是我们不想看到的。
插上设备,看看是哪里出了问题。
Device Start End Sectors Size Type
/dev/mmcblk0p1 49152 49663 512 256K Microsoft basic data
/dev/mmcblk0p2 49664 61951 12288 6M Microsoft basic data
/dev/mmcblk0p3 61952 225791 163840 80M Microsoft basic data
/dev/mmcblk0p4 225792 4419583 4193792 2G Linux filesystem
/dev/mmcblk0p5 4419584 61736956 57317373 27.3G Linux filesystem
很明显,4和5分别是G和H磁盘,唯一不一样的就是文件系统格式,一个是ext4,一个是fat。可以注意到,前三个磁盘并不会被电脑读取,后两个和前两个的type不同,修改下试试。
root@sipeed:/# fdisk /dev/mmcblk0
Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): t
Partition number (1-5, default 5):
Partition type (type L to list all types): l
6 Microsoft basic data EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
Partition type (type L to list all types): 6
Changed type of partition 'Linux filesystem' to 'Microsoft basic data'.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
不能用。
同时注意到新烧录的镜像不会出现此问题,上电脑对比下。
可以注意到修改大小后,rootfs的Flags丢失了,添加回来先。
上电后依然无法使用,原因在于Windows已经给此分区分配盘符,手动删除即可,
但并不是我们所期望的,我们希望用户拿到镜像后什么都不干就能用。
找一张新卡复现下。
发现在使用fdisk只修改了分区/dev/mmcblk0p4
后,没问题。
使用fdisk只修改了分区/dev/mmcblk0p5
后,没问题。
在修改了GUID后,两者都不在分配盘符。
root@sipeed:/# fdisk /dev/mmcblk0
Welcome to fdisk (util-linux 2.25.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Expert command (m for help): u
Partition number (1-5, default 5): 4
New UUID (in 8-4-4-4-12 format): A0085546-4166-744A-A353-FCA9272B8E48
Partition UUID changed from 3A22EC04-4B57-4945-A295-773995BDA2B0 to A0085546-4166-744A-A353-FCA9272B8E48.
Expert command (m for help): u
Partition number (1-5, default 5): 5
New UUID (in 8-4-4-4-12 format): A0085546-4166-744A-A353-FCA9272B8E49
Partition UUID changed from 742380B9-389D-4908-91F7-2FA2CB6E7195 to A0085546-4166-744A-A353-FCA9272B8E49.
Expert command (m for help): r
Command (m for help): w
把分区5的UUID修改后,就可以正常读取了。
注意到使用Phoenix card烧录的UDISK也无法读取,尝试修改UUID,发现没用,同时手动分配盘符时,会提示系统找不到指定的文件,应该是多种参数共同作用的结果,以后再探讨。
挂载分区
分区5在电脑上可读后,还需要再Linux下可读。
root@sipeed:/# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 2.0G 109.4M 1.9G 5% /
tmpfs 29.4M 12.0K 29.4M 0% /tmp
none 29.3M 0 29.3M 0% /dev
/dev/root 2.0G 109.4M 1.9G 5% /root
可以看到,现在磁盘还没挂载。
root@sipeed:/# mount /dev/mmcblk0p5 /mnt
root@sipeed:/# df -h
Filesystem Size Used Available Use% Mounted on
/dev/root 2.0G 109.4M 1.9G 5% /
tmpfs 29.4M 12.0K 29.4M 0% /tmp
none 29.3M 0 29.3M 0% /dev
/dev/root 2.0G 109.4M 1.9G 5% /root
/dev/mmcblk0p5 27.3G 64.0K 27.3G 0% /mnt
挂载后即可使用。
但是手动挂载不是我们想要的,我们期望系统启动后自动挂载。
实际上,在/etc/init.d/rcS
中,存在by-name挂载磁盘的代码。
if [ x"$src" == x/dev/by-name/UDISK ]; then
mount -t vfat "$fs_src" "$fs_mntpt" 2>/dev/null
if [ "$?" -ne "0" ]; then
mkfs.vfat "$fs_src" > /dev/null
mount -t vfat "$fs_src" "$fs_mntpt" 2>/dev/null
fi
所以我们只需要修改分区5的name即可。
root@sipeed:/# fdisk /dev/mmcblk0
Welcome to fdisk (util-linux 2.25.2).
Command (m for help): x
Expert command (m for help): n
Partition number (1-5, default 5):
New name: UDISK
Partition name changed from '' to 'UDISK'.
Expert command (m for help): r
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
重启,成功挂载。
Filesystem Size Used Available Use% Mounted on
/dev/root 2.0G 109.4M 1.9G 5% /
tmpfs 29.4M 12.0K 29.4M 0% /tmp
none 29.3M 0 29.3M 0% /dev
/dev/mmcblk0p5 27.3G 64.0K 27.3G 0% /mnt/UDISK
/dev/mmcblk0p5 27.3G 64.0K 27.3G 0% /root
制作脚本
用户可选的参数应该有
Filesystem | size | 备注 |
---|---|---|
/dev/root | 用户指定 | 在没有/dev/mmcblk0p5的情况下才能调节 |
/dev/mmcblk0p5 | 磁盘剩余所有空间 |
首先要有个选择菜单
#!/bin/sh
menu()
{
echo "choose you want do:
1):UDISK
2):root
"
read -p "defult 1):" task
task=${task:-1}
if [ "$task" = "2" ];then
read -p "+size{K,M,G,T,P} , such as: +1G
default all size:" size
else
fi
}
引导用户选择UDISK后,就要创建UDISK分区了。
创建分区手动方法如下
root@sipeed:/# fdisk /dev/mmcblk0 #打开fdisk
Command (m for help): n #新建分区
Partition number (5-8, default 5): #分区5
First sector (4419584-61736956, default 4419584): #默认大小
Last sector, +sectors or +size{K,M,G,T,P} (4419584-61736956, default 61736956):
Command (m for help): x #扩展功能
Expert command (m for help): n #修改名字
Partition number (1-5, default 5): #分区5
New name: UDISK #新名字
Expert command (m for help): r #退出
Command (m for help): w #保存
显然不可能引导用户手动完成这部分,这里可以借助linux管道
echo "n
5
x
n
5
UDISK
r
w
" | fdisk /dev/mmcblk0
显然这样写脚本太不美观了,我们可以使用 -e来转译特殊符号,每个\n即是一个换行符。
echo -e "n\n5\n\n\nx\nn\n5\nUDISK\nr\nw\n" | fdisk /dev/mmcblk0
下一步需要的就是格式化分区为fat,这里牵扯到重启系统。
我们希望重启后脚本自动执行,并且下次重启后脚本不在自动执行。
我们需要先备份一个开机脚本,移除执行权限
cd /etc/init.d
cp rc.final rc.final.bak
chmod -x rc.final.bak
然后rc.final 末尾添加执行我们这个脚本的命令
echo "sh /resize.sh mkfs" >> /etc/init.d/rc.final
其中mkfs是向脚本传递参数,可以通过传入的参数来判断运行情况。
这时候在我们的菜单外面套一层if [ "$1" != "mkfs" ];then fi
即可确保下次不执行。
重启后,脚本执行格式化UDISK,并且移除开机自启动。
mkfs_udisk()
{
mkfs.vfat /dev/mmcblk0p5
cd /etc/init.d
rm rc.final
mv rc.final.bak rc.final
chmod +x rc.final
echo "all ok"
}
然后在我们的菜单中添加该分支
elif [ "$1" = "mkfs" ];then
mkfs_udisk
放入根目录,执行即可。
在内部调试时,我们可能需要更大的根目录分区,这时候就要扩大根目录分区。
在扩容根目录前,要先删除UDISK,并且提示用户,防止文件丢失
detele_udisk()
{
if [ -e /dev/by-name/UDISK ]; then
echo "Warning, UDISK already exists, do you want to delete it?"
read -p "Y(es) or N(o),defult: Y"del_yn
del_yn=${del_yn:-y}
if [ $del_yn = "Y" -o $del_yn = "y" ];then
echo -e "d\n5\nw\n"|fdisk /dev/mmbclk0
else
echo "now stop task"
exit 0
}
然后编写扩容根目录的脚本
resize_root()
{
echo -e "d\n4\nn\n4\n225792\n$size\nx\nn\n4\nrootfs\nu\n4\nA0085546-4166-744A-A353-FCA9272B8E49\nr\nw\n"|fdisk /dev/mmbclk0
cd /etc/init.d
cp rc.final rc.final.bak
chmod -x rc.final.bak
echo "sh /resize.sh resize" >> /etc/init.d/rc.final
reboot
}
然后使扩容空间生效
resize2fs_root()
{
resize2fs /dev/root
cd /etc/init.d
rm rc.final
mv rc.final.bak rc.final
chmod +x rc.local
echo "change root size ok"
}
添加函数进菜单选项
elif [ "$select" = "resize" ];then
resize2fs_root
完整脚本如下:
#!/bin/sh
select=$1
select=${select:-begin}
detele_udisk()
{
if [ -e /dev/by-name/UDISK ]; then
echo "Warning, UDISK already exists, do you want to delete it?"
read -p "Y(es) or N(o),defult: Y" del_yn
del_yn=${del_yn:-y}
if [ $del_yn = "Y" -o $del_yn = "y" ];then
echo -e "d\n5\nw\n"|fdisk /dev/mmcblk0
else
echo "now stop task"
exit 0
fi
fi
}
create_UDISK()
{
echo -e "n\n5\n\n\nx\nn\n5\nUDISK\nr\nw\n" | fdisk /dev/mmcblk0
cd /etc/init.d
cp rc.final rc.final.bak
chmod -x rc.final.bak
echo "sh /resize.sh mkfs" >> /etc/init.d/rc.final
reboot
}
mkfs_udisk()
{
mkfs.vfat /dev/mmcblk0p5
cd /etc/init.d
rm rc.final
mv rc.final.bak rc.final
chmod +x rc.final
echo "all ok"
}
resize_root()
{
echo -e "d\n4\nn\n4\n225792\n$size\nx\nn\n4\nrootfs\nu\n4\nA0085546-4166-744A-A353-FCA9272B8E49\nr\nw\n"|fdisk /dev/mmcblk0
cd /etc/init.d
cp rc.final rc.final.bak
chmod -x rc.final.bak
echo "sh /resize.sh resize" >> /etc/init.d/rc.final
reboot
}
resize2fs_root()
{
resize2fs /dev/root
cd /etc/init.d
rm rc.final
mv rc.final.bak rc.final
chmod +x rc.final
echo "change root size ok"
}
menu()
{
echo "your input $select"
if [ "$select" = "begin" ];then
echo "choose you want do:
1):UDISK
2):root
If you want to view your disks on different platforms,you should do 1
IF you just want expand your root filesystem,do 2
maybe you all want,then do 2 before do 1
You will can't change the size of your root filesystem after you get UDISK
"
read -p "defult 1):" task
task=${task:-1}
echo "You choose $task;"
if [ "$task" = "2" ];then
read -p "+size{K,M,G,T,P} , such as: +1G
default all size:" size
detele_udisk
resize_root
else
create_UDISK
fi
elif [ "$select" = "mkfs" ];then
mkfs_udisk
elif [ "$select" = "resize" ];then
resize2fs_root
fi
}
menu
后续补充
在后续使用时发现,完全扩展root分区后,resize会报
resize2fs: Operation not permitted While trying to add group #3
这是由于文件系统中的journal
限制了块数量
此时需要重新创建journal
umount /dev/sdb4
tune2fs -O ^has_journal /dev/sdb4
tune2fs -j /dev/sdb4
e2fsck -fy /dev/sdb4
resize /dev/sdb4
此时插上板子后root分区才会正常,并且可以继续增加大小。
但是需要注意的是,以上操作是在电脑端进行的,在831上执行会出问题,暂且不谈。
尝试在dd镜像时就修改特性。
losetup -P /dev/loop404 test.img
Desktop losetup -P /dev/loop404 test.img
Desktop fdisk /dev/loop404
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1-5, default 5):
Partition 5 has been deleted.
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Desktop e2fsck -fyC 0 /dev/loop404p4
e2fsck 1.45.7 (28-Jan-2021)
/dev/loop404p4: recovering journal
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Padding at end of inode bitmap is not set. Fix? yes
/dev/loop404p4: ***** FILE SYSTEM WAS MODIFIED *****
/dev/loop404p4: 4009/6016 files (0.0% non-contiguous), 29384/51200 blocks
Desktop resize2fs -p /dev/loop404p4
resize2fs 1.45.7 (28-Jan-2021)
The filesystem is already 51200 (4k) blocks long. Nothing to do!
失败
考虑给root扩容下试试
Desktop losetup -P /dev/loop404 test.img
Desktop fdisk /dev/loop404
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1-4, default 4):
Partition 4 has been deleted.
Command (m for help): n
Partition number (4-8, default 4):
First sector (225792-983036, default 227328): 225792
Last sector, +/-sectors or +/-size{K,M,G,T,P} (225792-983036, default 983036): +300M
Created a new partition 4 of type 'Linux filesystem' and of size 299.8 MiB.
Partition #4 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: y
The signature will be removed by a write command.
Command (m for help): x
Expert command (m for help): n
Partition number (1-4, default 4):
New name: rootfs
Partition name changed from '' to 'rootfs'.
Expert command (m for help): r
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
Desktop e2fsck -fyC 0 /dev/loop404p4
e2fsck 1.45.7 (28-Jan-2021)
ext2fs_open2: Bad magic number in super-block
e2fsck: Superblock invalid, trying backup blocks...
Backing up journal inode block information.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong (0, counted=21816).
Fix? yes
Free inodes count wrong (0, counted=2007).
Fix? yes
/dev/loop404p4: ***** FILE SYSTEM WAS MODIFIED *****
/dev/loop404p4: 4009/6016 files (0.0% non-contiguous), 29384/51200 blocks
Desktop resize2fs -p /dev/loop404p4
resize2fs 1.45.7 (28-Jan-2021)
Resizing the filesystem on /dev/loop404p4 to 76736 (4k) blocks.
The filesystem on /dev/loop404p4 is now 76736 (4k) blocks long.
Desktop losetup -d /dev/loop404
可以使用了
需要注意的是,Last sector, +/-sectors or +/-size{K,M,G,T,P} (225792-983036, default 983036): +300M
这里,如果使用default,会导致windows下烧录镜像异常。
制作dd脚本
由于牵扯到电脑端预处理,所以写个脚本批处理下。
脚本期望功能如下
输入参数 | 输出 | 备注 |
---|---|---|
源镜像位置 | 压缩包镜像 | 可以指定任意位置 |
输出镜像位置 | 烧录信息 | 可以指定任意名称 |
创建接口,存储输入参数,同时提醒用户检查路径是否正确
#!/bin/sh
input_addr=$1
output_addr=$2
name=$3
input_addr=${input_addr:-/dev/sdb}
output_addr=${output_addr:-./}
name=${name:-sipeed.img}
read -p "Please confirm the path and image size,must be 512MiB!
Y(es) or other,defult<n>" sure_path
if [ "$sure_path" != "y" -a "$sure_path" != "Y" ];then
echo "exit"
exit 0
fi
然后dd镜像,并挂载到loop设备中修改并压缩
sudo dd if=$input_addr status=progress of=/tmp/$name &&\
sudo losetup -d /dev/loop404
sudo losetup -P /dev/loop404 /tmp/$name &&\
sleep 2
echo -e "\n\nd\n5\nd\n4\nn\n4\n225792\n+300M\nx\nn\n4\nrootfs\nr\nw\n"|sudo fdisk /dev/loop404 &&\
sudo e2fsck -fyC 0 /dev/loop404p4 &&\
sleep 2
sudo resize2fs -p /dev/loop404p4
sudo losetup -d /dev/loop404
addr=$(pwd) &&\
cd /tmp &&\
echo "Compressing the mirror takes some time, and you can use <progress -m> at other terminals to see progress" &&\
sudo xz -z -k $name --threads=0 &&\
cd $addr &&\
sudo mv /tmp/$name.xz $output_addr &&\
sudo rm /tmp/$name
实际上,fdisk无法以脚本方式删除signature,所以分区部分还需要手动执行。
Do you want to remove the signature? [Y]es/[N]o: y
Partition #4 contains a ext4 signature.
简化脚本,只保留修改分区大小部分。
#!/bin/sh
input_addr=$1
output_addr=$2
name=$3
input_addr=${input_addr:-dd.img}
output_addr=${output_addr:-./}
name=${name:-sipeed.img}
echo "input_addr=$input_addr,output_addr=$output_addr, name is $name
you can run xx.sh <intputaddr> <outputaddr> <name> to specify them or use defult
Such as
dd.sh ./dd.img /root test.img
or
dd.sh ./dd.img"
sudo cp $input_addr /tmp/$name
sudo losetup -d /dev/loop404
sudo losetup -P /dev/loop404 /tmp/$name &&\
sudo e2fsck -fyC 0 /dev/loop404p4 &&\
sleep 2
sudo resize2fs -p /dev/loop404p4
echo -e "\nx\nn\n4\nrootfs\nu\n4\nA0085546-4166-744A-A353-FCA9272B8E48\nr\nw\n"|sudo fdisk /dev/loop404p4
sudo losetup -d /dev/loop404
addr=$(pwd) &&\
cd /tmp &&\
echo "Compressing the mirror takes some time, and you can use <progress -m> at other terminals to see progress" &&\
sudo xz -z -k $name --threads=0 &&\
cd $addr &&\
sudo mv /tmp/$name.xz $output_addr &&\
sudo rm /tmp/$name
echo "all ok,use xz -dc $name.xz |sudo dd of=/dev/sdb bs=1M status=progress oflag=direct to create a tf Startup Disk"
同时人工需要执行的命令如下:
~sudo dd if=/dev/sdb of=dd.img status=progress
~ fdisk dd.img
Welcome to fdisk (util-linux 2.36.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): d
Partition number (1-5, default 5):
Partition 5 has been deleted.
Command (m for help): d
Partition number (1-4, default 4): 4
Partition 4 has been deleted.
Command (m for help): n
Partition number (4-8, default 4):
First sector (225792-983036, default 227328): 225792
Last sector, +/-sectors or +/-size{K,M,G,T,P} (225792-983036, default 983036): +300M
Created a new partition 4 of type 'Linux filesystem' and of size 299.8 MiB.
Partition #4 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: y
The signature will be removed by a write command.
Command (m for help): w
The partition table has been altered.
Syncing disks.
解决。