«Драйверы устройств FreeBSD: от первых шагов к освоению ядра» — это бесплатная книга с открытым исходным кодом, которая проведёт вас от состояния «Я никогда не писал код ядра» до состояния «Я могу писать, отлаживать и отправлять драйверы FreeBSD производственного качества». Это скорее пошаговый курс, чем справочник, структурированный вокруг 38 глав, 6 приложений и десятков практических заданий, которые компилируются и загружаются в реальной системе FreeBSD 14.x, пояснил автор проекта Эдсон Бранди.
Что такое LDL? Это графическая библиотека с единым API для всех систем как старых, так и новых.
Раньше я писал её на C++98, что давало хорошую портабельность. Но сейчас я пересмотрел многие тезисы, которые декларировал на GitHub, чтобы наконец добраться до первого релиза.
Новая стратегия
Я решил выпускать релизы без реализации полного функционала (графика, звук, шрифты и т.д.) постепенно, итеративно.
Перешёл на C89 для максимальной переносимости. Это не только DOS или Windows 3.x, но и старые системы вроде Solaris, PlayStation 1 и другие.
Для первого релиза реализую минимальный базовый функционал: графику (OpenGL, Vulkan), окна и события. По возможностям аналог GLFW.
С каждым следующим релизом буду добавлять: 2D-рендер, звук, шрифты и прочее.
Лицензия и целевые платформы
Лицензия меняется на LGPLv3.
На старте поддерживаются Windows и Linux.
Качество и инструменты
При разработке использую:
AddressSanitizer (ASan)
UndefinedBehaviorSanitizer (UBSan)
Различные анализаторы кода
Я считаю, что такая стратегия полезнее, чем годами доводить библиотеку до версии 1.0 в офлайн-режиме.
Примеры и бэкенды
Добавлю десятки примеров с OpenGL 1.x, OpenGL 3.x и Vulkan.
Буду добавлять бэкенды для LDL: не только под ОС, но и поверх других графических библиотек — SDL, SFML, GLFW и т.д.
API остаётся единым для всех бэкендов.
Это позволит сразу добавить поддержку звука и шрифтов (через бэкенды), а в нативных версиях реализовывать их позже.
2D-рендер без границ
Одной из главных задач LDL я вижу создание единого 2D-интерфейса, который стирает различия между поколениями графики.
Вам не нужно думать о том, что находится в системе: современная видеокарта с Vulkan, старый ускоритель с OpenGL 1.2 или вообще только центральный процессор (Software Rendering).
Единый интерфейс: Вы используете одни и те же команды для рисования пикселей, линий и спрайтов.
Адаптивность: LDL сам выберет наиболее эффективный способ вывода изображения. На современной системе это будет аппаратное ускорение, а на «железе» без видеокарты оптимизированный программный растеризатор.
Визуальная честность: Ваш визуальный стиль останется неизменным, на чем бы он ни запускался. Это дает возможность делать игры и приложения, которые выглядят и работают одинаково и на ретро-ноутбуке, и на современном мониторе.
Философия: Машина времени в вашем коде
Зачем тратить силы на поддержку систем, которые многие считают «трупами»?
1. Борьба с цифровым забвением
Современный софт живет 3–5 лет. Мы выбрасываем железо не потому, что оно сломалось, а потому, что софт стал слишком тяжелым и ленивым. LDL — это протест против «запланированного устаревания». Я хочу, чтобы код, написанный сегодня, мог дышать в железе любой эпохи.
2. Инженерный аскетизм
Когда у тебя гигабайты памяти, ты перестаешь ценить каждый байт. Написание библиотеки под C89 для слабого железа — это духовная практика для программиста. Это возвращение к искусству находить изящные решения в условиях жестких ограничений. Каждый сэкономленный такт процессора — это дань уважения инженерам прошлого.
3. Преемственность поколений
Мы стоим на плечах гигантов, но часто забываем их имена. LDL сохраняет возможность для диалога между эпохами. Это инструмент, который позволяет современному разработчику почувствовать «металл» старых машин, не теряя связи с современными технологиями вроде Vulkan.
Итог
LDL — это Little Directmedia Layer. Он маленький не потому, что слабый, а потому, что в нем нет ничего лишнего. Это попытка создать код, который будет принадлежать не конкретной версии ОС, а истории программирования в целом.
Один API. Один код. Тридцать лет компьютерной истории.
Разработчик Александр Гомес Гайгалас (Alexandre Gomes Gaigalas), автор библиотеки coral для создания переносимых shell-скриптов, опубликовал проект C89cc.sh. Это компилятор для языка C, написанный целиком на Shell.
Компилятор поддерживает стандарт C89 и может генерировать исполняемые файлы в формате ELF64 для систем x86-64. Исходный код проекта содержит около восьми тысяч строк и открыт под лицензией ISC.
Всё, что нужно знать для начала работы в PVS-Studio
Статический анализатор PVS-Studio — это инструмент для поиска ошибок в коде на протяжении всего жизненного цикла проекта. В новой статье разберём основные особенности анализатора PVS-Studio, сценарии и варианты анализа, а также узнаем всё, что нужно знать для начала работы с инструментом.
NixOS: идея, до которой индустрия доросла только сейчас.
Кажется, NixOS наконец выходит из категории системы «для своих» и становится все заметнее в инженерной среде. Это закономерно: он очень точно попал в проблемы, с которыми команды массово столкнулись только в последние годы.
История началась в 2003 году, когда исследователь Элко Долстра и его коллеги в Утрехтском университете запустили проект Nix. Это исследовательский проект, который включал пакетный менеджер и собственный декларативный язык. Идея была сделать так, чтобы пакеты и зависимости собирались предсказуемо, не конфликтовали между собой и не превращали систему в хаос после очередного обновления. Чуть позже из этой логики вырос NixOS, где тот же подход применили уже ко всей операционной системе.
В этом и был главный поворот. Nix с самого начала смотрел на систему не как на набор вручную настроенных файлов и команд, а как на то, что можно описать целиком. Пакеты хранятся изолированно, разные версии могут спокойно жить рядом, а состояние машины задается через конфиг. За счет этого обновления становятся атомарными.
Это особенно интересно на фоне обычных Linux‑дистрибутивов. Там текущее состояние системы часто является результатом длинной цепочки действий: что‑то поставили, что‑то удалили, где‑то поправили конфиг, где‑то забыли. В NixOS логика другая: ты описываешь желаемое состояние, а система приводит машину именно к нему. Если новая конфигурация не взлетела, предыдущее состояние никуда не исчезает.
😏 Почему NixOS набирает популярность именно сейчас? Потому что индустрия наконец доросла до его сильных сторон. Чем больше у команды окружений, CI/CD, инфраструктуры как кода и цены ошибки, тем важнее воспроизводимость и предсказуемость. То, что раньше выглядело как нишевая экзотика, сегодня все чаще выглядит как очень здравый инженерный выбор.
Многие современные immutable‑системы по сути идут в ту же сторону, куда NixOS пошел еще много лет назад.
А если хочется не просто прочитать про Nix, а разобраться, как он работает на практике, приходите на наш открытый воркшоп.
📹 Открытый воркшоп в рамках ИнженеркаТех Плюс, 18 марта в 19:00 по МСК. Александр Сергеев из сообщества RULKC, Russian Linux Kernel Community, расскажет про Nix и функциональный подход к пакетам и сборке.
Если вы хотите получить полный контроль над окружением и наконец закрыть вопрос воспроизводимых сборок, этот воркшоп для вас. Разберем ключевые концепции Nix и наглядно покажем, чем он отличается от привычных систем управления пакетами.
Помогите добить реверс bike tracker на MC60 + STM32L486 – что здесь за интерфейсы и как лучше подступиться.
Больше фото в конце!
Есть у меня bike tracker infocar bikeAngel AMB02. Разобрал его и сейчас пытаюсь спокойно, без лома через колено, понять архитектуру платы, интерфейсы и нормальный маршрут реверса. По фото и маркировке пока получается такая картина:
есть SIM-слот, батарейный блок и несколько непонятных тестовых/сервисных точек.
Из того, что пока смущает –MC60 и STM32 здесь явно живут как два разных мозга, и я пока не до конца понимаю, кто кого будит, кто держит power sequencing и где именно проходит основной UART.
На плате нет «человеческих» кнопок boot/reset, поэтому неочевидно, насколько реалистично подлезть к MC60 напрямую без плясок с его boot/pwrkey линиями. Не уверен, не зашита ли вся критичная логика именно в STM32, из‑за чего идея «просто заменить SIM и жить» может оказаться слишком наивной.
Что уже удалось идентифицировать по плате:
MC60 — сотовая часть, GPS и Bluetooth а STM32L486 — управляющий MCU,
SPI flash рядом с белым разъёмом , возможный сервисный коннектор / debug-разъём;
батарейный блок выглядит как 1S Li-ion pack на нескольких параллельных банках.
Моя цель сейчас не «ломать прод», а именно картировать железо, найти UART между STM32 и MC60 — понять, где SWD на STM32. Определить, можно ли безопасно снять дамп / хотя бы проверить RDP. Понять, есть ли смысл лезть в SPI flash отдельно да и прикинуть, насколько жизнеспособен вариант со своей SIM и своим софтом. Инструменты у меня пока довольно базовые: паяльник и USB‑UART, нормального анализатора и ST‑Link пока нет. (Заказал себе пока, ST‑link v2 Clone M89 для STM).
Поэтому особенно интересны советы именно по порядку действий: с чего лучше начать, чтобы не убить плату и не потратить неделю впустую.
Прошу помощи. Не могу найти документацию на плату. Купил когда-то на а**-э*****сс, но к ней не было в комплекте вообще ничего. За время поисков удалось найти только два фрагмента схемы. Мб есть у кого такая....
P.S. Если вам будет интересно, а у меня силы и карма - то расскажу, что там и как в отдельной статье. А теперь и ответ на всех мучающий вопрос: "Почему пингвин пошёл в горы?"
На неделе вспомнил про wchar_t в Си, пока в очередной раз работал с Unicode, но в Windows. Штука… Неоднозначная.
Часть WinAPI жёстко завязана на WCHAR (wchar_t). Но в Windows он до сих пор определён размером в 16 бит. Тот же GCC на Debian мне говорит, что у него wchar_t — все 32 бита.
Т.е. перевод строки из char в wchar_t генерирует валидный UTF-16 в Windows, но UTF-32 в Linux…
Кажется, char32_t должен решить эту чехарду в будущем… Хотя бы с точки зрения размерности… Пусть это и не исправит проблемы WinAPI…
Но действительно ли так часто нужно работать с полноценным code point в Unicode? Зачем? Только чтобы посчитать общее количество символов? Это же просто сделать и на основе char!
Авторы UTF-8 Everywhere дают развёрнутый ответ на этот и многие другие вопросы. Идея хорошо проработана, есть даже прекрасный FAQ для любопытных.
На этой веб-странице собрали самые веские доводы для использования исключительно UTF-8. Везде. Всегда.
Надоело искать парные вкладки (.h/.cpp) в VS Code? Я навайбкодил расширение, которое их магнитит.
Привет! Меня всегда немного раздражала одна мелочь в VS Code.
Открываешь Source.cpp, хочешь посмотреть заголовок, а Source.h открыт где-то в конце списка вкладок или вообще затерялся среди десятка других файлов. Приходится глазами искать его или тянуться к дереву проекта.
Стандартные методы сортировки тут не помогают, поэтому я написал Tab Magnet.
Как это работает: Вы просто кликаете на файл в Explorer-е. Tab Magnet проверяет, открыта ли его "пара" (например, .h для .c или .html для .component.ts), и если да - автоматически переносит её поближе, чтобы они стояли бок о бок.
Функционал:
Знает, что заголовки лучше держать справа, а тесты — рядом с кодом.
Поддерживает из коробки C/C++, C#, Web (JS/TS/HTML/CSS) и Angular.
Можно настроить свои правила (например, для Go тестов или специфичных структур папок).
В течении нескольких последних дней активно почитывал книгу Дженса Густеда “Modern C”.
Книга будет хороша как общий справочник, набор best practices кодинга на C, да и просто посмотреть, какие трюки в C23 можно делать.
Удивительно, что столь детальную и кропотливую работу можно найти в свободном доступе. Распространяется книга по лицензии CC 4.0 в вариации BY-NC-ND. Это очень радует.
Книга структурирована по уровню вовлечённости в C. От самых базовых элементов до многопоточных программ.
Для опытных разработчиков больше всего будут интересны Takeaways. Они резюмируют текст и позволяют фокусироваться на самом интересном. В конце книги есть листинг всех Takeaways, разбитый по разделам книги.
Иногда может показаться, что для тестирования программ нужно обязательно взять монструозный фреймворк, внедрить его в свою систему сборки, а потом при каждой проверке искать, какие же assert он умеет делать.
На практике это не всегда так.
Да, мир Си — дикий запад. Но, тем лучше, всегда есть выбор.
Джон Брюер приводит превосходный пример того, каким может быть минималистичный фреймворк для тестирования. Всего пара макро и одна переменная, восхитительно!
Только что в один из своих проектов на микроконтроллере RP2040 понадобилось интегрировать графический дисплей для отображения погодной информации. Выбор пал на распространенные монохромные OLED-дисплеи разрешением 128х64 точки.
Из плюсов этих дисплеев для меня: высокая яркость и контрастность, простота интерфейса, дешевизна и высокая плотность информации в небольшом размере.
Контроллер у всех этих дисплеев стандартный - SH1106.
Свои проекты я пишу на С с использованием нативной Pico SDK. Поиск библиотеки для нужной платформы на С результатов не дал. Все, что на данный момент есть, - различные ардуино-библиотеки и микропитон.
В итоге было принято решение портировать на RP2040 одну из реализаций для STM32. Эта библиотека умеет рисовать графические примитивы в виде вертикальных и горизонтальных линий, прямоугольников пустых и заполненных, растровых изображений а также есть различные функции вывода текста и числовой информации.
Библиотека позволяет задать разрешение экрана а разворачивать экран на 90/180/270 градусов.
Изначально библиотека включала в 2 шрифта с размерами знакомест 5х7 и 7х10 точек.
Для своих целей я самостоятельно разработал большой шрифт 12х16 точек (на фото он).
Всем привет, это снова stalker320. Делаю что-то вроде анонса, я тут изучаю что появилось в C23 и думаю записать пару уроков с помощью него, так как пара новых функций выглядят теперь довольно интересными, к примеру, при объявлении перечисления теперь можно указать размер поля (: char). Вот он в исходном виде:
Компьютерное зрение для кода: что PVS-Studio разглядел в OpenCV
Что общего у компьютерного зрения и статического анализа? Оба ищут смысл в данных. OpenCV находит образы среди миллионов пикселей, а PVS-Studio — ошибки среди тысяч строк кода. Изучим же исходники крупнейшей библиотеки компьютерного зрения.
На примере 14 фрагментов кода из OpenCV предлагаю посмотреть, как статический анализ помогает избежать попадания багов в релиз и облегчить жизнь разработчикам.
Давайте посмотрим на кусок кода из проекта:
template<typename T>
struct Ptr : public std::shared_ptr<T>;
// ....
Ptr<FlannNeighborhoodGraph> FlannNeighborhoodGraph::create(....)
{
return makePtr<FlannNeighborhoodGraphImpl>(....);
}
void Utils::densitySort (const Mat &points, int knn,
Mat &sorted_points, std::vector<int> &sorted_mask)
{
// ....
FlannNeighborhoodGraph &graph = // <=
*FlannNeighborhoodGraph::create(....);
std::vector<double> sum_knn_distances (points_size, 0);
for (int p = 0; p < points_size; p++) {
const std::vector<double> &dists = graph.getNeighborsDistances(p);
for (int k = 0; k < knn; k++)
sum_knn_distances[p] += dists[k];
}
// ....
}
Если вы думаете, что использование умных указателей раз и навсегда решает проблему "висячих" ссылок и доступов к памяти, то здесь всё пошло не так. Давайте разбираться. Сейчас код работает следующим образом:
Функция create создаёт и возвращает умный указатель на тип FlannNeighborhoodGraphImpl, и его счётчик ссылок на объект равен единице;
Создаётся ссылка graph на значение этого умного указателя, при этом счётчик ссылок на объект не изменяется;
Указатель является временным объектом, и поэтому после завершения инициализации счётчик ссылок уменьшится до нуля, что приведёт к освобождению управляемого объекта. Теперь ссылка указывает на разрушенный объект;
В цикле for происходит обращение к невалидной ссылке.
В итоге код, который казался правильным, приводит к неопределённому поведению. Кроме того, эту проблему находит не только PVS-Studio, но и санитайзер. Пруф.
Для исправления необходимо сохранить умный указатель, тогда объект типа FlannNeighborhoodGraph будет жить до конца блока. Можно сделать так:
std::vector<double> sum_knn_distances (points_size, 0);
{
// get neighbors
auto graph = FlannNeighborhoodGraph::create(....);
for (int p = 0; p < points_size; p++) {
const std::vector<double> &dists = graph->getNeighborsDistances(p);
for (int k = 0; k < knn; k++)
sum_knn_distances[p] += dists[k];
}
}
Дополнительно ограничили область видимости graph, чтобы ресурс освободился после выполнения циклов.
Хотите узнать больше?
Статический анализ выявляет скрытые дефекты даже в больших работающих проектах. Какие ещё опасные фрагменты кода мы нашли в коде OpenCV? Полный разбор можно найти в отдельной статье.
Слышали ли вы про то, что злобные C и C++ компиляторы могут удалить вызов memset в конце функции во время оптимизаций? У нас даже про это есть диагностика V597.
Это давно известная, но при этом живучая потенциальная уязвимость CWE-14: Compiler Removal of Code to Clear Buffers. В следующем коде компилятор удалит заполнение памяти нулями (вызов memset), так как после этого буфер не используется. Раз не используется, то заполнение буфера с точки зрения языка C++ не имеет каких-либо наблюдаемых эффектов и, следовательно, является лишим. Т. е. его можно и нужно удалить с целью оптимизации.
Код позаимствован из статьи про проверку проекта PPSSPP.
Проблема насущная, и для её решения в стандарт C23 внесли новую функцию memset_explicit, которая теперь обязательна для реализации в стандартной библиотеке вместо memset_s. Так вот, автор предложения (Miguel Ojeda, P1315) в своём документе сослался на нашу диагностику (ссылка N3).
И похоже, что он давно про нас знает, т. к. умудрился вставить ссылку ещё аж на старый сайт viva64.
Не зря столько лет говорим про memset. Приятно, что нас уже в proposal-ы затаскивают :)
Вместе с экспертами из "ФанкСэйфети" разбирались с такими сущностями, как ГОСТ Р МЭК 61508, уровнями SIL, стандартом MISRA C, сертификацией по функциональной безопасности и т. д.
В конце была активная дискуссия, во время которой отвечали на интересные вопросы. По её итогу приводим дополнительную информацию и ссылки.
Тип недостатка: Необоснованный выбор инструментов, в том числе инструментов статического анализа исходного кода, для выстраивания и выполнения процессов РБПО.
Описание: В настоящий момент ФСТЭК России не предъявляет требования наличия сертификата соответствия к большинству типов инструментов анализа кода и архитектуры. При этом к инструментам предъявляются следующие требования: ...
Примечание 3. Был вопрос, связанный с объединением требований ФБ и ИБ в одном стандарте. Некоторые усилия в этом направлении предпринимаются, см. примеры ГОСТов ниже:
ГОСТ Р 59506-2021/IEC TR 63074:2019. Безопасность машин. Вопросы защиты информации в системах управления, связанных с обеспечением функциональной безопасности.
ГОСТ Р 71452-2024/IEC/PAS 63325:2020. Требования к функциональной безопасности и защите системы контроля промышленной автоматизации (IACS) на протяжении жизненного цикла.
Однако необходимо понимать, что у ФБ и ИБ разные цели и разные подходы, поэтому объединение технических требований может создать путаницу, и сейчас меры по объединению некоторых аспектов ФБ и ИБ носят, прежде всего, организационный характер.
Как анализировать C и C++ код без привязки к сборочной системе на Windows
Код, написанный на C и C++, может использоваться для самых разных целей. И под каждые из этих целей есть свои инструменты сборки. Например, при разработке программного обеспечения для встраиваемых систем используются специальные компиляторы и сборочные системы.
Иногда бывает так, что появляется целый "зоопарк" самописных скриптов сборки, а его последний "смотритель" уволился ещё в прошлом году (играет Гражданская Оборона — "Зоопарк").
Хотелось бы всё равно как-то анализировать такой код без необходимости разбираться в хрупкой и непонятной системе сборки. Что же делать?
На самом деле, решение есть! Смысл взаимодействия анализатора со сборочной системой состоит в том, чтобы получить необходимую для анализа информацию. Но получить её можно и другим способом: из запущенного процесса компиляции.
В новой статье посмотрим, как воспользоваться этим механизмом для ОС Windows в анализаторе PVS-Studio, и как сделать его использование в процессе разработки удобным.
Ускоренный найм для инженеров C/C++: оффер за 3 дня
Телеком-команда YADRO создает решения для мобильных сетей нового поколения: базовые станции GSM и LTE, а также весь программный стек — от низкоуровневых протоколов до систем управления. Сейчас в команде открылись вакансии инженеров, отбор на которые можно пройти гораздо быстрее, чем обычно.
SPRINT OFFER — это формат ускоренного найма: все этапы отбора проходят всего за три дня. Чтобы попасть в программу, достаточно подать заявку до 19 октября.
Software Engineer (телеком-платформа)
Вам предстоит разрабатывать платформенное решение для телеком-систем. На его основе строятся современные узлы сотовых сетей LTE- и GSM-стандартов — например, базовые станции и системы управления. В это роли вы будете:
Развивать платформу, обеспечивающую middleware-сервисы, высокую доступность и управление узлами для приложений, входящих в состав базовой станции LTE/GSM.
Разрабатывать компоненты платформы в технологическом стеке C++/Linux.
Собирать и анализировать метрики для оценки производительности продукта.
Создавать и оптимизировать высокопроизводительные каналы коммуникации между компонентами, а также работать с подсистемами временной синхронизации, управления конфигурацией инфраструктуры и компонентов.
Поддерживать средства развертывания и обновления приложений.
Разрабатывать API для взаимодействия с аппаратным обеспечением и операционной системой при конфигурации и управлении инфраструктурой.
Обеспечивать качество продукта: исправлять дефекты, писать unit-тесты, проводить код-ревью, разрабатывать техническую документацию.
Создавать инструменты, упрощающие работу других разработчиков.
Участвовать в диагностике и анализе проблем работы системы в тестовых и полевых сценариях.
Создавайте высоконагруженные системы, которые обеспечивают стандарты связи разных поколений. Работа охватывает три уровня. L1 — низкоуровневое программирование, работа с радиоканалом и сигналами, близкая к железу. L2 — логика, работа с алгоритмами и математическими моделями. L3 — высокоуровневое программирование, бизнес-логика. В этой роли вы будете:
Разрабатывать решения совместно с командой — от этапа исследования и прототипирования до коммерческого внедрения пакетного ядра сети 5 поколения (5G).
Создавать программное обеспечение для базовых станций LTE, реализуя полный стек протоколов 3GPP.
Разрабатывать спецификации и дизайн программного обеспечения.
Интегрировать решения с другими компонентами системы — как программными, так и аппаратными.
Поддерживать и оптимизировать код, обеспечивая стабильность и производительность продукта.
Исследовать и устранять проблемы, влияющие на надежность, производительность и масштабируемость системы.