История одного патча II: приключения в FreeBSD
Еще одна поучительная история из жизни открытого ПО, на этот раз про «заимствование» чужих исходников.
Помните, рассказывал об одном досадном баге в ядре Linux, выедавшем мне мозг последние несколько лет?
Внезапно этот же баг проявился в совершенно другой операционной системе, по идее не имеющей к линуксу никакого отношения — FreeBSD.
С чего я знатно прих#ел впал в недоумение, поскольку интернет испокон веков и поныне заполнен срачами интеллектуальными дискуссиями на тему «Linux vs FreeBSD» — их радикальных отличий в самих идеях и концепциях, позиционировании и половой ориентации авторов.
Для тех кто не ходит по ссылкам, напомню суть бага:
Ноутбук засыпает, ноутбук просыпается и батарея «зависает» — перестает отдавать свой статус и уровень заряда.
Ноутбук старый, ноутбук редкий, из тех сказочных времен, в которые подсистема ACPI считалась чем-то новым и еще не до конца проработанным.
Поэтому производители компьютерного оборудования позволяли себе вольности по части поддержки ACPI в своих девайсах. И разумеется описываемый ноутбук (Asus F3Ke) оказался одним из таких.
Не буду повторять тут всю историю поиска решения, занявшего несколько лет — она описана в оригинальной статье и достаточно интересна для чтения.
Расскажу в этот раз про другое:
как бл#ть, каким таким сказочным образом баг в драйвере (!) одной открытой ОС перекочевал в другую открытую ОС.
Напоминаю на всякий случай, что термин «драйвер» — из мира Windows и для Linux/BSD не совсем корректен, поскольку прямого аналога драйверов оборудования в этих ОС нет.
Короче, сказочная х#ня о которой идет речь называется:
И живет оно внутри ядра, без возможности выгрузки.
Симбиоз
Конечно это не тайное знание и не «секрет полишинеля», что разработчики открытых систем постоянно обмениваются идеями и копируют друг у друга какие-то наработки — это разумно, поскольку в некоторых случаях нет ни смысла ни ресурсов изобретать собственный велосипед.
У проекта FreeBSD долгая история заимствований из Linux, для примера именно таким путем (прямого заимствования) в FreeBSD появился DBus, появился Bluez (поддержка Bluetooth) и много чего еще.
Процесс зашел настолько далеко, что появился и активно развивается отдельный слой эмуляции Linux на уровне ядра, позволяющий запускать практически любые Linux-приложения.
Но к заимствованию из Linux исходного кода целых подсистем, еще и прямо в ядро — к такому я был не готов.
Еще я не был готов к нынешним реалиям — история с ACPICA оказалась несколько глубже и интереснее, чем просто заимствование.
Мы пришли с миром
В исходном коде FreeBSD есть каталоги contrib, в которых находится код, разрабатываемый вне проекта FreeBSD. Сразу уточню, что речь не про пакеты или порты а про саму базовую ОС.
Каталогов contrib несколько, первый находится прямо в корне и содержит внешний исходный код утилит и библиотек, используемых в базовой системе:
Второй contrib находится в каталоге sys и содержит заимствованный код, используемый непосредственно в ядре FreeBSD:
Именно тут находится виновник нашего торжества, в каталоге:
/usr/src/sys/contrib/dev/acpica
Место правки - файл components/events/evregion.c, как видите сохранен даже оригинальный комментарий.
Сама правка и ее причины описаны в первой части:
/*
* These address spaces do not need a call to _REG, since the ACPI
* specification defines them as: "must always be accessible". Since
* they never change state (never become unavailable), no need to ever
* call _REG on them. Also, a DataTable is not a "real" address space,
* so do not call _REG. September 2018.
*/
if (
//(SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) ||
(SpaceId == ACPI_ADR_SPACE_SYSTEM_IO) ||
(SpaceId == ACPI_ADR_SPACE_DATA_TABLE))
{
return_VOID;
}Единственное заметное отличие — использование другой нотации в именовании переменных.
После правки ядро необходимо пересобрать и установить:
make buildkernel KERNCONF=ALEXS make installkernel
Напоминаю, что правка находится в подсистеме ACPICA, которая не отделяема и не выгружаема — т. е. монолитная часть ядра FreeBSD.
ACPICA
Мне стало интересно, что же это за неведомая хня, написанная на чистом Си и вот так просто кочующая из одной операционной системы в другую.
Недолгое гугление вывело на сайт проекта и репозиторий на Github:
The ACPI Component Architecture (ACPICA) project provides an open-source operating system-independent implementation of the Advanced Configuration and Power Interface specification (ACPI).
Думаю по сайту нетрудно догадаться, что отвечает за ACPICA компания Intel, которая славится своей любовью к закрытым прошивкам.
А теперь самое интересное, вот так выглядит оригинальный код с проблемным местом, которое я исправлял:
Как видите никаких отличий нет и даже сам комментарий с пояснением как оказалось был перенесен в ядро Linux именно отсюда.
А затем этот же код от Intel был внесен и в кодовую базу FreeBSD.