Pull to refresh

Comments 35

Сейчас BIOS правильнее называть UEFI, но по инерции многие продолжают называть эту систему BIOS

Вообще-то, не совсем так. В большинстве современных ПК классический BIOS объединён с современным UEFI, поэтому может прикидываться хоть тем, хоть другим в зависимости от того, какая система загружена. Недавно я ради изврата на комп с Ryzen-что-то-там поставил MS DOS :) Работает-с.

В начале 80-х годов компания IBM разработала для своих компьютеров микропрограмму, которая обеспечивала инициализацию оборудования

Вообще-то, микропрограмма -- это то, что управляет работой процессора, если он с микропрограммным, а не жёстким схемным управлением. BIOS же -- самая что ни на есть программа, и то, что она сидит не в ОЗУ, а в ПЗУ, не делает его микропрограммой. Думается, на русском языке лучше содержимое ПЗУ BIOS всегда именовать прошивкой.

Эта система получила название BIOS, то есть базовая система ввода-вывода. Это была закрытая проприетарная разработка

BIOS IBMовских персоналок не был закрытой разработкой. Исходник BIOS для IBM PC, например, опубликован в Technical Reference Manual на этот компьютер.

Основная задача этой стадии на процессорах Intel — инициализация оперативной памяти. Это сложный процесс, он требует больших объемов закрытого кода, из-за чего его практически невозможно реализовать самостоятельно, даже если у вас есть все необходимые спецификации

Хм... Почему это его "практически невозможно реализовать самостоятельно", если спецификации имеются?

Вернемся к режиму SMM. Его преимущества особенно заметны в серверных продуктах благодаря технологии RAS. Это набор обработчиков ошибок оборудования. В SMM работают драйверы, которые реагируют на прерывания, так как доступ в режим SMM возможен только через SMI. Из обычного кода, в том числе из кода ядра ОС, напрямую попасть в SMM нельзя.

Например, работающий сервер выдает ошибку памяти. Если система настроена правильно, то оборудование генерирует SMI, которое переводит процессор в режим SMM. В нем запускается соответствующий обработчик, который предпринимает действия для устранения или учета ошибки. 

Вообще, SMM -- это жуткий костыль, придуманный для того, чтоб управлять электропитанием ранних компов в условиях, когда ОС этим заниматься не умела (впервые появился в 80386SL). Обработка тех же ошибок памяти в SMM -- тоже не лучшее решение, если ОС умеет такое обрабатывать (а современные, теоретически, должны бы уметь это делать, ведь процы уже достаточно давно способны кидать прерывания при аппаратных ошибках, ну а в самых первых ПК в качестве сигнала неисправности памяти или ещё какой аппаратной ошибки использовался NMI).

Кстати говоря, у IBMовских мэйнфреймов прерывания от схем контроля были от Системы 360 до наших дней (т.е. с 1964-65 года), и ОС при возникновении такого прерывания думала, что делать дальше. Например, отказ блока памяти, если в этом блоке размещался прикладной код, приводил к "убийству" программы пользователя, но система в целом работоспособность сохраняла; отказ канала ввода-вывода приводил, понятное дело, к аварийному завершению всех выполняющихся операций ввода-вывода на этом канале, но при наличии альтернативных путей к нужным устройствам работоспособность системы, опять-таки, сохранялась, ну и т.д. и т.п.

Если сервер поддерживает разъем XDP, мы подключаем устройство Intel BlueBox для отладки

А синяя коробка поддерживает точки останова, покомандное выполнение и всё такое прочее, что доступно в обычных программах с помощью обычных отладчиков?

Хм... Почему это его "практически невозможно реализовать самостоятельно", если спецификации имеются?

Дело не в спецификации. Дело в ассемблере, на котором обычно пишется инициализация памяти. Ведь когда нет памяти, то и стека нет. А без стека, например, язык Си работает не очень хорошо (скорее не работает).

