# Bootloader Update Manager Веб-приложение на C для обновления ядра, device-tree и U-Boot environment на Orange Pi Zero 2W (Allwinner H618). ## Возможности - **Веб-интерфейс**: Современный адаптивный UI для удобного управления - **Обновление ядра**: Загрузка `Image.gz` в boot раздел - **Обновление Device-Tree**: Загрузка `sun50i-h618-orangepi-zero2w.dtb` - **U-Boot Environment**: Загрузка `uboot.env` - **U-Boot Binary**: Загрузка `u-boot-sunxi-with-spl.bin` с записью в: - `/media/u-boot-sunxi-with-spl.bin` (файл) - `/dev/mtd0` (SPI NOR flash, с предварительным стиранием) - `/dev/mmcblk1` со смещением 8KB (SD карта, аналог `dd seek=8`) - **Редактор extlinux.conf**: Просмотр и редактирование конфигурации загрузчика - **Индикатор прогресса**: Отображение прогресса загрузки в реальном времени - **Авто-монтирование**: Автоматически монтирует `/dev/mmcblk1p1` в `/media` - **Поддержка больших файлов**: - До 200 MB для обычных файлов - До 1 MB для U-Boot Binary (безопасный лимит) - **Перезагрузка системы**: Кнопка безопасной перезагрузки: - `sync()` - сброс буферов ФС - `umount /media` - отмонтирование - `shutdown -r now` - мягкая перезагрузка через finit - **Мониторинг температуры**: Отображение температуры CPU с цветовой индикацией: - < 50°C: 🟢 Зелёный (холодно) - < 70°C: 🔵 Синий (норма) - < 80°C: 🟠 Оранжевый (тепло) - ≥ 80°C: 🔴 Красный (горячо) - **Отслеживание версий файлов**: - Автоматическое сохранение даты/времени загрузки - Файлы `.version` для каждого загруженного файла - Timestamp передаётся от браузера (не зависит от времени на плате) - Человекочитаемый формат: `ГГГГ-ММ-ДД ЧЧ:ММ:СС` - Отображение последней даты модификации в веб-интерфейсе ## Структура проекта ``` . ├── src/ │ ├── main.c # Основной сервер (C + mongoose + cJSON) │ └── lib/ │ ├── mongoose.c/h # Mongoose web server (v7.19) │ └── cJSON.c/h # JSON parser (v1.7.18) ├── web/ │ ├── index.html # HTML веб-интерфейса │ ├── style.css # Стили веб-интерфейса │ └── app.js # Frontend JavaScript ├── mongoose_config.h # Конфигурация mongoose ├── Makefile # Конфигурация сборки └── README.md # Документация ``` ## Требования - GCC компилятор - Библиотеки встроены в проект: - [Mongoose](https://mongoose.ws) v7.19 - встроенный веб-сервер - [cJSON](https://github.com/DaveGamble/cJSON) v1.7.18 - JSON парсер - Права root (для монтирования устройств и перезагрузки) ## Сборка ```bash make ``` ## Запуск ```bash sudo ./up ``` Сервер запустится на **http://localhost:43243** ## Веб-интерфейс ### System Status - Статус монтирования `/dev/mmcblk1p1` → `/media` - Температура CPU (обновление каждые 5 секунд) ### File Versions Отображение даты последней загрузки/изменения для файлов: - Kernel (Image.gz) - Device-Tree (DTB) - U-Boot Env - U-Boot Binary - Extlinux (обновляется при сохранении через редактор) **Формат даты**: `2026-03-14 12:34:56` **Примечание**: Время берётся из браузера клиента, поэтому корректно даже если на плате не настроено системное время. ### File Upload Четыре вкладки для загрузки: - **Kernel** → `/media/Image.gz` - **Device-Tree** → `/media/sun50i-h618-orangepi-zero2w.dtb` - **U-Boot Environment** → `/media/uboot.env` - **U-Boot Binary (SPL)** → `/media/u-boot-sunxi-with-spl.bin` + `/dev/mtd0` + `/dev/mmcblk1` (+8KB) При загрузке браузер автоматически отправляет текущий timestamp, который сохраняется в `.version` файл. ### extlinux.conf Editor - Загрузка текущего `extlinux.conf` - Редактирование в текстовом поле - Сохранение изменений (с записью версии) - Очистка редактора ### System Control - Кнопка **Reboot System** с подтверждением - Безопасная перезагрузка через `shutdown -r now` ## API Endpoints | Endpoint | Method | Описание | |----------|--------|----------| | `/api/upload?timestamp=...` | POST | Загрузка файлов (kernel, dtb, uboot, uboot_bin) | | `/api/extlinux?timestamp=...` | GET | Чтение extlinux.conf | | `/api/extlinux?timestamp=...` | POST | Запись extlinux.conf (с версией) | | `/api/progress` | GET | Статус загрузки | | `/api/mount` | GET | Статус монтирования | | `/api/temperature` | GET | Температура CPU | | `/api/filedate?file=...` | GET | Дата версии файла | | `/api/reboot` | POST | Перезагрузка системы | ## Параметры загрузки Для `/api/upload`: - `type`: Тип файла (`kernel`, `dtb`, `uboot`, `uboot_bin`) - `file`: Загружаемый файл - `timestamp`: ISO 8601 timestamp (отправляется браузером автоматически) Для `/api/extlinux` (POST): - `content`: Содержимое файла extlinux.conf - `timestamp`: ISO 8601 timestamp (отправляется браузером автоматически) ## Расположение файлов | Тип | Файл назначения | Версия | |-----|-----------------|--------| | Ядро | `/media/Image.gz` | `/media/Image.gz.version` | | Device-Tree | `/media/sun50i-h618-orangepi-zero2w.dtb` | `/media/sun50i-h618-orangepi-zero2w.dtb.version` | | U-Boot Env | `/media/uboot.env` | `/media/uboot.env.version` | | U-Boot Binary | `/media/u-boot-sunxi-with-spl.bin` + `/dev/mtd0` + `/dev/mmcblk1` (+8KB) | `/media/u-boot-sunxi-with-spl.bin.version` | | Extlinux | `/media/extlinux/extlinux.conf` | `/media/extlinux.conf.version` | ## Конфигурация ### mongoose_config.h ```c #define MG_MAX_RECV_SIZE (256 * 1024 * 1024) // 256 MB лимит запроса #define MG_IO_SIZE 131072 // 128 KB буфер ``` ### Ограничения - Максимальный размер файла: **200 MB** (обычные файлы) - Максимальный размер U-Boot: **1 MB** (безопасно для boot area) - Порт сервера: **43243** ## Детали реализации ### U-Boot Binary загрузка 1. Сохранение файла в `/media/u-boot-sunxi-with-spl.bin` 2. Получение информации о SPI NOR через `ioctl(MEMGETINFO)` 3. Стирание SPI NOR через `ioctl(MEMERASE)` 4. Запись в `/dev/mtd0` (SPI NOR flash) 5. Запись в `/dev/mmcblk1` со смещением 8KB (сектор 16) 6. `sync()` для гарантии записи **Прогресс бар**: - 0-30%: Запись файла в `/media` - 30-65%: Запись в SPI NOR - 65-100%: Запись в SD карту ### Temperature monitoring - Чтение из `/sys/class/thermal/thermal_zone*` (0-3) - Приоритет: зоны с типом `cpu`, `soc` - Резервный источник: `/sys/class/hwmon/hwmon*/temp1_input` (0-3) - Приоритет: сенсоры с именем `cpu`, `sunxi`, `acpitz` - Обновление каждые 5 секунд ### File version tracking 1. Браузер создаёт ISO 8601 timestamp: `2026-03-14T12:34:56.789Z` 2. Timestamp кодируется для URL: `2026-03-14T12%3A34%3A56.789Z` 3. Сервер декодирует `%3A` → `:` 4. Конвертирует в человекочитаемый формат: `2026-03-14 12:34:56` 5. Сохраняет в `.version` 6. Frontend опрашивает `/api/filedate` каждые 10 секунд **Важно**: Время берётся из браузера клиента, поэтому: - ✅ Корректное время даже если на плате не настроено - ✅ Часовой пояс клиента - ✅ Синхронизация через NTP браузера ### Extlinux.conf editor - Сохранение через POST с timestamp от браузера - Автоматическое обновление списка версий после сохранения - Версия записывается в `/media/extlinux.conf.version` ## Безопасность ⚠️ **Предупреждение**: - Приложение требует права **root** для: - Монтирования устройств (`mount`, `umount`) - Записи в `/dev/mtd0` (SPI NOR flash) - Записи в `/dev/mmcblk1` (SD карта) - Перезагрузки системы (`shutdown`) - Используйте с осторожностью в production окружении - Рекомендуется ограничить доступ к веб-интерфейсу (firewall, auth) ## Зависимости Все зависимости встроены в проект: - `mongoose.c/h` - веб-сервер (из репозитория Cesanta, v7.19) - `cJSON.c/h` - JSON парсер (из репозитория DaveGamble, v1.7.18) ## Лицензия MIT License