Вопрос или проблема
Я использую параметр init= для передачи скрипта во время загрузки ядра. С помощью этого скрипта я настраиваю overlayfs, используя два раздела на устройстве mmc.
Это работает нормально. Я использую root=/dev/mmcblk0p1 в качестве корневого.
При загрузке я хочу иметь возможность обновить раздел p1 новыми данными с mmcblk0p3.
Так как p1 смонтирован в качестве корня, я не могу найти способ размонтировать его, чтобы перезаписать новыми данными и снова смонтировать, чтобы продолжить обычную последовательность загрузки.
Можно ли осуществить switch root или pivot root с mmcblk0p1 на, скажем, mmcblk0p3 и обратно?
Система на базе ARM с uboot.
Вы можете использовать pivot_root
, чтобы временно переключить корневую файловую систему на другой раздел, обновить оригинальный корневой раздел, а затем переключиться обратно. Вот общий обзор того, как этого можно достичь:
-
Загрузка с начальным корнем на
mmcblk0p1
: Ваша система загружается сroot=/dev/mmcblk0p1
и выполняет ваш init-скрипт. -
Смонтировать
mmcblk0p3
: В вашем init-скрипте смонтируйтеmmcblk0p3
в временный каталог, например/mnt/newroot
. -
Переключить корень на
mmcblk0p3
: Используйтеpivot_root
для переключения корневой файловой системы на/mnt/newroot
. -
Размонтировать оригинальный корень: После переключения корня вы можете размонтировать оригинальную корневую файловую систему (
mmcblk0p1
). -
Обновить
mmcblk0p1
: Скопируйте новые данные сmmcblk0p3
наmmcblk0p1
. -
Вернуть корень на
mmcblk0p1
: Используйтеpivot_root
снова для переключения на оригинальную корневую файловую систему. -
Продолжить процесс загрузки: Продолжите обычную последовательность загрузки.
Вот упрощенный пример того, как можно реализовать это в вашем init-скрипте:
#!/bin/sh
# Смонтировать новую корневую файловую систему
mkdir -p /mnt/newroot
mount /dev/mmcblk0p3 /mnt/newroot
# Переключить корень на mmcblk0p3
mkdir -p /mnt/newroot/oldroot
pivot_root /mnt/newroot /mnt/newroot/oldroot
# Размонтировать старую корневую файловую систему
umount /oldroot
# Обновить mmcblk0p1 новыми данными с mmcblk0p3
dd if=/dev/mmcblk0p3 of=/dev/mmcblk0p1 bs=1M
# Переключить корень обратно на mmcblk0p1
mkdir -p /oldroot/newroot
mount /dev/mmcblk0p1 /oldroot/newroot
pivot_root /oldroot/newroot /oldroot/newroot/oldroot
# Размонтировать временную корневую файловую систему
umount /oldroot/newroot
# Продолжить обычный процесс загрузки
exec /sbin/init
Объяснение:
- Смонтировать
mmcblk0p3
: Мы монтируемmmcblk0p3
в/mnt/newroot
. - Переключение корня: Команда
pivot_root
переключает корневую файловую систему на/mnt/newroot
. Старый корень перемещается в/mnt/newroot/oldroot
. - Размонтирование старого корня: После переключения старый корень (
mmcblk0p1
) размонтируется. - Обновление
mmcblk0p1
: Командаdd
копирует содержимоеmmcblk0p3
наmmcblk0p1
. - Возвращение назад: Мы возвращаемся на оригинальную корневую файловую систему (
mmcblk0p1
). - Продолжение загрузки: Наконец, процесс загрузки продолжается путем выполнения
/sbin/init
.
Важные соображения:
- Обработка ошибок: Добавьте обработку ошибок, чтобы убедиться, что каждый шаг успешен перед переходом к следующему.
- Конфигурация загрузчика: Убедитесь, что ваш загрузчик (U-Boot) правильно настроен для передачи необходимых параметров ядра.
- Тестирование: Тщательно протестируйте этот процесс в контролируемой среде перед развертыванием в эксплуатации.
Этот подход должен позволить вам обновить корневой раздел (mmcblk0p1
) новыми данными с другого раздела (mmcblk0p3
) в процессе загрузки.
.
Ответ или решение
Конфигурация пользовательских init-скриптов и корневой файловой системы на стадии загрузки ядра может быть сложной, особенно при необходимости обновления корневого раздела. Ваша ситуация подразумевает использование скрипта init для настройки OverlayFS с использованием двух разделов на устройстве MMC. Этот процесс требует тщательного управления корневыми файловыми системами и использования команд, таких как pivot_root
, чтобы сменить корневую файловую систему, не нарушая последовательность загрузки.
Теория
При загрузке операционной системы ядро монтирует определённый раздел в качестве корневого (представленный в вашем случае как /dev/mmcblk0p1
). Во время этого процесса невозможно просто так размонтировать корневую файловую систему, так как она обеспечивает критические ресурсы для продолжающейся загрузки. Однако, команда pivot_root
предоставляет механизм смены корневой файловой системы, перемещая текущий корень в новое местоположение и позволяя дальнейшую модификацию старой корневой системы, как только она станет неактивной.
pivot_root
может эффективно заменить текущую корневую директорию на другую точку монтирования, что позволяет временно отключить исходный корень и внести в него изменения. Ваша задача заключается в том, чтобы обновить данные на mmcblk0p1
из mmcblk0p3
, а также сменить и вернуть корневую файловую систему.
Пример
Предположим, что ваша система начинает работу с mmcblk0p1
в качестве корня. На начальной стадии загрузки ваш init-скрипт может выполнить следующие шаги:
-
Монтирование новой файловой системы: Начните с монтирования
mmcblk0p3
на временную директорию, например,/mnt/newroot
. -
Использование
pivot_root
: Перенесите корень на новый раздел, тем самым создавая условия для безопасного обновления оригинального корня (mmcblk0p1
). -
Размонтирование оригинального корня: После успешного переноса можно безопасно размонтировать старую корневую файловую систему.
-
Обновление: Используйте, например, команду
dd
для копирования новых данных сmmcblk0p3
наmmcblk0p1
. -
Возвращение корня: Снова примените
pivot_root
, чтобы вернуться к использованию оригинального корня. -
Продолжение процесса загрузки: После возврата к первоначальному корню, продолжайте с обычной загрузкой.
Этот процесс представлен в скрипте:
#!/bin/sh
# Монтирование новой корневой файловой системы
mkdir -p /mnt/newroot
mount /dev/mmcblk0p3 /mnt/newroot
# Перемещение корневой ФС на mmcblk0p3
mkdir -p /mnt/newroot/oldroot
pivot_root /mnt/newroot /mnt/newroot/oldroot
# Размонтирование старой корневой ФС
umount /oldroot
# Обновление данных на mmcblk0p1 из mmcblk0p3
dd if=/dev/mmcblk0p3 of=/dev/mmcblk0p1 bs=1M
# Возврат к оригинальной корневой файловой системе
mkdir -p /oldroot/newroot
mount /dev/mmcblk0p1 /oldroot/newroot
pivot_root /oldroot/newroot /oldroot/newroot/oldroot
# Размонтирование временной корневой файловой системы
umount /oldroot/newroot
# Продолжение с обычной загрузкой
exec /sbin/init
Применение
Понимание и реализация вышеописанного сценария требует учёта следующих важных аспектов:
-
Обработка ошибок: Включите обработку ошибок на каждом этапе, чтобы обеспечить целостность и предсказуемость работы вашей системы. Например, проверяйте завершение каждой команды до перехода к следующей.
-
Конфигурация загрузчика: Проверьте, что ваш загрузчик (в данном случае U-Boot) корректно передаёт нужные параметры ядру, позволяющие выполнение всех необходимых операций с корневой файловой системой.
-
Тестирование: Важно тщательно протестировать процедуру в контролируемых условиях, прежде чем внедрять её на реальной системе. Это позволит выявить и устранить потенциальные ошибки или неучтённые ситуации.
Таким образом, pivot_root
представляет собой мощный инструмент для работы с корневыми файловыми системами, позволяя временно изменять их расположение для выполнения обновлений и других операций. Эти шаги помогут вам обновить корневой раздел (mmcblk0p1
) за счёт данных из другого раздела (mmcblk0p3
) в процессе загрузки вашей системы ARM.