Как результат, производитель процессора делает некую ассемблерную "штуку", которая умеет работать без памяти (и старается использовать кэш процессора как псевдо-память, чтобы хоть что-то хранить - на одних регистрах совсем грустно будет; там как раз и есть закрытый код, который ещё и специфичен для семейства процессора) и она память инициализирует, учитывая при этом, что могут использоваться разные банки памяти (например, разъёмов памяти больше, чем планок с памятью), разные скорости (делаем вычитывание битиков с железки) и объём планок тоже всякий бывает. А ещё желательно (например, для SOC) иметь возможность жёстко задать, где какая память вот прямо "хардкодом". В общем, там одни тонкости. И отлаживать этот код не то чтобы легко (памяти-то нет).

Поэтому желающих это писать самому обычно немного.

Как по мне, на ассемблере реально низкоуровневые вещи писать зачастую проще, чем на тех же сях. Для себя обычно на нём и пишу, а вот что по работе -- на це/це++, чтоб не я один мог понять, что там делается :)

Слушайте, но вопрос решается просто. Возьмите, скажем не Intel. Возьмите пороще. Даже не aarch64, всего-то arm-v7. Тот же IMX6, допустим.

Там спецификация по регистрации, но вполне доступна (не из России, конечно). Потом прицепите к нему одну из множества разрешенных типов RAM (там, вроде бы DDR2, DDR3, DDR3-L в самых разных конфигурациях по части банков памяти - но могу ошибаться). На которые тоже вполне открыта спецификация. Потом изучите особенности BOOTROM, в части загрузки с одного из носителей (SerialFlash, SD-карта, eMMC, NAND - вроде на этом все). Остается дело за малым - написать код, который там в семь шагов вроде бы, каждый из которых разбит на три-четыре подшага. Потом подберите или вычислите специфичные для конкретно взятой платы (а именно ее трассировки) задержки распространения и несимметричность линий данных. И молитесь, чтоб ни на одном шаге не случилось ошибки. Ну и при производстве все было гладко - в том смысле, что текстолит нормальный, оборудование не врет, монтаж на уровне, и трассировщики сделали необходимые зазоры по всем параметрам. Документация на процессор - около 2К страниц, из них контроллер DDR страниц 100. Документация на чип DDR3 - еще около 1К. Читать не перечитать, считать не пересчитать.

Или возьмите там же XLS файл, куда вбиваются данные их спецификации выбранной микросхемы, получите набросок конфигурации в виде CSV - регистр-значение. Загоните его с помощью фирменной утилиты через USB в готовую плату вместе с фирменной утилитой, которая погоняет это на всех частотах сутки-другие, и выдаст итоговые регистры. Или выдаст косяки трассировщиков - кто не безгрешен? Но через несколько итераций, возможно с переделкой платы, получите готовые регистры. Которые просто надо вбить в те самые семь шагов. В том же U-Boot'e.

Все можно руками. Никто не говорил что нельзя. Просто целесообразность этой работы сомнительна. При том же итоговом результате.

И это IMX6. А если взять, допустим IMX8, то там все сложнее. Что уж говорить о DDR5 у Intel'а. Особенно зная весьма специфическое отношение Intel к документации. Одна ее иерархия займет отдельную книжку, страниц этак на 100. Да и не Intel'ом единым. Rockchip вообще ничего не раскрывает. Опять же - на входе референсный бинарь и текстовое описание микросхем и особенности трассировки. На выходе бинарь, который надо просто разместить в нужном месте на загрузочном накопителе. Типовая практика, к сожалению. Или к счастью. Это как посмотреть.

Все можно руками. Никто не говорил что нельзя. Просто целесообразность этой работы сомнительна

Вот как раз было сказано про "практически невозможно", что и вызывает, так сказать, большие сомнения. А не про то, что целесообразно и тем более не про то, что "это элементарно, Ватсон"

Право слово, прежде чем ловить оттенки смыслов стоит раз-другой попробовать. И только потом для себя решить какой из терминов использовать "практически невозможно" или "нецелесообразно". В конечном итоге это синонимы. С разным смысловым оттенком, но синонимы. Я вполне согласен с любым из них.

А что до "Элементарно, Ватсон" - так не боги горшки обжигают. Каждая новая задача кажется невыполнимой, а каждая пару-тройку раз повторенная элементарной. И вся жизнь всегда состоит из рутины элементарных задач и гор невыполнимых. Просто задачи у всех разные. И часть из них только с первого взгляда кажутся достаточно простыми и понятными. Ровно до тех пор, пока их решать не придется.

Представьте себе, пробовал. И даже работало. В том числе на упомянутом Вами iMX6 с DDR3. Вот с DDR4 и более поздними не доводилось и вряд ли доведётся, да и особого желания нет: общие идеи и так понятны, а зарываться в специфику очередного проца и прочая нецелесообразно, да и сами такие процы мне не нужны ни по работе, ни для личного удовольствия.

Вопрос скорее риторический. Почему производители плат не открывают исходники этих блобов? Я совсем не понимаю, какая там может быть коммерческая тайна, зарабатывают то не на этом. Наоборот, открытые исходники сделали бы плату популярнее, сообщество исправило бы имеющиеся баги.

Подозреваю, что это не производители матерей, а производители процов (и чипсетов).

Да, конечно. Неправильно выразился.

Вожусь периодически с одноплатником на mtk. MTK выложили в репозиторий на гитхабе почти все исходники, кроме инициализации (скорее доинициализации, т.к. это уже bl2) DRAM. Его объектным файлом положили.

Поэтому желающих это писать самому обычно немного.

Так много и не нужно, насколько я понимаю. И уж точно для мотивированного человека ассемблер не проблема, если есть спецификации. В своё время самые обычные люди писали в машинных кодах, рисуя карандашом двоичные разряды в ячейки, нарисованные на бумажных простынях. Всё относительно.

Ведь когда нет памяти, то и стека нет. А без стека, например, язык Си работает не очень хорошо (скорее не работает).

Это не совсем так. Маленький кусочек статической памяти всегда есть на всех современных СнК, именно для целей инициализации аппаратуры, в том числе DDR контроллера. Но в целом Вы правы, процедура инициализации современной DDR памяти (SDRAM training) представляет собой черную магию и часто является проприетарным куском кода от создателей DDR контроллера. Так как у компании ЯДРО нет своего функционального блока DDR контроллера, то скорее всего и исходников DDR INIT тоже нет. :)

У интеловских (или АМДшных) процов вполне может и не быть памяти; я и раньше встречал, что в качестве ОЗУ на время первых этапов инициализации используется кэш. Технически это вполне осуществимо, если кэш можно настроить в таком режиме. Более того, этих десятков мегабайт кэша вполне достаточно, чтоб запустить какую-нибудь там WinNT, только, скорей всего, DMA не будет работать чисто с кэшем, ему почти наверняка полностью инициализированную обычную память подавай :)

Вообще-то, не совсем так. В большинстве современных ПК классический BIOS объединён с современным UEFI, поэтому может прикидываться хоть тем, хоть другим в зависимости от того, какая система загружена.

Не совсем так. Есть compatibility support module (CSM). Он вот как раз и отвечает за поддержку Легаси. Это бинарь, который копируется на место Биоса + пачка драйверов uefi. DOS грузится как раз благодаря этому CSM.

Вообще-то, микропрограмма -- это то, что управляет работой процессора, если он с микропрограммным, а не жёстким схемным управлением. BIOS же -- самая что ни на есть программа, и то, что она сидит не в ОЗУ, а в ПЗУ, не делает его микропрограммой. Думается, на русском языке лучше содержимое ПЗУ BIOS всегда именовать прошивкой.

Да, тут косяк с терминологией. Спасибо! :)

BIOS IBMовских персоналок не был закрытой разработкой. Исходник BIOS для IBM PC, например, опубликован в Technical Reference Manual на этот компьютер.

Вот это уже не застал, поэтому про опубликованные исходники не в курсе...

Хм... Почему это его "практически невозможно реализовать самостоятельно", если спецификации имеются?

Ну, тут вопрос в трудозатратах. В контексте того, что взять и написать полностью свободную прошивку для x86 крайне тяжело. Тот же coreboot содержит тот же закрытый код в виде бинарей FSP, которые Интел выкладывает.

Вообще, SMM -- это жуткий костыль, придуманный для того, чтоб управлять электропитанием ранних компов в условиях, когда ОС этим заниматься не умела (впервые появился в 80386SL).

Ну, тут согласен, но так исторически сложилось. Есть штуки типа Platform Runtime Mechanism, но в массы ещё не пошло.

А синяя коробка поддерживает точки останова, покомандное выполнение и всё такое прочее, что доступно в обычных программах с помощью обычных отладчиков?

Ага, это JTAG там фактически.

требует больших объемов закрытого кода, из-за чего его практически невозможно реализовать самостоятельно, даже если у вас есть все необходимые спецификации

А они вообще есть? Особенно на всякие интловские ME и амдшные PSP.

Ну то есть coreboot с блобами, а у всяких libre/gnuboot и открытых seabios в списке поддерживаемого оборудования самое новое лет 15 назад с производства снято.

И baremetalный "hello world" (без uefi), чтобы прямо из spi flash, невозможен сегодня на современном х64 железе впринципе? Для какой-нибудь более специфичной железки у которой аппаратная конфигурация заведомо определена раз и навсегда, распаяна и меняться никода не будет.

Товарищи из Yadro как всегда молодцы. Не то, чтобы что-то фундаментально новое и интересное, но всё в одном лонгриде - теперь это редкость.

От себя скажу так - EDK II сложна не кодом. Она сложна своей системой описания платформы и сборки. Десяток конфигурационных файлов с кросс-вложениями и не самой лучшей документацией. Вот бы это кто хоть крупными мазками. Чтобы этакий "Hello, world!" для абстрактной платформы. Так чтоб понять минимум и методы его наращивания.

Есть желание сделать UEFI для своих процессорных модулей с aarch64, но пока приходится обходиться по старинке - U-Boot/Barebox. Боюсь моих сил не хватит, на то чтоб осилить эту задачу. Но стремиться мне никто запретить не может.

Ещё раз спасибо. Было интересно и познавательно.

DXE часть можно брать из edk - там почти все что надо есть. Вот с начальной загрузкой SEC и PEI самая проблема, критичное железо не инициализировано и оно должно там инициализироваться, а средств отладки в это время кот наплакал.

Есть желание сделать UEFI для своих процессорных модулей с aarch64,

Я радикально не понимаю в чем прелесть UEFI и предпочитаю старый добрый UBoot. На мой взгляд UEFI это троянский конь который непонятно чем занят.

Ну и отлично. Очень многое зависит от того, что именно представляет собой ваше конечное изделие. Если это "черный ящик" с заданным функционалом - роутер, телевизор, ТВ-приставка, станок или что-то подобное - то в принципе достаточно U-Boot. Да, будет некоторой риск окирпичивания при обновлении прошивки, но не факт что это обновление вообще будут делать.

Другое дело, если вы замахиваетесь на ПК общего назначения. Куда любая домохозяйка должна иметь возможность установить хоть Windows, хоть Ubuntu с Gentoo, хоть FreeBSD с Астрой, хоть Android с Авророй. При чем с помощью флешки от производителя операционной системы. Да в режиме мультизагрузки в любом варианте. Вот тут UEFI с ACPI начинает рулить. Его за то производители осей и любят.

По остальным частям - непонятно чем занят как раз и раскрывается данной статьей. И весьма неплохо раскрывается. А про троянского коня... Скорее всего это не про UEFI, а про IME (Intel Management Engine) или её аналоги. Другое дело, что появление обоих технологий было более или менее синхронизировано по времени, но каждая из них вполне самостоятельна.

В современных армах место IME занимает ATF/TEE, который является частью стадии загрузки. Неважно Uboot у вас или UEFI, в него в попадаете только после ATF.

Ну, в общем случае это не так. Другое дело, что есть известная присказка: "Колхоз - дело добровольное. Хочешь - вступай. Не хочешь - расстреляем!" Так и тут. Оба компонента не обязательны. И в принципе без них можно обойтись. Вот только не очень хочется. Да и "современные армы" - уж очень широкое определение.

Наш BIOS, основанный на EDK2, поддерживает кроссплатформенную сборку.

ну прямо прорыв в импортозамещении, не иначе))) целый свой bios сделали)))
как обычно на словах все гладко, а на деле просто небольшой плагин пилим для импортной ОС работающей на импортном железе, с помощью импортного инструментария разработчика...

