Linux 縮小磁碟影像檔教學,解決回復 MicroSD 卡空間不足問題

建立 Loopback 設備

若想要修改磁碟分割表,就必須先讓 Linux 核心載入磁碟,才能使用各種磁碟分割工具來修改,但是現在我們的磁碟不是一般的實體磁碟,而是一個影像檔,若要讓 Linux 核心可以載入這個磁碟,就必須使用 loopback 設備來處理。

首先啟用 Linux 核心 的 loopback 模組:

sudo modprobe loop

接著找尋尚未被使用的 loopback 設備:

sudo losetup -f
/dev/loop0

這個輸出表示 /dev/loop0 這個設備尚未被使用,所以我們可以使用這個名稱來建立一個影像檔的 loopback 設備:

sudo losetup /dev/loop0 my_image.img

其中 my_image.img 就是從 MicroSD 卡備份下來的影像檔,現在 /dev/loop0 就代表了 my_image.img 影像檔中的磁碟,接著要讓 Linux 核心也載入這個磁碟:

sudo partprobe /dev/loop0

這時候在系統上應該就可以看得到這個磁碟了(但是應該是處於未掛載的狀態)。

調整分割區
在使用 loopback 載入影像檔中的的磁碟之後,就可以使用普通的磁碟工具來修改它了。

一開始要調整分割區的大小,讓磁碟末端騰出一些空間,這個動作可以使用 GParted 的操作介面來處理:

sudo gparted /dev/loop0

原本的磁碟分割狀態會類似這樣,整個磁碟幾乎都用滿了,但某些分割區裡面還有些空間:

磁碟分割表

使用 GParted 的介面調整一下分割區的大小或位置,讓磁碟末端騰出一些空間,通常這個空間也不需要很大,就看影像檔的大小與 MicroSD 卡的容量相差多少,就騰出多少即可,如果磁碟分割區內的資料很少,多騰出一點空間也沒有關係:

磁碟分割表

使用 GParted 調整磁碟分割區時,結果會直接寫入我們的影像檔,修改好影像檔之後,即可卸載 loopback 設備:

sudo losetup -d /dev/loop0

裁剪影像檔
現在我們的影像檔的狀態應該就會像 GParted 介面中顯示的那樣,末端是沒有使用的空間,最後只要將那段沒用的空間裁剪掉即可。

首先以 fdisk 檢查影像檔內部使用的狀況:

fdisk -l my_image.img
Disk my_image.img: 14.9 GiB, 15987638272 bytes, 31225856 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: 0x03ca9076

Device Boot Start End Sectors Size Id Type
my_image.img1 8192 96453 88262 43.1M c W95 FAT32 (LBA)
my_image.img2 98304 27054079 26955776 12.9G 83 Linux

從這個輸出中可以看出每個分割區在磁碟中的開始位置(Start)與結束位置(End),最後一個分割區結束的位置是 26955776,也就是說在這個位置之後的空間,就是沒有使用到的部份,也就是可以裁剪掉的部份。

這裡的輸出中也有說明一個 sector 的大小是 512 位元組(bytes),而 sector 的計算方式是從 0 開始起算的,所以整個磁碟從開頭算起,一直到有資料的最末端,總共的大小應該是 (26955776+1)*512 位元組(bytes)。

計算出資料在磁碟中最末端的位置之後,就可以使用 truncate 裁剪影像檔,只留下前面有資料的部份:

# 裁剪影像檔
truncate --size=$[(27054079+1)*512] my_image.img

裁剪影像檔必須很謹慎,萬一弄錯資料就毀了,若是不確定的話,記得先備份影像檔,以免出錯造成資料損毀救不回來。

Comments

No comments yet. Why don’t you start the discussion?

    發佈留言

    發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *