diff --git a/config.toml b/config.toml index 1e51678..5070d92 100644 --- a/config.toml +++ b/config.toml @@ -14,7 +14,7 @@ enableRobotsTXT = true [markup.highlight] - style = 'monokailight' + style = 'friendly' [markup.goldmark.parser] wrapStandAloneImageWithinParagraph = false diff --git a/content/categories/linux/_index.md b/content/categories/linux/_index.md new file mode 100644 index 0000000..3748694 --- /dev/null +++ b/content/categories/linux/_index.md @@ -0,0 +1,3 @@ +--- +title: "Linux и вот это вот" +--- \ No newline at end of file diff --git a/content/posts/x96maxplus-armbian/firstrun.jpg b/content/posts/x96maxplus-armbian/firstrun.jpg new file mode 100644 index 0000000..355f1a9 Binary files /dev/null and b/content/posts/x96maxplus-armbian/firstrun.jpg differ diff --git a/content/posts/x96maxplus-armbian/firstrun.webm b/content/posts/x96maxplus-armbian/firstrun.webm new file mode 100644 index 0000000..c3c4fab Binary files /dev/null and b/content/posts/x96maxplus-armbian/firstrun.webm differ diff --git a/content/posts/x96maxplus-armbian/index.md b/content/posts/x96maxplus-armbian/index.md new file mode 100644 index 0000000..174937e --- /dev/null +++ b/content/posts/x96maxplus-armbian/index.md @@ -0,0 +1,300 @@ +--- +title: "Linux на X96 Max Plus" +categories: ["linux", "cpp"] +date: 2023-11-17T21:09:25+03:00 +draft: false +featured_image: miniature.jpg +--- + +Сегодня будем экономить на Raspberry Pi и поставим armbian на X96 Max Plus. + + + +> ⚠ **Прошу обратить внимание!** +> +> Моя модификация - **X96MaxPlus_2101**. Соответственно, действия описаны для этой модификации. +> Для других модификаций действия могут отличаться. +> +> Подробнее о модификациях [4pda](https://4pda.to/forum/index.php?showtopic=1013103&st=40#entry102780026). + +## Подготовка USB накопителя + +Для начала скачиваем образ файловой системы для нужного процессора отсюда: [ophub/amlogic-s9xxx-armbian](https://github.com/ophub/amlogic-s9xxx-armbian/releases). + +Ищем в списке последний релиз для процессора s905x3. В момент написания статьи это был файл [Armbian_23.11.0_amlogic_s905x3_lunar_6.1.62_server_2023.11.12.img.gz](https://github.com/ophub/amlogic-s9xxx-armbian/releases/download/Armbian_lunar_save_2023.11/Armbian_23.11.0_amlogic_s905x3_lunar_6.1.62_server_2023.11.12.img.gz). + +Ищем USB флешку. Моя была на 8 ГБ (успешно загружался и с 16). С помощью какой-либо программы записываем образ диска на неё. +Я использовал [Rufus](https://rufus.ie/ru/). +Можно использовать что угодно, что умеет записывать сырой образ диска на накопитель (Balena Etcher / dd / etc.). + +В Rufus сразу выбираем .gz архив, программа сама его распаковывает в процессе записи. + +![rufus](rufus.png) + +После записи образа на накопителе открываем раздел fat32, в нём файл `uEnv.txt`. Меняем имя файла в параметре FDT на `meson-sm1-x96-max-plus-2101.dtb`. + +```diff +LINUX=/zImage +INITRD=/uInitrd +-- FDT=/dtb/amlogic/meson-sm1-x96-max-plus-100m.dtb +++ FDT=/dtb/amlogic/meson-sm1-x96-max-plus-2101.dtb +APPEND=root=UUID=a40af2d2-999f-4b37-98b6-973b0e6faf52 rootflags=data=writeback rw rootfstype=ext4 console=ttyAML0,115200n8 console=tty0 no_console_suspend consoleblank=0 fsck.fix=yes fsck.repair=yes net.ifnames=0 max_loop=128 cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory swapaccount=1 +``` + +## Загрузка с USB накопителя + +Вставляем USB накопитель в приставку с **отключенным питанием**, зажимаем Reset (находится внутри гнезда AV), подключаем питание, держим Reset ~5 секунд. + +{{< video src="firstrun.webm" >}} + +На видео нет логотипа стоковой прошивки, потому что на устройство был уже установлен armbian. + +После запуска скрипт предложит сконфигурировать систему. + +![firsrun](firstrun.jpg) + +После предложения ввести новый пароль суперпользователя лучше немного подождать, +так как система всё ещё загружается и будут выводиться сообщения из журнала, сбивающие с толку. + +Отвечаем на вопросы и завершаем установку. + +## Установка на eMMC + +На данном этапе вся конфигурация сохраняется на **USB накопитель**. Для того, чтобы загрузить armbian нужно будет каждый раз нажимать reset при загрузке. + +Чтобы установить armbian на встроенный eMMC накопитель и загружаться с него нужно выполнить + +```bash +armbian-install -m yes +``` + +Без параметра -m у меня отказывалась загружаться операционная система. + +Сам параметр расшифровывается как "Use Mainline u-boot" (см. [тут](https://github.com/ophub/amlogic-s9xxx-armbian/tree/main/documents#81-installation-method-for-amlogic-series)). + +При установке будет предложено выбрать устройство и файловую систему (я выбрал X96 Max Plus 2101 и ext4). +После того, как скрипт завершит работу, вводим poweroff, извлекаем USB накопитель и переподключаем питание. +Система теперь будет загружаться со встроенной памяти. + +Если приставка к Wi-Fi не подключена, то советую это сделать (с помощью armbian-config или nmcli). +Через Ethernet подключить вроде как не получится, проблемы с драйвером. + +Если вы уже подключили приставку к Wi-Fi, то можно управлять ей с помощью ssh (в дистрибутиве уже настроен ssh сервер). + +## Решение проблем с нестабильным Wi-Fi + +В процессе работы я начал наблюдать подобные сообщения ядра + +```bash +[ 83.751980] ------------[ cut here ]------------ +[ 83.754595] firmware failed to ack driver for entering Deep Power mode +[ 83.760091] WARNING: CPU: 1 PID: 9 at drivers/net/wireless/realtek/rtw88/ps.c:106 rtw_power_mode_change+0x154/0x1a0 [rtw88_core] +[ 83.771493] Modules linked in: cpufreq_userspace cpufreq_conservative cpufreq_powersave sunrpc hci_uart btqca btrtl btbcm btintel rtw88_8822cs rtw88_8822c rtw88_sdio rtw88_core bluetooth panfrost mac80211 gpu_sched snd_soc_meson_axg_sound_card drm_shmem_helper snd_soc_meson_card_utils snd_soc_meson_g12a_tohdmitx cfg80211 snd_soc_meson_axg_tdmout snd_soc_meson_codec_glue rfkill snd_soc_meson_axg_frddr libarc4 snd_soc_meson_axg_fifo zram ir_nec_decoder meson_gxbb_wdt meson_imeson_vdec(C) videobuf2_dma_contig v4l2_mem2mem snd_soc_meson_axg_tdm_interface snd_soc_meson_axg_tdm_formatter tcp_bbr sch_fq ip_tables x_tables hid_logitech_hidpp hid_logitech_dj +[ 83.832293] CPU: 1 PID: 9 Comm: kworker/u8:0 Tainted: G C 6.1.62-ophub #1 +[ 83.840398] Hardware name: AMedia X96 Max+ (DT) +[ 83.844885] Workqueue: phy0 rtw_watch_dog_work [rtw88_core] +[ 83.850404] pstate: 60400009 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 83.857302] pc : rtw_power_mode_change+0x154/0x1a0 [rtw88_core] +[ 83.863166] lr : rtw_power_mode_change+0x154/0x1a0 [rtw88_core] +[ 83.869031] sp : ffffffc00a18bcc0 +[ 83.872309] x29: ffffffc00a18bcc0 x28: ffffff800005bd00 x27: ffffff800000ec00 +[ 83.879382] x26: ffffff80030908e0 x25: ffffff8003092080 x24: 0000000000000001 +[ 83.886454] x23: 0000000000068dbc x22: 00000013843748d4 x21: 0000000000000001 +[ 83.893527] x20: 0000000000000000 x19: ffffff8003092080 x18: ffffffffffffffff +[ 83.900599] x17: 0000000000000004 x16: 0000000000000000 x15: 0000000000000006 +[ 83.907671] x14: 0000000000000000 x13: ffffffc009d9ce50 x12: 0000000000000648 +[ 83.914744] x11: 0000000000000218 x10: ffffffc009e4ce50 x9 : ffffffc009d9ce50 +[ 83.921816] x8 : 00000000ffffdfff x7 : ffffffc009e4ce50 x6 : 0000000000000001 +[ 83.928889] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000 +[ 83.935961] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffff80000a7000 +[ 83.943035] Call trace: +[ 83.945810] rtw_power_mode_change+0x154/0x1a0 [rtw88_core] +[ 83.950970] rtw_sdio_deep_ps+0x90/0xd0 [rtw88_sdio] +[ 83.955886] rtw_enter_lps+0xf4/0x110 [rtw88_core] +[ 83.960629] rtw_watch_dog_work+0x25c/0x270 [rtw88_core] +[ 83.965890] process_one_work+0x1dc/0x370 +[ 83.969858] worker_thread+0x168/0x4e0 +[ 83.973567] kthread+0xd4/0xdc +[ 83.976585] ret_from_fork+0x10/0x20 +[ 83.980123] ---[ end trace 0000000000000000 ]--- +``` + +Связано это с проблемами входа wi-fi модуля в режим экономии энергии. Поэтому эту самую экономию мы отключим. + +Открываем файл `/etc/NetworkManager/conf.d/default-wifi-powersave-on.conf` и значение параметра `wifi.powersave` изменяем с 3 на 2. + +``` +sudo nano /etc/NetworkManager/conf.d/default-wifi-powersave-on.conf +``` + +```diff +[connection] +# Values are 0 (use default), 1 (ignore/don't touch), 2 (disable) or 3 (enable). +-- wifi.powersave = 3 +++ wifi.powersave = 2 +``` + +После этого перезагружаемся (команда reboot). Проверить, отключилось ли энергосбережение можно командой + +```bash +sudo iwconfig wlan0 | grep "Power Management" +``` + +Результат должен быть `Power Management:off`. + +## Вывод произвольного текста на семисегментный дисплей + +В репозитории [ophub/amlogic-s9xxx-armbian](https://github.com/ophub/amlogic-s9xxx-armbian) описывается как включать или отключать индикаторы на дисплее. + +TL;DR: + +```bash +sudo armbian-openvfd +``` + +Однако нет информации как выводить произвольный текст вместо часов. + +После изучения исходников [сервиса openvfd](https://github.com/arthur-liberman/linux_openvfd/blob/3118dda3aeb5b2f02b0ac0b5d30cbef58947a805/OpenVFDService.c#L342-L357) +стало понятно, что сервис использует канал по пути `/tmp/openvfd_service`. +При записи в этот файл, сервис перестаёт отключает вывод по умолчанию (часы) и выводит заданную информацию. +Сама информация передаётся в виде структуры `vfd_display_data` (`openvfd_drv.h`). В этой структуре достаточно установить `mode = DISPLAY_MODE_TITLE` и заполнить `string_main`. + +Имея всю эту информацию я сделал небольшую программку, которая устанавливает произвольный текст на дисплее. + +Что нужно сделать? + +Клонировать репозиторий [arthur-liberman/linux_openvfd](https://github.com/arthur-liberman/linux_openvfd): + + +```bash +git clone https://github.com/arthur-liberman/linux_openvfd +``` + +Перейти в директорию репозитория: + +```bash +cd linux_openvfd +``` + +Создаём исходный файл программы. Я назвал его `set-display-text.c`. + +```bash +nano set-display-text.c +``` + +Код: + +```c +#include +#include +#include +#include +#include +#include "driver/openvfd_drv.h" + +#define SERVICE_PIPE "/tmp/openvfd_service" + +int main(int argc, char const *argv[]) +{ + if (argc < 2) + { + fprintf(stderr, "Text not provided\n"); + exit(1); + } + + // Открыть файл сервиса + int service_fd = open(SERVICE_PIPE, O_RDWR); + + if (service_fd < 0) + { + perror("Open " SERVICE_PIPE " failed\n"); + exit(1); + } + + // Структура данных драйвера дисплея + static struct vfd_display_data data; + + // Инициализировать структуру пустыми значениями + memset(&data, 0, sizeof(data)); + + // Режим вывода на экран - произвольный текст + data.mode = DISPLAY_MODE_TITLE; + + // Скопировать максимум 4 символа + strncpy(data.string_main, argv[1], 4); + data.string_main[5] = '\0'; + + // Записать в файл сервиса + int written = write(service_fd, &data, sizeof(data)); + + if (written != sizeof(data)) + { + perror("Write failed\n"); + } + + close(service_fd); + + return 0; +} +``` + +Компилируем: + +```bash +gcc -O2 -Werror set-display-text.c -o set-display-text +``` + +На всякий случай оставлю тут собранный бинарник: [set-display-text](set-display-text) + +Проверяем. + +Сначала запускаем драйвер и сервис (если на экране уже что-то выводится, то сервис уже запущен!): + +```bash +sudo armbian-openvfd + +``` + +Или + +```bash +sudo armbian-openvfd 12 +``` + +Где 12 - номер модели (x96maxplus s905x3). + +Далее проверяем нашу утилиту: + +```bash +sudo ./set-display-text lol +``` + +![lol.jpg](lol.jpg) + +Если всё работает, то можно скопировать исполняемый файл в локальное окружение для того, чтобы можно было его выполнять из любого места: + +```bash +sudo cp set-display-text /usr/local/bin +``` + +### Автозапуск драйвера и сервиса индикации + +Открываем файл автозапуска и меняем строки: + +``` +sudo nano /etc/custom_service/start_service.sh +``` + +```diff +# Led display control +-- openvfd_enable="no" +++ openvfd_enable="yes" +-- openvfd_boxid="15" +++ openvfd_boxid="12" +[[ "${openvfd_enable}" == "yes" && -n "${openvfd_boxid}" && -x "/usr/sbin/armbian-openvfd" ]] && { + armbian-openvfd ${openvfd_boxid} && + echo "[$(date +"%Y.%m.%d.%H:%M:%S")] The openvfd service started successfully." >>${custom_log} +} +``` + +openvfd_boxid можно узнать выполнив `sudo armbian-openvfd`. diff --git a/content/posts/x96maxplus-armbian/lol.jpg b/content/posts/x96maxplus-armbian/lol.jpg new file mode 100644 index 0000000..c44bd12 Binary files /dev/null and b/content/posts/x96maxplus-armbian/lol.jpg differ diff --git a/content/posts/x96maxplus-armbian/miniature.jpg b/content/posts/x96maxplus-armbian/miniature.jpg new file mode 100644 index 0000000..b82d7fd Binary files /dev/null and b/content/posts/x96maxplus-armbian/miniature.jpg differ diff --git a/content/posts/x96maxplus-armbian/rufus.png b/content/posts/x96maxplus-armbian/rufus.png new file mode 100644 index 0000000..0e1413a Binary files /dev/null and b/content/posts/x96maxplus-armbian/rufus.png differ diff --git a/content/posts/x96maxplus-armbian/set-display-text b/content/posts/x96maxplus-armbian/set-display-text new file mode 100644 index 0000000..f8c4bf9 Binary files /dev/null and b/content/posts/x96maxplus-armbian/set-display-text differ diff --git a/themes/mmotium/layouts/shortcodes/video.html b/themes/mmotium/layouts/shortcodes/video.html new file mode 100644 index 0000000..09b527c --- /dev/null +++ b/themes/mmotium/layouts/shortcodes/video.html @@ -0,0 +1,10 @@ +{{- $video := .Page.Resources.GetMatch (.Get "src") -}} +{{ if $video -}} + +{{- else -}} + video-error +{{- end -}} + + diff --git a/themes/mmotium/static/images/video-error.png b/themes/mmotium/static/images/video-error.png new file mode 100644 index 0000000..c5b39ee Binary files /dev/null and b/themes/mmotium/static/images/video-error.png differ