в целом понимание происходящего на уровне не только лишь все, мало кто может... как вообще можно BIOS основать на development kit-е... как вообще что-то можно основать на наборе инструментов? набор инструментов может помочь что-то создать... но основать на наборе инструментов...

и это не единственное подобное мыслеизлияние в этом тексте... и все это просто кричит о нехватке компетентных людей, уровне экспертизы и понимания того, что они вообще делают.

Если каждый день кричать на каждом углу что ты сделал все сам, то тебе рано или поздно поверят

Да, хабр окончательно скатился до уровня инфопомойки... и теперь не отличается от бОльшей части интернета.

На скриншотах ниже — прошивка нашего сервера, которая открыта в утилите UEFITool. Эта утилита разработана нашим соотечественником (@CodeRush, спасибо за утилиту 🙂). 

@serg_blackout, пожалуйста.

Молодцы, что не стали пользоваться услугами IBV, а решили все делать сами на базе "голого" EDK2. После определенного опыта работы со всеми тремя платформами, которые нынче предлагают IBV (AMI AptioV, Phoenix SCT, Insyde H2O) - это лучшее решение, к которому пришли в свое время и Apple, и Microsoft.

По поводу однопоточности - уровень использования CpuMpProtocol зависит от вас самих, и никто не мешает на AP (ядрах, которые не являются BSP) запускать что угодно, с любой степенью параллелизма, Qualcomm вон вообще запускает свою RTOS на всех ядрах, и компоненты традиционного UEFI запускает уже из нее как приложения, а SMM (который теперь официально называется просто MM, потому что к архитектуре x86(-64) сама идея Management Mode имеет мало отношения) реализует через TrustZone.

После десятка лет работы с UEFI я все сильнее соглашаюсь с @checkpoint, но не в смысле "троянского коня" (не приписывайте злой умысел тому, что можно объяснить глупостью), а в смысле "UBoot или любая другая более простая альтернатива UEFI PI, реализующая UEFI как интерфейс - строго лучше, чем любая прошивка, основанная на EDK2". Дело в том, что современный EDK2 (а сейчас у нас 2025 год) заметно отягощен решениями, которые Intel принимал в 1998 году, для процессора, который уже и не выпускается, и не поддерживается, принятыми людьми, которые до этого занимались разработкой драйверов для Windows NT. С тех пор воды утекло заметно, и системное программирование развилось заметно, а в EDK2 продолжают заниматься поллингом на одном потоке, танцами вокруг TPL, передачей управления хрен знает куда вместо человеческого IPC, загрузкой сотни драйверов по одному в цикле, пока нечего станет загружать, наглухо отбитым интерфейсом к NVRAM (API so nice you have to call it twice), плохо прикрученной через 13 лет безопасной загрузкой, и т.д. и т.п.

Понятно, что любые альтернативы - это отличный способ снова прогуляться по всем граблям разработки системного ПО, но в текущем виде продукт, основанный на EDK2, и при этом радикально не переделанный в сторону уменьшения влияния особенностей EDK2 на него - не может быть ни быстрым, ни безопасным, ни простым в отладке. Когда Apple выкинули MacEFI в пользу iBoot на машинах с Apple Silicon - жить стало лучше и веселее, то же самое сделали ребята из Oxide, и теперь у них отличная прошивка, написанная в основном на Rust, которая их здоровенное облако-на-сервере загружает за пару секунд.

С другой стороны, я очень рад, что в России появились люди, способные не только АПМДЗ в AMI AptioV внедрять, но и реализовывать работающие серверные прошивки для разработанного ими же железа, а потом об этом еще и статьи нормальные писать. Так держать!

... в смысле "UBoot или любая другая более простая альтернатива UEFI PI, реализующая UEFI как интерфейс - строго лучше, чем любая прошивка, основанная на EDK2".

Есть одна проблема. Описание платформы. ACPI точно не лишён недостатков. И не каждый производитель считает нужным вчитываться в эту спецификацию. "И так сойдёт" - это прямо повсеместно. Но и DTB - это полная анархия. Там всё настолько платформо-специфично, что просто кошмар. Шансы на то, что U-Boot каким-то образом правильно сделает ACPI ничтожны, а без него и UEFI как таковой мало интересен.

