為V831制作dd鏡像及擴容腳本的記錄


需求

  1. 制作一個全平台通用的燒錄鏡像

  2. 用戶可自行調整root空間大小

  3. 存在一個分區,可以全平台讀寫

解壓鏡像

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:),

image-20210830093720388

但是同時會多出一個需要格式化的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.

不能用。

同時注意到新燒錄的鏡像不會出現此問題,上電腦對比下。

image-20210830100139117

image-20210830100100904

可以注意到修改大小后,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.

解決。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM