Тот самый первый Blood, в виде современного форка, собранный из исходников и запущенный под FreeBSD.
С исходниками отдельная интересная история: они получены с помощью реверс-инжиниринга, занявшего несколько лет, частично взяты из движка Build, доработанная версия которого использовалась для создания этой игры. Форк называется NBlood, исходники тут: https://github.com/NBlood/NBlood , но собирать было откровенно непросто ввиду определенной упоротости авторов.
Пока вы рождались, ходили в школу, заканчивали учебу и выходили на свою первую работу, на свете существовал совершенно особенный набор компиляторов, о котором крайне мало известно на просторах РФ.
Именно о нем пойдет сегодняшний рассказ.
Amsterdam Compiler Kit
Врядли среди читателей обнаружится аксакал живой пользователь этого удивительного проекта:
The Amsterdam Compiler Kit is a venerable piece of software that dates back to the early 1980s. It was originally written by Andrew Tanenbaum and Ceriel Jacobs as a commercial product; for many years it was also used as Minix’ native toolchain. After eventually failing as a commercial project, it was made open source under a BSD license in 2003 when it looked like it was going to be abandoned and the code lost.
Сочетание «начало 80х» и «коммерческий продукт» оставляет мало шансов на появление пользователей ACK в родных краях, поскольку в 80е еще вовсю жил СССР и вопрос покупки иностранного программного обеспечения был мягко говоря неактуальным.
Теперь подробнее, что там внутри и почему оно до сих пор шевелится представляет интерес:
The ACK contains compilers for ANSI C, K&R C, Pascal, Modula-2, Occam 1, and a primitive Basic. It contains code generators for a large number of architectures, mostly 8 and 16 bit machines; there are also a set of generic optimisation, linker and librarian tools.
В принципе стандартный набор языков для тех лет, но есть нюанс:
It contains assembler and linker support for: 6500, 6800, 6805, 6809, ARM, i80, Z80, Z8000, i86, i386, 68000, 68020, NS32016, S2650, SPARC, VAX, PDP11 and VideoCore IV.
Это уже несет определенный «вау-эффект», причем как для тех, так и для этих лет, поскольку даже для популярных clang и gcc столь широкая поддержка различных архитектур решается весьма нетривиально - путем форков и неофициальных патчей.
В мейнстриме и готовых пакетах столь дикого набора архитектур разумеется нет, при этом поддержку устаревших архитектур еще и регулярно ломают, а некоторые вообще удаляют.
Современная версия ACK, разрабатываемая с 2003 года как открытый проект, поддерживает следующие платформы:
И ACK дает вам возможность скомпилировать приложение в современном окружении в 2025м году, которое будет работать на этом.
Чтобы у вас не сложилось впечатление, будто ACK это только лишь про плешивых дедов пожилых программистов и их древние игрушки, покажу как выглядит заявленный выше VideoCore IV:
Как видите это уже вполне себе современная плата, используемая в различных устройствах.
Minix
Отдельно стоит упомянуть историю с Minix — той самой операционной системой, созданной тем самым Таненбаумом для обучения нерадивых студентов сложной теме разработки операционных систем.
В почтовой рассылке, посвященной этой ОС когда-то давно некий Линус Торвальдс впервые представил свой известный проект, вызвавший эпический архитектурный срач дискурс, ныне являющийся историческим событием.
Дело в том, что ACK когда-то был основным системным компилятором в Minix, при этом являясь коммерческим продуктом — поставлялся в виде готовых бинарников:
The ACK has been used as the standard Minix compiler for years. While the ACK was still commercial, this was done by distributing binaries; when it get opened, a version was forked off and is now used as part of the Minix base build.
Форк с поддержкой Minix мне был не особо интересен, поэтому искать не стал, тем более что в современной Minix 3 используется вполне стандартный clang.
Однако на поддержке столь широкого набора архитектур возможности ACK не заканчиваются и чтобы добить окончательно нежную психику современных разработчиков, процитирую следующий абзац:
Each language comes with its own runtime, so if you’re a C programmer you also get a libc. Compared to gcc, it is far smaller, faster and easier to port.
Стоило догадаться об этом, прочитав список поддерживаемых архитектур и прикинув как оно вообще может работать, но тем не менее.
Так что ACK это уникальный, редкий и необычный проект, позволяющий творить запредельную дичь вроде кросс-компиляции из FreeBSD в MS-DOS подручными средствами, которую вы могли видеть в шапке статьи.
Ниже я опишу процесс сборки и использования этого необычного проекта.
Сборка
Собирать буду по традиции на FreeBSD 14, поэтому часть требуемых шагов несколько отличается от стандартных.
Проект старый, разработка в git ведется давно, поэтому внутри репозитория присутствует множество разных веток, не актуальных для обывателя.
Чтобы не выкачивать всю эту дичь, я использовал ключ --depth -1, с которым будет выгружена только ветка по-умолчанию:
Таким образом собирать мы будем текущую на момент написания статьи версию:
ACK 6.0 is a ground-up reworking of the whole compiler suite, with a lot of the more archaic features removed.
Сборка проекта.. весьма своеобразна, поскольку основана на скриптах Python и немного Lua. Как гласит описание:
The version 5.0 build mechanism has been completely rewritten (twice).
И видимо это еще не конец.
Для сборки нужен достаточно банальный набор инструментов:
любой ANSI C компилятор (автор использовал GCC)
flex и yacc
GNU make (gmake)
Lua с библиотекой lua-posix
Python 3.4 и выше
~2Гб свободного места
В трекере проекта и пул-реквестах есть сообщения от камрадов, использующих ACK на OpenBSD, так что врядли будут проблемы в куда более популярных Linux, Windows и MacOS.
Запускается сборка стандартным образом — вызовом GNU Make в корне проекта:
gmake
Поскольку автор собирал на FreeBSD, которая имеет определенную специфику в именовании инструментов, появится такая ошибка:
Происходит это из-за того, что lua во FreeBSD имеет постфикс версии:
Так что надо отредактировать Makefile в корне проекта и поменять значение переменной LUA=, добавив версию:
Следующая ошибка также специфична для FreeBSD, поскольку gcc у нас тоже с постфиксом версии:
Несмотря на документацию, которая утверждает что актуальный компилятор должен подхватываться через стандартную переменную окружения CC=, нашлось место в скриптах сборки, где были прямо забиты названия используемых бинарников:
Нужный файл называется ack/build/ab.mk и почему-то несмотря на название и расположение — не является генерируемым.
По аналогии с lua, добавляем постфикс версии и сохраняем:
После этого заново запускаем сборку и ждем, никаких других ошибок при сборке замечено не было.
Итоговый размер после завершения сборки, со всеми временными файлами получился размером в 1.7Гб, что несколько больше заявленного в требованиях:
По-умолчанию ACK устанавливается в каталог /opt/pkg/ack, поэтому запускаем из корня проекта:
mkdir -p /opt/pkg/ack gmake install
Перед установкой будут запущены тесты, но далеко не все:
Итоговый каталог bin выглядит следующим образом:
Хотя основные бинарники находятся в ack/lib/ack:
Теперь переходим к самому интересному — к запуску и работе с ACK, это будет действительно весело.
В репозитории проекта находится каталог examples, где лежат примеры более-менее сложной логики на Си, Паскале и Бейсике, которые точно собираются и работают с помощью ACK.
Один из таких примеров под названием mandelbrot.c , выводящий в консоль с помощью символа * фрактал Мандельброта вы можете лицезреть в работе на заглавной картинке к статье.
Но поскольку мне был интереснее сам процесс компиляции и запуска приложений на разных экзотических архитектурах из древних времен нежели специфика каждой конкретной платформы, не стал заморачиваться сложной логикой, взяв в качестве эталона классический «Hello world!» на Си:
#include <stdio.h>
int main(void) { printf("Hello, alex0x08 \n"); return 0; }
И собственно ниже покажу сборку и запуск этой нестареющей классики под крайне экзотические (по современным меркам) архитектуры.
Компиляция FreeBSD->MS-DOS
Компиляцию в COM-файл с последующим запуском можно увидеть на заглавной картинке, поэтому ниже покажу компиляцию в EXE под DOS:
Поэтому для работы нужен запущенный DPMI-резидент — т. н. «расширитель памяти», который можно взять например тут.
Так это выглядит в записи:
Как видите запуск осуществлялся в известном эмуляторе DOS под названием Dosbox, установленном из пакетов FreeBSD.
Компиляция для CP/M
Продолжая исторический угар, показываю сборку и запуск под CP/M, напоминаю что это операционная система из 1970х (старше автора) а компьютеры, на которых она работала выглядели так:
Kaypro II
Тут надо сделать небольшое отступление и рассказать про эмулятор CP/M, поскольку его в пакетах FreeBSD не нашлось — пришлось собирать руками.
При сборке будет описанная выше проблема с номером версии в названии исполняемых файлов компилятора GCC — стандартная для FreeBSD, поэтому необходимо в файле RunCPM/Makefile.posix в переменную СС= добавить номер версии:
Сама сборка запускается командой:
gmake posix build
Но это еще не все приключения, после сборки необходимо подготовить рабочее пространство — специальный каталог из которого будет запускаться эмулятор:
Круто, но недостаточно, поскольку среди поддерживаемых ACK систем есть:
pdpv7 produces PDP/11 V7 Unix binaries
Думаю вы догадываетесь, что пройти мимо такого было невозможно, поэтому автор убил еще неделю показываю нечто действительно удивительное.
Компиляция для Unix v7 и PDP-11 в 2025м году (!)
Чтение этого абзаца прибавляет 100 баллов к инженерным навыкам.
Напоминаю как выглядел PDP-11:
Вот так выполняется компиляция из ACK для этого древнего монстра:
/opt/pkg/ack/bin/ack -mpdpv7 -O hello.c -o hello
Как ни странно и неожиданно, но стандартная утилита file, присутствующая во всех UNIX-системах с незапамятных времен честно показывает тип:
Apout — Simulate PDP-11 Unix a.out binaries
Для проверки я сначала запустил полученный бинарник на этом:
This program is a user-level simulator for UNIX a.out binaries. Binaries for V1, V2, V5, V6, V7, 2.9BSD and 2.11BSD can be run with this simulator. The user-mode PDP-11 instructions are simulated, and TRAP instructions are emulated by calling equivalent native-mode system calls.
Собирается оно под FreeBSD одной командой, поскольку внешних зависимостей нет:
export CC=gcc13 gmake
После сборки в корне проекта появится бинарник apout, так выглядит в работе запуск нашего «Hello world»:
Но разумеется сильно круче было бы попробовать запустить в реальном симуляторе PDP с Unix v7 на борту, что я и сделал.
SIMH
Эмуляцию PDP как впрочем и множества других исторических систем обеспечивает известный проект Open SIMH. Нужный нам Unix v7 заявлен на главной странице проекта в качестве ключевого примера:
For example Version 7 Unix, released in 1979, runs unchanged today on SimH.
В этот раз эмулятор присутствовал в готовом виде среди пакетов FreeBSD, так что хотя-бы его не пришлось собирать из исходников.
Дальше необходимо создать конфигурационный файл эмулятора:
set cpu u18 set cpu idle attach rl0 unix_v7_rl.dsk attach rl1 hello.tar boot rl0
Сохраните файл как simh-pdp11.ini, в том же самом каталоге v7 , куда был распакован образ диска.
Теперь надо создать tar-файл с собранным бинарником "Hello world" приложения:
cd ~ tar cvf hello.tar hello cp hello.tar ~/v7/
Итоговый набор файлов должен выглядеть как-то так:
Запускаем эмулятор:
pdp11 simh-pdp11.ini
После появления приглашения в виде символа @ вводим:
boot
Появится древний предок современного Grub, загрузчик:
Вводим:
rl(0,0)rl2unix
Появится приглашение в виде символа # , что означает запуск Unix v7 в однопользовательском режиме:
Нажмите Ctrl - D для начала работы в многопользовательском режиме:
Появится хорошо знакомое любому юниксоиду приглашение авторизации. Введите root в качестве логина и пароля:
При первом запуске будет необходимо выполнить ряд дополнительных шагов. Создаем каталог для временных файлов:
mkdir /tmp
Создаем ссылки на устройства:
cd /dev make rl
Таким образом со стороны запущенной в эмуляторе Unix v7 будет доступно устройство, эмулирующее ленту и можно будет добраться наконец до собранного на хосте бинарника:
cd /tmp tar xvf /dev/rrl1
В результате в файловой системе появится тот самый файл hello, собранный на FreeBSD с помощью ACK:
Наконец сам запуск:
Ну кто еще вам спрашивается покажет такую красоту?
Эпилог
ACK имеет отличную портируемость и расширяемость, поэтому существует столь интересный форк этого проекта:
This fork of the Amsterdam Compiler Kit supports the Cray X-MP supercomputer and the COS operating system platform.
Его тоже удалось собрать и запустить, но ввиду невероятной сложности самобытности COS, история будет уже в отдельной статье. Следите за анонсами, как говорится.
Статья была опубликована на Хабре, оригинал как обычно в нашем блоге, все желающие получить обои с автографом (и не умеющие пользоваться нейросетями) должны будут повторить все описанные в статье шаги и прислать скриншот с работающим «Hello <username>» под Unix v7 на PDP, где username — ваш ник.
На самом деле это "форк форка" старого доброго XMMS, созданного когда-то давно по мотивам легендарного плеера Winamp, получается клон в четвертом поколении! Переписан на Rust и запущен под FreeBSD, чтобы снова радовать меня треками начала 2000х😎
Продолжаю тему отбитого ретрогейминга для "особенных" пользователей, показываю только что собранную из исходников первую Diablo, запущенную на моей домашней FreeBSD:
На свете есть не так много вещей, способных выбесить программиста. И лишь одна делает это с гарантией: оборзевшая машина, возомнившая себя умнее человека.
А значит снова пришло время карать и патчить!
Видите эти повторяющиеся записи справа? Так будет выглядеть буфер сообщений ядра (dmesg), если вам не повезло нарваться на этот баг.
Direct Rendering Manager (DRM)
Развитие современных видеокарт пошло по весьма.. сюрреалистичному пути:
производители страстно желают, чтобы выпускаемые устройства имели максимальную совместимость с модными открытыми ОС, но одновременно были закрытыми и неповторимыми, защищенными разнообразными патентами.
То что звучит как чистая шизофрения для человека с техническим образованием, будучи спущенным сверху в виде директивы, еще и подкрепленной серьезным бюджетом, породило на свет такую «хтонь» как binary blob.
Это когда основная часть управляющей устройством логики реализуется в виде специальной прошивки с защитой и обфрускацией — того самого «блоба».
Затем вокруг создается открытая часть ПО, которая линкуется с открытым ядром и/или окружением. А все это вместе и без смущения объявляется как частично беременна открытое решение.
The Direct Rendering Manager (DRM) is a subsystem of the Linux kernel responsible for interfacing with GPUs of modern video cards
Если кратко и цензурно, то это такая специальная дыра в ядре Linux, для максимально быстрой коммуникации между видеокартой и клиентским ПО, создаваемая в первую очередь ради видеоиг.. скажем так «медийных приложений, требующих аппаратного ускорения графики».
В угаре оптимизации «ядростроители» дошли до использования 3D-ускорения (GPU) даже для отрисовки терминала текстовой консоли (тот самый KMS):
И теперь мы все имеем клевый терминал в разрешении 1920×1280 со сглаживанием шрифтов, на котором что-то разобрать возможно лишь с лупой прищурившись.
Угар портирования
Под натиском волн малолетних специалистов, желающих «гонять игоры» на серверной ОС, не выдержали даже разработчики FreeBSD:
подсистема DRM и KMS, вместе с проприетарными блобами была перенесена из Linux и теперь вовсю используется в FreeBSD.
По-умолчанию, да.
Кстати с тех лет и до сих пор разработка DRM синхронизируется с апстримом (а это внезапно отдельный проект) и ядром Linux, заезжая в сборки FreeBSD вместе со всеми свежими багами в виде срезов исходников. Основная разработка при этом едет дальше.
Нетрудно догадаться, что отправлять багрепорты в проект drm-kmod, курируемый FreeBSD или апстрим ядра Linux при таком подходе равнозначно отправке в «Спортлото».
Заодно во FreeBSD были фактически похоронены альтернативные варианты:
старый текстовый TTY и Xorg-драйвер для видеокарт Intel пока еще существуют и собираются в виде пакетов, но вот их настройку и главное — все сопутствующие сбои в клиентском ПО вы теперь вынуждены отлавливать и исправлять самостоятельно.
«Интерес сообщества» к таким технологиям оказался утрачен.
В качестве вишенки на этом интересном торте из говна, добавлю что всенародно любимый браузер Google Chrome плохо работает без модуля KMS, поэтому заводить весь этот цирк с DRM и KMS приходится даже на откровенно винтажных машинах — ради работающего браузера.
И других вариантов уже фактически нет.
Как-то так выглядит процесс попадания обновлений DRM в FreeBSD. FreeBSD — крайний справа, увы.
Оборзевшая техника
Вся эта технологическая «многоножка» из разработчиков Intel с блобами, апстрима ядра Linux с любовью к тотальным переделкам на Rust, на практике приводит к тому, что в бедную FreeBSD постоянно попадают ломающие обновления, отследить и исправить которые «в моменте» не получается.
«Думали что работает» — говорят в таких случаях разработчики FreeBSD и советуют обновиться до -CURRENT версии.
Что для обычных людей и рабочего окружения на машине равносильно старому японскому ритуалу сеппуку, поскольку упадет и сломается вообще все.
В какой-то момент обновление пакета drm-kmod, содержащего тот самый порт подсистемы DRM из ядра Linux принесло мне такое:
drmn0: [drm] ERROR Fault errors on pipe A: 0x00000080
Ну принесло и принесло, ошибок много разных, исправляются далеко не все, дело это небыстрое и так далее.
Но только эта забивала собой весь буфер сообщений ядра!
Сообщений генерировалось настолько много, что dmesg — команда для отображения этого самого буфера, показывала только одну эту бесконечно повторяющуюся ошибку, как на скриншоте в шапке статьи.
Но самое веселое, что баг оказался с рогами и копытами совсем не специфичным и само сообщение означает буквально.. ничего.
Просто «что-то сломалось», в переводе с языка Intel.
Ну что, вы все еще любите проприетарные драйвера от уважаемых производителей?
Беглый поиск в репозитории, в котором ведется разработка подсистемы DRM (напоминаю, она ведется отдельно от ядра Linux) показал, что сообщений с этой ошибкой навалом:
88 репортов, только в этом довольно новом репозитории.
Положение дел
В итоге есть некий баг, с гнездом в районе прошивки видекарты Intel, который (судя по репортам) зверствует проявляет себя самым феерическим образом:
от спама сообщениями до мигания экрана и полного зависания системы.
Исправить своими силами этот баг нельзя, все «workaround» в сети по накалу дичи в рекомендациях напоминают известное шоу «Битва Экстрасенсов»:
нарисуйте ночью в поле пентаграмму из соли, разложите по углам загрузочные диски FreeBSD с 5й по 10ю и громко читайте Changelog задом наперед.
Первая заключается в том, что в свежих прошивках баг вроде бы исправили на стороне Intel, но чтобы эту прошивку поставить — нужна сборка модуля DRM для FreeBSD 15, которая еще не была выпущена на момент написания статьи:
Еще стоит рассказать, что прямо сейчас идет серьезная работа по перепиливанию DRM как в его основном проекте так и на стороне команды FreeBSD (в -CURRENT), поэтому даже пытаться бекпортировать текущую версию drm-kmod в 14.х ветку не стоит.
Также (к сожалению) не стоит рассматривать переезд на 15ю версию как гарантированное решение, поскольку есть уже открытые багрепорты и оттуда:
Хотя тут явно использовалась 6.1 версия.
Вторая хорошая новость заключается в том, что на двух моих ноутбуках, где проявляется данный баг все работает без критических сбоев — без мигания и зависаний системы. А само сообщение до недавних пор глушилось настройкой:
compat.linuxkpi.i915_disable_power_well="0"
Так что конкретно в моем случае, проблема заключается лишь в бесконечном затирании буфера сообщений ядра этой дурацкой и бессмысленной ошибкой:
drmn0: [drm] ERROR Fault errors on pipe A: 0x00000080
Которую мы и будем сейчас цинично глушить.
Аморальный патч
Разумеется так делать нельзя:
глушить сообщения об ошибках в ваших реальных проектах не стоит.
Хотя если в вашем проекте возникает ситуация, когда сообщение об ошибке генерируется по сотне раз за секунду — ну наверное вопрос уже к вам как к разработчику, допустившему такую дичь.
К счастью FreeBSD проект не мой, прямого доступа к разработчикам нет, а сам процесс разработки подсистемы DRM сильно напоминает известный фильм «Human Centipede».
Где (а главное — зачем) искать концы в такой ситуации не очень понятно, для примера багрепорты по ошибкам DRM в трекере ядра Linux сразу просят перенаправлять в отдельный проект, не разбираясь:
Так что было решено применить военную хитрость просто заглушить сообщение об ошибке в исходниках, пересобрав DRM из портов.
Так выглядит конечный результат после патча:
Как видите буфер ядра не забит этими дурацкими сообщениями.
Поскольку новая 15я по счету версия FreeBSD еще официально не вышла на момент написания статьи, я все еще использую 14.3, где максимально доступная версия DRM для этой ветки — 6.1.
Ее мы и будем жестоко патчить.
В портах она находится в этом каталоге:
/usr/ports/graphics/drm-61-kmod
Поиск в исходном коде по тексту сообщения об ошибке показал, что генерируется она всего в одном месте, в файле i915_irq.c:
if (fault_errors) drm_err(&dev_priv->drm, "Fault errors on pipe %c: 0x%08x\n", pipe_name(pipe), fault_errors); ..
Все что нужно сделать — закомментировать этот блок, начиная с условия.
И все, больше вы это проклятое сообщение не увидите, ура.
Для уменьшения работы мозгом у дорогих читателей, подготовил на этот раз готовый патч, который достаточно положить в специальный каталог и он автоматически применится при сборке drm-kmod.
Надо создать файл patch-i915_irq.c в каталоге /usr/ports/graphics/drm-61-kmod/files, затем вставить туда вот такое содержимое:
*** drivers/gpu/drm/i915/i915_irq.c.orig Tue Nov 18 17:17:39 2025 --- drivers/gpu/drm/i915/i915_irq.c Tue Nov 18 17:17:52 2025 *************** *** 2571,2585 ****
if (iir & gen8_de_pipe_underrun_mask(dev_priv)) intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
fault_errors = iir & gen8_de_pipe_fault_mask(dev_priv); ! if (fault_errors) drm_err(&dev_priv->drm, "Fault errors on pipe %c: 0x%08x\n", pipe_name(pipe), ! fault_errors); }
if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) && master_ctl & GEN8_DE_PCH_IRQ) { /*
Дальше просто перезапускаем сборку:
make clean make
Проверяем что изменения в файле i915_irq.cприменились и запускаем установку собранного пакета:
make reinstall
После чего перезагружаем систему.
Если все прошло удачно — дурацкое сообщение вас больше беспокоить не будет, если нет — компьютер взорвется система скорее всего зависнет при запуске, либо вас будет ожидать черный экран.
Но главное это разумеется хорошее настроение и поставленная на место машина, вернувшаяся к своей основной задаче служить людям.
P.S.
Ошибка действительно дурацкая, еще и наведенная — если дойдет до серьезных сбоев вроде мигания экрана (screen flickering), вы увидите дополнительные сообщения в логах, по которым можно продолжать искать реальную проблему.
Так что вопрос удаления этого сообщения чисто косметический и частично — лишней нагрузки, поскольку генерация сотен таких сообщений в секунду разумеется нагружала систему.
Рассказываю про еще одну коварную подлость, встроенную в современные технологии беспроводной связи — WiFi. Про это знают все приличные сетевые инженеры, но почему-то не рассказывают простым пользователям.
Проблема
Временами во время разъездов, когда нахожусь в дороге, включаю мобильную точку WiFi на своем телефоне — чтобы подключиться к ней с ноутбука и попасть в интернет.
Работает надежнее и быстрее, чем использование публичных сетей, даже в поезде или гостинице.
Однако после одного из недавних обновлений, WiFi-точка на телефоне стала работать нестабильно и подключиться получалось не с первой попытки.
Временами мобильная точка пропадала из выдачи — ее не было видно в списке доступных сетей, даже когда телефон лежал рядом. Причем проблемы с подключением были далеко не со всем клиентским оборудованием и не со всеми ОС, так что дело было явно не в ней самой.
Я довольно долго не мог понять в чем дело и забивал на исправление, пока однажды это не стало проблемой:
в нужный момент не смог подключиться и отправить важное письмо.
Тут стоит указать, что хотя все действия происходили на FreeBSD, сама проблема актуальна для любых ОС, включая внезапно встроенные.
Были скопированы настройки сети с «соседнего устройства», где все работало, после чего попытался подключиться полностью вручную — указав название точки, пароль, SSID и номер канала.
Мобильная точка выбирает номер канала случайным образом при каждом включении и на момент отладки выпал номер 13.
Внезапно, при попытке указать канал с этим «чертовым» номером появилась ошибка:
unknown/undefined channel number 13 flags 0x0
Которая немедленно была забита в поисковик и выдала кучу сообщений с похожими проблемами:
FreeBSD's net80211 stack has basic regulatory domain support, enforcing restrictions on frequency, operating modes, transmission power and general behavior.
Та самая сказочная хтонь, про которую вы точно слышали, если имеете отношение к беспроводным сетям и админству, но слабо представляли как оно может влиять на просторах нашей необъятной.
While the USA restricts 2.4 GHz Wi-Fi to eleven channels, channels 12 through 14 are available elsewhere in the world. You might even be able to activate them by changing your router settings, although you should not do so. Channel 14 is the most tempting to people, as it would have even less interference---but it's illegal to operate your router on this channel in the USA.
Круто?
Как думаете, что произойдет если при установке системы (любой) будет выбрана страна по-умолчанию — США?
Помимо очевидной английской локали, форматов дат и времени, будет применен еще и этот самый «regulatory domain» для Wifi — для США.
И вы получите описанную проблему с подключением и каналами. Ну разве 21 век это не чудо?
Решение
Как уже писал в самом начале, про сам «regulatory domain» знает любой более-менее опытный сисадмин, но вот как его неправильный выбор влияет на работу WiFi-карты — не знает почему-то никто (проверено).
Поэтому вполне допускаю, что описанное окажется сюрпризом и для вас.
К счастью для исправления ситуации, на этот раз не надо патчить драйвера или пересобирать ядро, достаточно указать в /etc/rc.conf правильный regulatory domain:
create_args_wlan0="country RU"
Затем перезагрузить всю систему, либо поддержку сети:
/etc/rc.d/netif restart
Для того чтобы убедиться в правильности выбора и что описанная проблема вас не коснется, существует команда:
ifconfig wlan0 list regdomain
После перенастройки regulatory domain, проблема с мобильной WiFi-точкой исчезла как по волшебству — удивительно какого размера свиней временами подкладывают разработчики стандартов и оборудования простым пользователям.
Еще один удивительный момент:
ни одна нейросеть не смогла найти связь между проблемами с подключением к WiFi и выбором regulatory domain, ни для одной ОС.
Хотя по идее это старая и широко известная история.
Стоит еще добавить, что на самом деле проблема касается двух каналов: 12 и 13. А еще есть 14, использование которого разрешено только в Японии, поэтому для его использования придется переключиться на их regulatory domain.
Хотите довести до дурки любимого преподавателя компьютерных наук или навсегда прослыть «особенным» среди коллег, сразу после немедленного увольнения?
Ниже патентованный метод, с которым вас точно не забудут.
Вы наблюдаете самый настоящий ящик Пандоры, который автор для вас любезно приоткрыл.
Электронная дичь
Ладно, допустим вы не имеете отношения к ИТ или не занимаетесь непосредственно разработкой ПО. Возможно вы начинающий веб‑разработчик, умеющий только в лендинги и сайты‑визитки — словом вы никогда прежде не слышали об экзотерических языках программирования и их ярчайшем представителе:
Brainfuck — один из эзотерических языков программирования, придуман Урбаном Мюллером (нем. Urban Müller) в 1993 году, известен своим минимализмом. Название языка можно перевести на русский как вынос мозга, оно напрямую образовано от английского выражения brainfuck (brain — мозг, fuck — вынос), т. е. заниматься ерундой. Язык имеет восемь команд, каждая из которых записывается одним символом. Исходный код программы на Brainfuck представляет собой последовательность этих символов без какого-либо дополнительного синтаксиса.
Понимаю, тяжело воспринять фразу «экстремальный минимализм» по отношению к языку программирования, поэтому вот вам небольшая иллюстрация:
Brainfuck почти не используется для практического программирования (за исключением работ отдельных энтузиастов), а используется преимущественно для головоломок и задач для соревнований.
Теперь, если вы занимаетесь разработкой и более‑менее подкованы в программировании — вернитесь обратно к картинке выше и задумайтесь: чтоименно автор тут для вас приготовил:)
Транспилеры и компиляторы
Минутка матчасти, прежде чем мы с вами погрузимся в бездну бесконечного ужаса разработки, для лучшего хоть какого-то понимания этой сложной темы.
A source-to-source translator, source-to-source compiler (S2S compiler), transcompiler, or transpiler is a type of translator that takes the source code of a program written in a programming language as its input and produces an equivalent source code in the same or a different programming language. A source-to-source translator converts between programming languages that operate at approximately the same level of abstraction, while a traditional compiler translates from a higher level programming language to a lower level programming language.
Максимально упрощая, транспилер — такой специальный компилятор, для превращения исходного кода на одном языке в исходный код на другом языке.
Очень часто используется на практике, в том числе в современных и сверхпопулярных языках вроде Java или.NET.
Чаще всего такую технику применяют для выдачи «желаемого за действительное», например с помощью транспилера реализованы ваши любимые генерики и замыкания в Java.
Да это «та самая программа с помощью которой создаются другие программы», в изначальном смысле этого слова.
Практически любой компилятор — очень сложная программа, даже использование которой требует определенной подготовки. Ну а задача создания компилятора с нуля — предмет для изучения в высших технических заведениях и удел исключительно опытных профессионалов.
В теории.
Теперь совместите в воображении безумный эзотерический язык программирования и связку из транспилера и компилятора.
Именно эту дичь мы сейчас и будем творить.
Но все же объясню чуть подробнее, для обывателей:
программировать на самом Brainfuck безумно тяжело и ничего сложнее «Hello, World» у вас не выйдет пока вы не рехнетесь, но если использовать транспилер, — становится возможно писать код уже на С (или С‑подобном языке) и гораздо более интересные вещи.
Полный вариант занимает ~1.6Mb одной строкой, представляте как обрадуется любимый преподаватель такой оригинальной работе?
Главное чтобы вас потом не нашли.
Теперь перейдем к инструментарию для наших веселых шалостей.
Гримуар
Поскольку программисты по большей части ребята веселые, оказалось что для языка Brainfuck реализовано очень много всего интересного. Ниже будет небольшой обзор самых отбитых инструментов, которые мы будем использовать во имя Луны для создания тестового проекта.
Вся эта радость отлично встраивается например в Python‑скрипт работающий с нейросетями, тем самым добавляя новую грань смысла слову «blackbox», которым так любят прикрывать свои провалы ML‑разработчики.
К сожалению этот проект очень далек до завершения:
For instance, BFPY can only translate arithmetic operations (addition, subtraction, multiplication, floor division and power). There is still a lot of features to implement for it to be a proper Python runtime alternative
Поэтому если у вас есть лишний $1млн и ненависть к человечеству — можете проинвестировать в этот замечательный проект. Деньги пойдут автору на лечение в лучшей дурке.
Brainfix
Следующий проект зашел немного дальше в своем безумии, поэтому именно с его помощью мы с вами и сделаем тестовое приложение:
BrainFix is a compiler/language that takes a C-style language (although the syntax slowly evolved to something very close to Javascript for some reason) and compiles this into BrainF*ck, an esoteric programming language consisting of only 8 operations.
Для проверки корректности, вставляем полученный код Brainfuck в онлайн-интерпретатор:
Чего только не бывает в интернете.
Там еще многоинтересныхпримеров, но большие программы будут ощутимо долго компилироваться в код на Brainfuck, имейте ввиду.
Но едем дальше.
BFC
Как лаконично описывает проект его автор: «an industrial‑grade Brainfuck compiler» и он при этом совсем не врет:
bfc includes an extensive range of optimisations. This page discusses the techniques used, and gives examples of BF programs that are transformed in each case.
Написана эта штука разумеется на Rust (неужели вы сомневались?) и сейчас мы будем ее пенетри.. ээ использовать.
Поскольку дело происходит на FreeBSD (неужели я забыл об этом упомянуть?), с помощью переменной окружения RUSTFLAGS необходимо указать путь /usr/local/lib, который почему‑то не учитывается сборщиком cargo.
Также на машине должен быть сам Rust и 14я версия LLVM.
Зато теперь вы тоже знаете как использовать Rust на FreeBSD, надеюсь эти знания помогут вам построить успешную карьеру в ИТ-индустрии а не наставят на путь экстремального ИТ-терроризма.
В результате успешной сборки в каталоге ./target/debug появится готовый к использованию бинарник bfc:
Предупреждения компилятора, которые не решился исправлять даже автор
Что же мы будем делать с оптимизирующим компилятором Brainfuck? Разумеется использовать для всего хорошего и замечательного:
Это тот самый пример с «Hello world!» сгенерированный выше из С‑подобного кода, который с помощью замечательного оптимизирующего компилятора превратился в настоящее приложение:
Только что собранное, нативное приложение на Brainfuck
Итого
Повторим еще раз всю цепочку для лучшего запоминания:
Код на С‑подобном языке → транспилер Brainfix → компилятор Bfc → готовое приложение
В чем отличие от обычной разработки:
Вы спокойно сдаете в качестве лабы код на Brainfuck, который будет компилироваться в запускаемый бинарник и вполне себе подпадать под термин «исходный код».
Разумеется ваш любимый преподаватель будет в полном восторге, пытаясь в этом коде разобраться, в то время как вы никаких сложностей даже не увидите, поскольку настоящий код с читаемой логикой останется на уровне транспилера.
Правда весело?
Примерно из-за таких милых шалостей мои бывшие преподы до сих пор меня помнят мою фамилию.
Ну а если вас попросят написать тестовое задание, вставив в постановку фразу «на любом известном вам языке» — теперь вы знаете как и на чем его делать.
Само собой вся изложенная информация приведена исключительно в развлекательных целях, не стоит применять подобные технологии на практике в реальных проектах.