Во всяком случае так ситуация выглядит с моей колокольни и на сегодня.

Опыт показывает, что и DT можно сделать нормально, и ACPI можно зафакапить так, что устанешь ядро патчить.

ACPI, вообще говоря, ортогонален UEFI (хоть теперь и управляется одними и теми же людьми), тем более EDK2, и потому относительно независимую реализацию ACPI сделать не мешает ничего, кроме дороговизны мероприятия.

Более того, я теперь попробовал хорошие альтернативы ACPI, а не только тот русский рэп, который предлагают всякие человеки-эмбеддо-свиньи (не в обиду нормальным эмбеддерам), и могу сказать, что идея "давайте абстрагируем платформу до такого состояния, чтобы любую ОС можно было прямо как есть переносить с любого ПК на любой другой" - она такая же глупая и нежизнеспособная, как и обратная ей идея "нахер вообще вам переносимость, собирайте кастомное ядро под каждую ревизию платы". ACPI - это реально очень удобно, когда работает, но зачастую оно не работает, и работать начнет примерно к ишачьей пасхе, а должно бы уже вчера. В том числе поэтому вместо нормального сопроцессора безопасности у нас в обычном ПК хорошо если есть TPM 2.0, а зачастую и вообще ничего нет, и приходится ходить на костылях там, где можно было ехать на Синкансэне.

ACPI - это реально очень удобно, когда работает, но зачастую оно не работает

Эм... Что, даже на обычных "серийных" ПК до сих пор с ACPI проблемы бывают?

Да, бывают. И сильно чаще, чем хотелось бы. Другое дело, что стараниями разработчиков осей и драйверов их не очень видно конечному пользователю.

Да и что считать за обычный "серийный" ПК. Ноутбуки, например, почти поголовно имеют те или иные проблемы. Но опять же - они обычно довольно неплохо спрятаны.

Надежда умирает последней (c)

Я, когда ковырялся с ранними реализациями ACPI (чисто для собственного удовольствия, моя работа никогда с подобным связана не была), регулярно натыкался на багоглюки, но надеялся, что в будущем вылижут-таки всякие косяки. В общем, наивный чукотский юноша (ещё один (с))

Но, вообще говоря, удручает, что такое огромное количество ошибок сохраняется в совершенно базовых вещах (типа длиннющих Эррат на микроконтроллеры, причём многие ошибки не исправляются годами и переносятся в новые модели). Ощущение такое, что развитие идёт... в неправильном направлении. Погоня за сиюминутной выгодой, "и так сойдёт" и т.д. и т.п. Но это уже философия.

Ну а "серийный" -- обычный, не имеющий каких-то особых требований и особого набора железа на борту. Грубо говоря, берёшь эталонную реализацию от разработчика процессора, добавляешь пару светодиодиков (непременно разноцветных для подсветки системника!), клеишь свой лохотип и продаёшь.

Банально: (https://dortania.github.io/Anti-Hackintosh-Buyers-Guide/Motherboard.html#usb)

Special AMD Note: Due to how macOS builds USBs, they must be defined somewhere in the ACPI tables. For some reason, many AMD boards just forget to do this and users end up with a lot of broken USB ports. There is a fix but it involves manually adding the ports to the DSDT or SSDT (opens new window).

Одновременно меня поражает, сколько разных SKU плодят производители: обзор по "50" материнкам Intel Z890: https://www.youtube.com/watch?v=GxzMtPmjG_M. Больше половины видео только перечисление характеристик, в конце данные по взятой памятью частоте и VRM.

Тут поддержку 16 битного кода в виде CSM до сих пор не выпилили из биосов! О каком прогрессе может после этого идти речь.

Дык совместимость же...

Вендоры, которые разрабатывают Option ROM для PCIe-устройств, также могут создавать свои меню. Их легко интегрировать в BIOS, и меню будут выглядеть чужеродно.

Ещё маленький косяк обнаружил при более внимательном прочтении: надо полагать, меню не будет выглядеть чужеродно.

Спасибо за внимательность) Поправили!

Sign up to leave a comment.