Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Make (push) Successful in 6s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-CMake (push) Successful in 11s
Prepare Build and Testing executable binary / Prepare-Build-Testing-With-Meson (push) Successful in 9s
221 lines
10 KiB
Markdown
221 lines
10 KiB
Markdown
# 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. Сохраняет в `<filename>.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
|