SWUpdate — это агент обновлений Linux, целью которого является эффективный и безопасный способ обновления встроенной системы. SWUpdate поддерживает локальные и удаленные обновления, включает несколько стратегий обновления, и его можно легко интегрировать в систему сборки Yocto, подключив слой meta-swupdate.
В статье описывается как можно настроить режим обновления в Yocto наиболее простым способом для платы Orange Pi R1, таким же образом вы можете настроить и обновление для самой распространенной платы Raspberry Pi.
Образ Yocto для которого будет подготовлено обновление наследуется от core-image-minimal и выполняет функцию простого маршрутизатора, используя DHCP и Shorewall.
Статья из серии: если хочешь что то обновить, сделай это сам.
Назначение и возможности SWUpdate
SWUpdate позволяет настроить обновление ПО для встраиваемых систем наиболее надежным способом. SWUpdate поддерживает распространенные носители на встроенных устройствах, такие как: флеш память NAND, eMMC, SD карты памяти, а также SPI-NOR.
В SWUpdate существует возможность расширить процедуру обновления с помощью сценариев обновления, которые можно запустить до или после установки. Сценарии могут быть написаны на языке LUA. Пакет обновления описывается в файле sw-description с использованием синтаксиса libconfig или JSON.
Для развертывания программного обеспечения можно использовать:
Локальное хранилище;
Интегрированный веб-сервер;
Получение с удаленного сервера по протоколам http и https;
C помощью бэкенда т.е. обновление загружается с удаленного сервера (режим suricatta). Текущая версия SWUpdate поддерживает сервер hawkBit.
Обновление программного обеспечения поставляется в виде образов, tar-архивов, сжатых с помощью gzip.
Обновление ПО на встраиваемой системе невозможно без непосредственного взаимодействия с загрузчиком ОС. SWUpdate поддерживает загрузчики U-Boot и Grub. Для встраиваемых систем по большей части используется U-Boot, так как он поддерживает наибольшее количество оборудования.
В большинстве случаев требуется обновить ядро и корневую файловую систему, с сохранением пользовательских данных. И лишь в крайне редких случаях требуется обновить загрузчик. Обновление загрузчика может привести к выходу из строя платы, и в этом случае возможно придется отправить плату обратно производителю.
Стратегия обновления SWUpdate
В зависимости от ресурсов системы могут использоваться разные стратегии обновлении, вот две из них:
Единая копия с использованием отдельных образов;
Стратегия двойного копирования.
Основная концепция единой копии заключается в том, что разработчик поставляет один большой образ, в котором все отдельные образы упакованы в формате CPIO, вместе с дополнительным файлом (sw-description), который содержит мета информацию о каждом отдельном образе.
Стратегия двойного копирования используется в том случае, если в хранилище достаточно места для сохранения двух копий всего программного обеспечения. В этом случае можно гарантировать, что всегда будет рабочая копия, даже если в процессе обновления что то пошло не так, например произошел сбой из за отключения питания.
Каждая копия содержит ядро, файл дерева устройств и корневую файловую систему. Для этой стратегии SWUpdate запускается в качестве прикладного программного обеспечения для обновления резервной копии, оставляя текущую копию ПО не тронутой.
Основным носителем информации для платы Orange Pi R1 является microSD карта памяти и для обновления программного обеспечения я буду использовать стратегию с двойной копией.
Примечание:
SD карты часто сыпятся, являются крайне не надежными, но их очень легко заменить, и в идеале для увеличения срока службы карты памяти файловая система rootfs должна быть использована в режиме только чтение.
Подключение механизма обновления к своему дистрибутиву в Yocto
Тот образ дистрибутива, для которого мне необходимо обновление, наследуется от core-image-minimal. Дистрибутив собирается для платы Orange Pi R1, она такая же, как и Orange Pi Zero только с двумя сетевыми интерфейсами.
В Yocto для сборки я буду использовать параметр MACHINE = "orange-pi-zero".
В первую очередь необходимо подключить слой meta-swupdate в build/conf/blayers.conf:
...
${BSPDIR}/sources/meta-swupdate \
...
После этого необходимо добавить расширение рецепта для сборки SWUpdate:
── recipes-support
└── swupdate
├── swupdate
│ └── orange-pi-zero
│ ├── 09-swupdate-args
│ ├── defconfig
│ └── swupdate.cfg
└── swupdate_%.bbappend
Расширение включает три файла:
09-swupdate-args: скрипт для формирования аргументов с которыми запускается программа SWUpdate;
defconfig: конфигурация для сборки программы, используется процедура сборки Kbuild;
swupdate.cfg: конфигурация для запуска программы SWUpdate.
Содержимое скрипта 09-swupdate-args:
rootfs=`mount | grep "on / type" | cut -d':' -f 2 | cut -d' ' -f 1`
if [ $rootfs == '/dev/mmcblk0p2' ];then
selection="-e stable,copy2"
else
selection="-e stable,copy1"
fi
state=`fw_printenv ustate | cut -f 2 -d'='`
if [ "$state" == "1" ];then
SWUPDATE_SURICATTA_ARGS="-c 2"
else
SWUPDATE_SURICATTA_ARGS=""
if [ -e /media/etc/swupdate.cfg ];then
CFGFILE="/media/etc/swupdate.cfg"
else
CFGFILE="/etc/swupdate.cfg"
fi
SWUPDATE_ARGS="-H orange-pi-zero:1.0 ${selection} -f ${CFGFILE}"
Скрипт 09-swupdate-args используется для определения текущей корневой файловой системы (переменная "selection"). Это позволяет выбрать на какой носитель в стратегии двойного копирования будет записываться обновление. Для загрузки с /dev/mmcblk0p2 (rootfs1) обновление будет записано на следующий раздел диска (копия 2), а для загрузки с /dev/mmcblk0p3 (rootfs2) обновление будет записано на предыдущий раздел диска (копия 1).
Параметр из переменных загрузчика u-boot "ustate == 1" определяет будет ли запущен режим обновления с использованием сервера HawkBit (режим suricatta).
Скрипт также формирует аргументы запуска SWUpdate с указанием названием компьютера "-H orange-pi-zero" и версией аппаратной платформы "1.0". Этот идентификатор должен совпасть со значением указанным в конфигурационном файле sw-description, иначе обновление не установиться.
Конфигурационный файл swupdate.cfg также содержит общие настройки обновления, настройки загрузки, настройки Suricatta и настройки локального Web Сервера.
Содержимое файла swupdate.cfg:
globals :
{
verbose = true;
loglevel = 5;
syslog = true;
/* public-key-file = "test.pem";*/
};
download :
{
retries = 3;
timeout = 1800;
};
identify : (
{ name = "orange-pi-zero"; value = "1.0"; }
);
suricatta :
{
tenant = "default";
id = "orange-pi-zero";
confirm = 0;
url = "http://paperina2:8280";
polldelay = 60;
nocheckcert = true;
retry = 4;
retrywait = 200;
loglevel = 10;
userid = 0;
groupid = 0;
max_artifacts = 1;
/*
cafile = "/etc/ssl/cafile";
sslkey = "/etc/ssl/sslkey";
sslcert = "/etc/ssl/sslcert";
*/
};
webserver :
{
document_root = "/www";
userid = 0;
groupid = 0;
};
Для подключения механизма обновления в конфигурационном файле слоя conf/layer.conf, который будет использовать слой meta-swupdate необходимо добавить секцию:
# libubootenv — это библиотека, которая обеспечивает независимый
# от аппаратного обеспечения способ доступа к среде U-Boot.
# позволяет выполнять команды "fw_printenv / fw_setenv"
PREFERRED_PROVIDER_u-boot-fw-utils = "libubootenv"
# ядро Linux, которое содержит дополнительную служебную информацию для U-Boot
KERNEL_IMAGETYPE = "uImage"
# для обновления используется сжатая версия корневой файловой системы rootfs (ext4)
# образ дистрибутива подготавливается с использованием механизма wic
IMAGE_FSTYPES += " wic ext4.gz"
# указание wic сценария для разбиения на логические разделы
WKS_FILES_orange-pi-zero = "sunxi-mmc-spl.wks"
Для того, чтобы включить механизм обновления в уже готовый образ Yocto Project вы можете добавить файл рецепта update-image.bb, который наследуется от класса swupdate, c указанием трех основных переменных:
- IMAGE_DEPENDS: образ от которого зависит сборка обновления;
- SWUPDATE_IMAGES: образ файлы которого будут включены в сборку обновления;
- SWUPDATE_IMAGES_FSTYPES: тип и формат файловой системы, в котором зависимый образ будет включен в состав обновления.
Файл рецепта update-image.bb:
DESCRIPTION = "Example image demonstrating how to build SWUpdate compound image"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
inherit swupdate
SRC_URI = "\
file://emmcsetup.lua \
file://sw-description \
"
# images to build before building swupdate image
IMAGE_DEPENDS = "router-bs-image"
# images and files that will be included in the .swu image
SWUPDATE_IMAGES = "router-bs-image"
SWUPDATE_IMAGES_FSTYPES[router-bs-image] = ".ext4.gz"
Описание образа обновления и сценарий развертывания обновления включаются в update-image.bb в виде двух файлов sw-description и emmcsetup.lua.
Файл sw-description:
software =
{
version = "0.1.0";
orange-pi-zero = {
hardware-compatibility: [ "1.0"];
stable : {
copy1 : {
images: (
{
filename = "router-bs-image-orange-pi-zero.ext4.gz";
type = "raw";
compressed = true;
device = "/dev/mmcblk0p2";
}
);
scripts: (
{
filename = "emmcsetup.lua";
type = "lua";
}
);
uboot: (
{
name = "opipart";
value = "2";
}
);
};
copy2 : {
images: (
{
filename = "router-bs-image-orange-pi-zero.ext4.gz";
type = "raw";
compressed = true;
device = "/dev/mmcblk0p3";
}
);
scripts: (
{
filename = "emmcsetup.lua";
type = "lua";
}
);
uboot: (
{
name = "opipart";
value = "3";
}
);
};
};
}
}
Файл sw-description описывает аппаратную платформу для которой используется обновление "orange-pi-zero", и идентификатор "hardware-compatibility" для указания номера версии этой платформы.
Секцию с названием дистрибутива обновления "stable" и разделением в соответствии со стратегией обновления "двойная копия" с подсекциями "copy1" и "copy2", каждая из которых содержит название образа обновления "filename", с указанием формата образа и логическим разделом на который будет записано обновление.
Здесь также указывается скрипт, отвечающий за развертывания обновления и переменная загрузчика uboot, которая будет изменена после успешного завершения обновления. Переменная "opipart" сохраняется в файле настроек /boot/uboot.env и будет содержать логический номер раздела с которого будет загружаться ядро и корневая файловая система.
Примечание:
Физически переменные среды загрузчика uboot располагаются на первом логическом разделе диска /dev/mmcblk0p1, об этом я напишу подробней чуть ниже.
Файл emmcsetup.lua:
function os.capture(cmd)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
return s
end
function file_exists(name)
local f=io.open(name,"r")
if f~=nil then io.close(f) return true else return false end
end
function cmdexec(cmd)
local ret, s, status = os.execute(cmd)
if (status ~= 0) then
return false, cmd .. " return with error"
end
return true,""
end
function preinst()
local out
local s1
local ret
local log = os.tmpname()
local eMMC = "/dev/mmcblk0"
ret = file_exists("/dev/mmcblk0")
if (ret == false) then
return false, "Cannot fine eMMC"
end
cmdexec("/usr/sbin/sfdisk -d " .. eMMC .. "> /tmp/dumppartitions")
-- check if there are two identical partitions
-- and create the second one if no available
f = io.input("/tmp/dumppartitions")
fo = io.output("/tmp/partitions")
t = f:read()
found = false
while (t ~= nil) do
j=0
j=string.find(t, "/dev/mmcblk0p3")
fo:write(t .. "\n")
if (j == 1) then
found=true
break
end
j=string.find(t, "/dev/mmcblk0p2")
if (j == 1) then
start, size = string.match(t, "%a+%s*=%s*(%d+), size=%s*(%d+)")
end
t = f:read()
end
if (found) then
f:close()
fo:close()
return true, out
end
start=start+size
partitions = eMMC .. "p3 : start= " .. string.format("%d", start) .. ", size= " .. size .. ", type=83\n"
fo:write(partitions)
fo:close()
f:close()
out = os.capture("/usr/sbin/sfdisk --force " .. eMMC .. " < /tmp/partitions")
-- use partprobe to inform the kernel of the new partitions
cmdexec("/usr/sbin/partprobe " .. eMMC)
return true, out
end
function postinst()
local out = "Post installed script called"
return true, out
end
Использование WIC для создания логических разделов
Для того, чтобы программа SWUpdate смогла успешно накатить обновление в соответствии с мета информацией файла sw-description и выбранной стратегией обновления, необходимо записать исходный образ дистрибутива на файловый носитель в определенном формате, с разбиением на несколько логических разделов.
Для упрощения этой процедуры используется механизм WIC и в этом случае структура исходного raw образа описывается о одном файле sunxi-mmc-spl.wks
следующего содержания:
part u-boot --source rawcopy --sourceparams="file=u-boot-sunxi-with-spl.bin" --ondisk mmcblk0 --no-table --align 8
part /boot --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 1024 --fixed-size 16
part / --source rootfs --ondisk mmcblk0 --fstype=ext4 --label rootfs1 --align 1024 --fixed-size 256
part --source rootfs --ondisk mmcblk0 --fstype=ext4 --label rootfs2 --align 1024 --fixed-size 256
part --ondisk mmcblk0 --fstype=ext4 --label data --align 1024 --fixed-size 512
механизм подключается в конфигурационном файле слоя:
IMAGE_FSTYPES += " wic"
WKS_FILES_orange-pi-zero = "sunxi-mmc-spl.wks"
В первой строке файла "part u-boot ..." указывается размещение вторичного загрузчика (SPL) в начале дискового носителя без таблицы разделов. Сразу после включения питания система еще ничего не может, обычно в самом начале работает только одно процессорное ядро и доступна статическая память на кристалле очень ограниченного размера, поэтому процесс загрузки сильно фрагментирован и в нем обычно участвуют несколько загрузчиков.
Первичный загрузчик размещен в ПЗУ процессора и он умеет работать с памятью процессора SRAM и основной его задачей является загрузка в память и передача управления вторичному загрузчику, который входит в состав образа "u-boot-sunxi-with-spl.bin".
Файл загрузчика должен быть размещен по фиксированным адресам на одном из поддерживаемых носителях, в данном случае в начале SD карты памяти по смещению 8Kбайт.
Одноплатный компьютер Orange Pi R1(Zero) включает процессор "Allwinner H2(+) quad core Cortex A7". Информацию о загрузке с карты памяти SD, а именно стартовый адрес по которому должен располагаться загрузчик SPL, вы можете посмотреть здесь. Вторичный загрузчик уже умеет работать с динамической памятью DRAM и его задача скопировать и запустить из этой памяти полноценный загрузчик U-Boot, который также входит в состав интегрированного образа "u-boot-sunxi-with-spl.bin".
Загрузчик ищет стартовый конфигурационный сценарий boot.scr на первом логическом разделе ("part /boot ...") и запускает его. Образ bootimg-partition также содержит linux ядро uImage и файл дерева устройств sun8i-h2-plus-orangepi-zero.dtb. В дальнейшем, после первого запуска на этом разделе будут храниться текущие переменные среды u-boot, сохраненные командой saveenv в файле uboot.env. После загрузки системы, раздел монтируется в fstab, и файл настроек будет доступен по пути /boot/uboot.env. Размер первого логического раздела 16 Мбайт.
Следующие две записи создают две одинаковые копии корневой файловой системы rootfs, размещаемые на втором логическом разделе "/dev/mmcblk0p2" и на третьем логическом разделе "/dev/mmcblk0p3" соответственно, при этом для SWUpdate используется стратегия двойного копирования. Размер разделов фиксированный и равен 256 Мб.
Примечание:
Чем больше размер разделов, тем больше будет размер исходного raw образа для первоначального копирования на карту памяти SD. RAW образ c расширением .wic копируется командой dd. Размер подбирается из предпосылок будущей функциональности дистрибутива. При превышении этого размера вы не сможете обновить образ.
И наконец четвертым разделом будет являться раздел с данными, которые необходимо хранить отдельно от корневой файловой системы. Это позволяет сохранить пользовательские данные после завершения процесса обновления.
Подключение файловой системы overlayfs
Диск будет подключен с помощью механизма overlayfs в точку монтирования /etc в качестве файлового слоя верхнего уровня и это позволит все изменения существующих конфигурационных файлов, а также новых файлов в каталоге /etc хранить на этом логическом разделе.
── recipes-core
└── overlayfs
├── etc-overlay.bb
└── files
├── etc.mount
└── overlays-etc-dirs.service
В рецепте используется следующий скрипт Systemd для монтирования диска:
[Unit]
Description=Overlay /etc/
Requires=overlays-etc-dirs.service
After=overlays-etc-dirs.service
[Mount]
What=overlay
Where=/etc
Type=overlay
Options=lowerdir=/etc,upperdir=/media/overlayfs/etc/upper,workdir=/media/overlayfs/etc/work
[Install]
WantedBy=local-fs.target
Доступ к переменным среды загрузчика U-Boot
В процессе обновления программа SWUpdate использует библиотеку libubootenv для доступа к переменным загрузчика U-Boot (команды "fw_printenv / fw_setenv"). Эта библиотека ищет информацию о месте нахождения переменных среды в файле /etc/fw_env.config, и для каждой платы эти адреса могут различаться. Поэтому следующим шагом является дополнение для рецепта libubootenv_%.bbappend:
└── recipes-bsp
└── libubootenv
├── files
│ ├── fw_env.config
│ └── orange-pi-zero
│ └── fw_env.config
└── libubootenv_%.bbappend
Содержание дополнения рецепта libubootenv_%.bbappend:
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append:class-target = " file://fw_env.config"
do_install:append:class-target() {
install -d ${D}${sysconfdir}
install -m 644 ${WORKDIR}/fw_env.config ${D}${sysconfdir}
}
FILES:${PN}:append:class-target = " ${sysconfdir}"
Конфигурация "/etc/fw_env.config" для платы Orange Pi Zero:
/boot/uboot.env 0x0000 0x20000
Здесь указывается начальный адрес и размер выделяемый для переменных среды т.е. 128 kБайт.
Стартовый конфигурационный сценарий U-Boot
Для самого загрузчика U-Boot необходимо добавить стартовый конфигурационный сценарий boot.cmd, это текстовый файл который будет преобразован в файл boot.scr, размещаемый на первом логическом разделе.
└── dynamic-layers
└── orange
└── recipes-bsp
└── u-boot
├── files
│ └── boot.cmd
└── u-boot_%.bbappend
В Yocto можно выборочно подключать определенные рецепты, при работе с разными аппаратными конфигурациями (BSP слои). Для этого используется динамический слой, который подключается по имени коллекции, т.е. рецепты слоя будут подключены только в том случае, если в списке слоев будет слой с BBFILE_COLLECTIONS+=meta-sunxi.
Это позволяет в одном слое совмещать разную функциональность, которую в противном случае пришлось бы хранить в разных слоях.
Слой подключается в layer.conf следующим образом:
BBFILES_DYNAMIC += " \
meta-sunxi:${LAYERDIR}/dynamic-layers/orange/*/*/*.bb \
meta-sunxi:${LAYERDIR}/dynamic-layers/orange/*/*/*.bbappend \
"
Содержание дополнения рецепта u-boot_%.bbappend:
###https://stackoverflow.com/questions/58610052/how-to-get-thisdir-inside-do-unpack-append-in-bbappend-file
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI_append += " file://boot.cmd"
SAVED_DIR := "${THISDIR}/files"
do_unpack_append(){
bb.build.exec_func('replace_file', d)
}
replace_file(){
cp -f ${SAVED_DIR}/boot.cmd ${WORKDIR}/boot.cmd
}
Стартовый конфигурационный сценарий boot.cmd:
saveenv
if env exists opipart;then echo Booting from mmcblk0p${opipart};else setenv opipart 2;echo opipart not set, default to ${opipart};fi
setenv bootargs console=${console} console=tty1 root=/dev/mmcblk0p${opipart} rootwait panic=10 ${extra}
load mmc 0:${opipart} ${fdt_addr_r} ${fdtfile} || load mmc 0:${opipart} ${fdt_addr_r} boot/${fdtfile}
load mmc 0:${opipart} ${kernel_addr_r} zImage || load mmc 0:${opipart} ${kernel_addr_r} boot/zImage || load mmc 0:${opipart} ${kernel_addr_r} uImage || load mmc 0:${opipart} ${kernel_addr_r} boot/uImage
bootz ${kernel_addr_r} - ${fdt_addr_r} || bootm ${kernel_addr_r} - ${fdt_addr_r}
В том случае, если переменная выбора корневой файловой системы "opipart" не установлена, то по умолчанию используется второй логический раздел диска.
Когда SWUpdate успешно завершает обновление резервной копии корневой файловой системы, он переключает эту переменную т.е. меняет основную и резервную rootfs местами для следующей загрузки.
Это делается например так, командой:
fw_setenv opipart 3
Примечание:
Таким же образом вы можете вручную сменить текущую версию системы, переключив ее на предыдущую, без использования SWUpdate. Если текущая функциональность вас каким либо образом не устроила, это быстро и требует только перезагрузки.
В начале команда "load mmc 0:${opipart} ${fdt_addr_r} boot/${fdtfile}" загружает файл дерева устройств для платы в память, где:
0 - номер диска, нумерация дисков начинается с 0;
opipart - номер раздела, задается начиная с 1. Номер раздела 0 указывает, что все устройство должно использоваться как один «раздел».
Затем команда "load mmc 0:${opipart} ${kernel_addr_r} boot/uImage" загружает ядро в память и передает управления загруженному ядру "bootm ${kernel_addr_r} - ${fdt_addr_r}".
Для корректного выполнения обновления через SWUpdate на работающей системе Linux должны быть подключены дополнительные дисковые разделы, указанные выше.
В первую очередь это загрузочный раздел и раздел с данными. Дополнение для рецепта base-files_%.bbappend:
└── recipes-core
└── base-files
├── base-files
│ └── fstab
└── base-files_%.bbappend
Содержание файла fstab:
# stock fstab - you probably want to override this with a machine specific one
/dev/root / auto defaults 1 1
proc /proc proc defaults 0 0
devpts /dev/pts devpts mode=0620,ptmxmode=0666,gid=5 0 0
tmpfs /run tmpfs mode=0755,nodev,nosuid,strictatime 0 0
tmpfs /var/volatile tmpfs defaults 0 0
/dev/mmcblk0p1 /boot vfat defaults 0 0
/dev/mmcblk0p4 /media ext4 defaults 0 0
Таким образом fstab добавляется вручную, так как он должен присутствовать как в rootfs (wic), так и в update-image (ext4.gz) и чтобы исключить обновление файла fstab (дублирование строк) при создании wic образа в layer.conf используется запись:
WIC_CREATE_EXTRA_ARGS = "--no-fstab-update"
После запуска встроенной системы, проще всего проверить механизм обновления через встроенный Web сервер, который доступен на 8080 порту:
http://ip_address:8080
Web интерфейс крайне минималистичен, достаточно выбрать файл с обновлением и расширением swu, а затем нажать кнопку загрузки. Интерфейс позволяет посмотреть текущий лог процесса обновления.
После успешного обновления плату можно перезагрузить вручную, подключившись по ssh протоколу и выполнив команду reboot.
Размер файла обновления с ядром и корневой файловой системой rootfs у меня занимает ~44 Мбайта (update-image-orange-pi-zero-20221017123455.swu).
Suricatta - режим демона SWUpdate, при котором он регулярно опрашивает удаленный сервер на наличие обновлений, загружает и устанавливает их, а затем перегружает систему. Для этого вначале необходимо установить и запустить сервер обновления hawkBit, например на Desktop компьютере с Ubuntu:
git clone https://github.com/eclipse/hawkbit
cd hawkbit
git checkout 0.3.0M7
# собрать через Maven
sudo apt install maven
mvn clean install
# и запустить
java -jar ./hawkbit-runtime/hawkbit-update-server/target/hawkbit-update-server-0.3.0-SNAPSHOT.jar
По умолчанию настройка сервера доступна через http://localhost:8080, пользователь admin, пароль admin.
Конфигурация для работы SWUpdate c hawkbit в swupdate.cfg:
suricatta :
{
tenant = "default";
id = "orange-pi-zero";
confirm = 0;
url = "http://paperina2:8280";
polldelay = 60;
nocheckcert = true;
retry = 4;
retrywait = 200;
loglevel = 10;
userid = 0;
groupid = 0;
max_artifacts = 1;
};
Режим включается в том случае, если установлена переменная u-boot "ustate = 1".
Для того, чтобы не заморачиваться с перенастройкой, можно проверить взаимодействие с HawkBit вручную запустив команду на встраиваемой системе:
swupdate -H orange-pi-zero:1.0 -e stable,copy2 -f /etc/swupdate.cfg -l 5 -u '-t DEFAULT -u http://ip_address:8080 -i orange-pi-zero'
Указав порт по умолчанию 8080 и ip адрес вашего Desktop компьютера, на котором запущен hawkBit. HawkBit позволяет управлять обновлениями достаточно сложным образом, но это уже совсем другая история.
Зависимости образа дистрибутива, для которого нужно создать обновление update-image у меня следующие:
IMAGE_INSTALL += " \
base-files \
base-passwd \
busybox \
mtd-utils \
mtd-utils-ubifs \
libconfig \
util-linux-sfdisk \
libubootenv-bin \
swupdate \
swupdate-www \
etc-overlay \
"
Инструкция по сборке образа
mkdir yo-swupdate
cd yo-swupdate
repo init -u https://github.com/berserktv/bs-manifest -m orange/hardknott/router-bs-swupdate-0.7.6.xml
repo sync
./shell.sh
bitbake update-image
На мой взгляд SWUpdate очень классный проект, который хорошо документирован и который позволяет настроить процесс обновления достаточно надежным способом, и вы всегда можете увеличить эту надежность подобрав и соответствующую аппаратную платформу, а проверить этот механизм можно на простых платах прототипирования типа Orange Pi R1.
zedroid
Очень крутая статья! Очень подробно расписано как включить в релиз йокты