Я работаю над проектом, в котором обновление до Raspberry PI выполняется по протоколу HTTP, а Raspberry PI не будет доступен напрямую (нельзя просто поменять местами карты).
Я хотел бы настроить раздел следующим образом:
- Раздел 1- / boot (содержит ядра для обоих разделов)
- Раздел 2- / (раздел восстановления)
- Раздел 3- / (основной раздел)
Когда обновление идет плохо и Raspberry PI попадает в цикл перезагрузки или зависает при загрузке, я бы хотел, чтобы пользователь мог нажать кнопку, которая запускает линию GPIO, которая заставляет загрузчик загружаться в раздел восстановления вместо основного раздела.
Раздел восстановления никогда не будет обновлен, так что это будет безопасно.
Я вижу пару вариантов:
- Всегда загружайтесь в раздел восстановления, проверьте GPIO, затем загрузитесь в основной раздел без нажатия кнопки
- GPIO проверяется загрузчиком напрямую
Я в основном пытаюсь сделать что-то похожее на то, что делают маршрутизаторы, где, если вы удерживаете перезагрузку во время загрузки, вы можете использовать TFTP поверх нового образа или чего-то еще.
Это возможно с Raspberry PI? Если да, есть ли документация для такого рода вещей?
Редактировать:
Я нашел ответ на этот связанный вопрос: возможно ли двойная загрузка с SD-карты?
Комментарий по вышеупомянутому вопросу привел меня сюда: http://www.berryterminal.com/doku.php/berryboot . Это выглядит многообещающе, но мне придется больше исследовать его, чтобы посмотреть, смогу ли я получить из него GPIO. Если у кого-то есть опыт, я был бы очень заинтересован.
/boot
(RO),/
(RO),/var
(RW),/home
(RW). Первоначальной проблемой было повреждение файловой системы при отключении питания во время загрузки. Я все еще хотел бы написать / найти загрузчик 2-го этапа, хотя.Ответы:
Если ошибка может произойти в любое время после запуска системы, вы можете использовать сторожевой таймер и некоторый загрузочный скрипт.
Принцип этого метода заключается в том, что всякий раз, когда система перезагружается без надлежащего выключения, она переходит в раздел восстановления.
Вам нужно написать скрипт, который запускается каждый раз, когда система запускается и правильно завершает работу. Перейдите
/boot/cmdline.txt
в раздел восстановления при запуске системы и вернитесь обратно, прежде чем правильно завершить работу.Затем настройте сторожевой таймер. Вы можете использовать встроенный в микросхему BCM2835 или (при использовании платы ревизии 2) построить свой собственный, используя два вывода GPIO, разъем сброса P6 и микросхему 555. Когда запускается критическая программа, запустите сторожевой таймер и периодически пинайте собаку, если система работает правильно. При сбое системы сторожевой таймер отключается и сбрасывает процессор, отправляя его в раздел восстановления. Это также не требует взаимодействия с пользователем, а если используется встроенный таймер, нет GPIO.
Используя этот метод, вы также можете реализовать кнопку сброса, которая гарантирует отправку системы для восстановления вручную на плате Rev. 2 путем установки кнопки в заголовок P6.
источник
У меня есть способ сделать это без взлома ядра, который включает в себя защиту системы от несвоевременной перезагрузки:
При неудачном обновлении система будет автоматически загружена в систему восстановления. GPIO не требуется.
источник
Кроме того, существует третье возможное решение, но оно потребует, чтобы вы проанализировали
initrd
некоторую версию дистрибутива Linux для ПК, чтобы выяснить, какpivot_init()
работает системный вызов . Я не уверен, что ядро Пи имеет этот системный вызов. Если это так, этот метод возможен, взлом ядра также не требуется, и он использует один GPIO.Для этого вам нужно написать пользовательскую
init
программу в производственной системе. проверьте, включен ли GPIO. Если так, тоpivot_root()
до восстановления. Затемexec()
оригинал,init
чтобы система продолжала загружаться. В производственной системе вы можете найти способ обеспечить непрерывную работу этого устройства наблюдения за GPIOinit
(PID = 2) с оригиналомinit
(PID = 1), следить за GPIO и перезагружаться для восстановления, если кнопка нажата.источник