Статья будет довольно капитанская: речь пойдет о том как можно стандартными средствами Linux сменить размер раздела внутри файл-образа. Разбирать это будем на следующем примере. Дано: образ Zeroshell для встраиваемых систем на носителях типа CF или USB-flash с которого можно загружаться. Образ содержит в себе 3 раздела с неизменяемыми частями, где хранится конфигурация и файлы дистрибутива и 1 раздел с изменяемой частью, куда записываются профили настроек дистрибутива. По-умолчанию размер этого последнего размера около 1.1 ГБ. На мою старую USB-флешку размером в 1 Гб этот образ не запишешь, хотя полезной нагрузки в исходном образе — чуть больше 400 Мб. Что можно сделать в данной ситуации? Конечно же немного подправить размер 4 раздела для того, чтобы все помещалось.
Итак приступим. Для начала скачаем сам образ тут. Брать надо соответствующий образ с меткой «USB Image». После скачивания смотрим список его разделов:
# fdisk ZeroShell-3.3.2-USB.img Команда (m для справки): p Диск ZeroShell-3.3.2-USB.img: 1992 МБ, 1992294400 байт 255 головок, 63 секторов/треков, 242 цилиндров, всего 3891200 секторов Units = секторы of 1 * 512 = 512 bytes Размер сектора (логического/физического): 512 байт / 512 байт I/O size (minimum/optimal): 512 bytes / 512 bytes Идентификатор диска: 0xcf5090fb Устр-во Загр Начало Конец Блоки Id Система ZeroShell-3.3.2-USB.img1 * 2048 432127 215040 83 Linux ZeroShell-3.3.2-USB.img2 432128 1087487 327680 83 Linux ZeroShell-3.3.2-USB.img3 1087488 1742847 327680 83 Linux ZeroShell-3.3.2-USB.img4 1742848 3891199 1074176 83 Linux
Размер последнего 4 раздела 1074176 Кб или чуть больше 1 Гб. Нам надо сократить его допустим до 128 Мб. Сделать это можно с помощью стандартных утилит работы с файловой системой Linux. Первое что мы делаем — создаем из 4 раздела loop-устройство. Для этого надо правильно посчитать смещение с начала файла и указать максимальный размер устройства, с которым мы будем работать. Считаем смещение по формуле (номерконцараздела — номерначалараздела +1) * размер_блока: (3891199 — 1742848 + 1) * 512 = 892338176, а максимальный размер узнаем умножив количество блоков в разделе на размер блока или 1099956224. Далее с помощью losetup создаем устройство:
losetup -o 892338176 --sizelimit 1099956224 /dev/loop3 ZeroShell-3.3.2-USB.img
Далее проверяем на ошибки этот раздел:
e2fsck -f /dev/loop3
Уменьшаем этот раздел до 128 Мб или 262144 Кб:
resize2fs /dev/loop3 262144k
Отсоединяем устройство:
losetup -d /dev/loop3
Далее переписываем информацию о разделе в MBR:
# fdisk ZeroShell-3.3.2-USB.img Команда (m для справки): p Диск ZeroShell-3.3.2-USB.img: 1992 МБ, 1992294400 байт 255 головок, 63 секторов/треков, 242 цилиндров, всего 3891200 секторов Units = секторы of 1 * 512 = 512 bytes Размер сектора (логического/физического): 512 байт / 512 байт I/O size (minimum/optimal): 512 bytes / 512 bytes Идентификатор диска: 0xcf5090fb Устр-во Загр Начало Конец Блоки Id Система ZeroShell-3.3.2-USB.img1 * 2048 432127 215040 83 Linux ZeroShell-3.3.2-USB.img2 432128 1087487 327680 83 Linux ZeroShell-3.3.2-USB.img3 1087488 1742847 327680 83 Linux ZeroShell-3.3.2-USB.img4 1742848 3891199 1074176 83 Linux Команда (m для справки): d Номер раздела (1-4): 4 Команда (m для справки): n Partition type: p primary (3 primary, 0 extended, 1 free) e расширенный Select (default e): p Выбранный раздел 4 Первый сектор (1742848-3891199, по умолчанию 1742848): Используется значение по умолчанию 1742848 Last сектор, +секторы or +size{K,M,G} (1742848-3891199, по умолчанию 3891199): +262144K Команда (m для справки): p Диск ZeroShell-3.3.2-USB.img: 1992 МБ, 1992294400 байт 255 головок, 63 секторов/треков, 242 цилиндров, всего 3891200 секторов Units = секторы of 1 * 512 = 512 bytes Размер сектора (логического/физического): 512 байт / 512 байт I/O size (minimum/optimal): 512 bytes / 512 bytes Идентификатор диска: 0xcf5090fb Устр-во Загр Начало Конец Блоки Id Система ZeroShell-3.3.2-USB.img1 * 2048 432127 215040 83 Linux ZeroShell-3.3.2-USB.img2 432128 1087487 327680 83 Linux ZeroShell-3.3.2-USB.img3 1087488 1742847 327680 83 Linux ZeroShell-3.3.2-USB.img4 1742848 2267135 262144 83 Linux
Записываем изменения, перечитываем loop-устройство и еще раз проверяем файловую систему на ошибки. Затем сооружаем собственно обновленный файл-образ с помощью dd:
dd if=ZeroShell-3.3.2-USB.img of=ZeroShell-3.3.2-USB-1G.img bs=1024 count=1023624
Все, образ готов для записи на USB-флешку:
dd if=ZeroShell-3.3.2-USB-1G.img of=/dev/sdX bs=1024 count=1023624
Как я уже говорил статья довольно капитанская, т.к. описывает вполне стандартную комбинацию утилит в Linux для манипуляции с файловой системой. Однако это хороший случай их применения с вполне отличным результатом. Надеюсь эта информация поможет кому-то решить его проблему. Источник вдохновения взят тут «Converting ZeroShell 2GB Disk Image to a 1GB Disk Image With Installation«.