Pull to refresh

Comments 58

Справедливости ради у прикладных процессоров всегда все плохо с документацией (даже если вы получили под NDA). Но писать под православный Эльбрусий или вот под x86 это отдельный садомазо. Если вы даже не знаете сколько и каких процессорных ядер у вас на материнской плате или даже не знаете истинную систему команд, ведь x86 уже давно RISC, а не CISC.
Под ARM уже можно найти драйвер GPU и софтверный DSP камеры в исходниках. А здесь блоб на блобе и блобом погоняет.
Я считаю, что жизнь слишком коротка чтобы работать без документации, без исходников и становиться специалистом по вендор-локам.

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


К счастью, это просто хобби :)

даже не знаете истинную систему команд, ведь x86 уже давно RISC, а не CISC

Как это влияет на программиста?

Под ARM уже можно найти драйвер GPU и софтверный DSP камеры в исходниках. А здесь блоб на блобе и блобом погоняет

Честно говоря, не понял о чём вы. И на arm, и на x86 есть системы как с blob, так и без них.

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


И, как я понял, именно по этой причине у вас изначально не запускалась та маленькая плата с ROM для расширения BIOS?

О копировании в оперативную память даже не догадывался.

Самое удивительное, что нигде не встречал даже описания по этому поводу. А главное, как такое дебажить.

И, как я понял, именно по этой причине у вас изначально не запускалась та маленькая плата с ROM для расширения BIOS?

Именно поэтому не работал BASIC-ROM, он просто не мог работать.

Тогда понятно. Просто я помнил, что он виделся в памяти, но не стартовал...

Самое удивительное, что нигде не встречал даже описания по этому поводу. А главное, как такое дебажить.

Да ладно вам. BIOS RAM SHADOW - загадочный пункт в 486-ых и первых пентюхах. Прямо в описании на материнскую плату. Да и во всяких прочих источниках.

А вот про код, который непосредственно из ROM... Это да - надо уметь. Особенно когда RAMа еще вообще нет, а значит нет даже стека и располагаем мы только регистрами...

Впрочем, не знаю как там про современный gcc, но Borland троечка в свое время умел... Полагаю и gcc умеет, но надо много доков перерыть. Что-нить в стиле __attribute__((naked)) чтоб стандартную преамбулу со стеком не включать.

В современных биосах используется технология CAR(cache as ram), которая инициализируется практически сразу после самого старта, а дальше обычный Си.

Спасибо, буду знать... Я нынче очень далек от мира x86, а все мои ARMы имеют на борту небольшое количество SRAM. Потому проблемы "кода из ROM" давно не встречал.

Да ладно вам. BIOS RAM SHADOW - загадочный пункт в 486-ых и первых пентюхах.

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

В coreboot (это проект по разработке свободного BIOS) есть компилятор romcc, который генерирует машинный код, не использующий оперативную память.

Спасибо за ценнейший комментарий.

Да ладно вам. BIOS RAM SHADOW — загадочный пункт в 486-ых и первых пентюхах.
BIOS RAM SHADOW появился уже в 386, если не в 286. А всё потому что ROM это очень медленно, и программы которые активно использовали функции BIOS ощутимо так тормозили. И чтоб победить эти тормоза, BIOS копировал себя в блок RAM, отключал ROM и командовал чипсету переключить этот блок RAM в адреса ROM. Попутно чипсет мог запретить запись в этот блок, а мог и оставить её открытой для записи. ;)
Именно так, разрешением записи в верхние блоки RAM, можно было организовать UMB без EMM386.
А вот про код, который непосредственно из ROM… Это да — надо уметь. Особенно когда RAMа еще вообще нет, а значит нет даже стека и располагаем мы только регистрами...
MRBIOS, если мне не изменяет память, при своей инициализации (когда оперативная память еще не была активна) использовал регистры DMA контроллера для хранения переменных.

У меня есть провал с 286-ми. PС-XT в техникуме, 386-е, 486-ые, программирование РФ ПЗУ на ЕС-1841. И свои первый был 486ым. Я не помню этого пункт в BIOS "трешки". Это, безусловно, не говорит о том что его там не было.

"Код из ром" впервые возник в контексте "Питерской телефонии". Тогда окучивали i386ex в части замены им привычного 186-ого и столкнулись с тем, что уже хочется использовать защищенный режим и писать без оглядки на сегменты, но при всем при этом стартуем-то мы по прежнему из ПЗУ и ОЗУ надо еще правильно проинициализировать. Впрочем, тогда я не программист. Скорее схемотехник с уклоном во взлом демоверсий софта для разработки. Но все работали в одной комнате и курилка была общая. А молодой и любопытный организм как губка - впитывал все.

У меня есть провал с 286-ми. PС-XT в техникуме, 386-е, 486-ые, программирование РФ ПЗУ на ЕС-1841. И свои первый был 486ым. Я не помню этого пункт в BIOS «трешки». Это, безусловно, не говорит о том что его там не было.
Навскидку поиском изображений в Яндексе «AMI BIOS 386DX»
image
По запросу «ami bios 286»
image
А ещё можно скачать PCEm с ROM-ами и насладится их видом и настройкой BIOS
image
Тогда окучивали i386ex в части замены им привычного 186-ого и столкнулись с тем, что уже хочется использовать защищенный режим и писать без оглядки на сегменты,
Это уже был не защищённый (protected) режим доступный с 286, а virtual 8086 mode (он же virtual real mode, он же V86-режим, ещё известный как VM86) святой грааль программистов DOS эры, страстно желавших вырваться за пределы сегмента в 64кб. Но информации по программированию в этом режиме, было реально крупицы, как говориться пара абзацев на последних страницах толстого тома по 386 процессору. :(
Это уже был не защищённый (protected) режим доступный с 286, а virtual 8086 mode (он же virtual real mode, он же V86-режим, ещё известный как VM86) святой грааль программистов DOS эры, страстно желавших вырваться за пределы сегмента в 64кб. Но информации по программированию в этом режиме, было реально крупицы, как говориться пара абзацев на последних страницах толстого тома по 386 процессору. :(


Кулаков В. Программирование на аппаратном уровне: специальный справочник



Очень подробно описывает, и почти вся книга в этом режиме работает.

В те времена издательства "Питер" ещё не существовало. :(
Опять же, ЕМНИП назывался этот переводной том "Архитектура и программирование процессора 386", и вроде был издан издательством "Статистика". И в библиотеке политена этот том находился в перманентном состоянии "на руках".

Но информации по программированию в этом режиме, было реально крупицы, как говориться пара абзацев на последних страницах толстого тома по 386 процессору. :(

То были славные времена, когда пусть и под NDA, но можно было найти информацию о самых последних новинках. Siemens тогда еще был Siemens'ом а не Infenion'ом, Harris был Harrisom а не Intersil'ом, Motorolla была одним из крупнейших игроков, а Mitel практически безоговорочно лидировал в новых разработках и вообще был совсем на коне в частности как производитель чипов (не безызвестная своим эротическим именем minet.dll в Windows это их приветы).

В те славные времена мы разжились (дай бог памяти - в Питерской Гамме вроде) двумя дисками от Intel. Как раз в связи с желанием приобрести некоторое количество 386ЕХ'ов. Один был полностью про embedded и содержал отличную документацию, которую в последствии неоднократно цитировали и пользовались как справочником. В частности тема режимов работы процессора была расписана просто отлично и скорее вопрос был в компиляторах C, которые могли бы плодить код для того или иного режима (да всяких exe2bin, которые могли бы "вытащить" бинарь для прошивки в ПЗУ станции). Сейчас любая objcopy так умеет, а тогда... И да - вне этого диска информации было крайне мало, а издательство "Питер" только начинало свою работу и печатало откровенную дичь типа перевода мануалов (хорошо как не Prompt'овского перевода). Второй диск был посвещен коммерции. Все тогда популярные чипсеты с подробной документацией. Нам, правда, именно он был совсем не интересен.

Но еще раз повторюсь. Я тогда планомерно работал над тем, чтоб из "курьера, а по совместительству монтажника-настройщика РЭА" превратиться в разработчика. Осваивал схемотехнические CAD'ы (а тогда PCAD 4.5, самые модные смотрели на PCAD 6, но пользоваться им не решались). А у меня в фаворе OrCAD для Windows 3.1 - первый "человеческий" схемотехнический CAD, гербера из которого вполне брало производство. Ну и всякие софтинки... Спасибо нодам, дававшим доступ к Fido (2:5030/666 - если вдруг меня читают) и Крису Касперскому с его учебниками... FlexLM до сих пор ничего кроме легкой ухмылки не вызывает - ибо "математикой" ломать почти не возможно, за то методом " грубого хака" или патча - за пару минут.

А поскольку помимо всего прочего прошло 30 лет... Что-то могу не помнить или помнить не правильно.

В 386 был, потому что помню на ассемблере переписывал 21h прерывания на свои.

Кажется в CoreBoot был компилятор C, генерирующий код, не использующий память. Как раз для ее инициализации.

UPD: Я буду читать комментарии, я буду читать комментарии....

UPD: Я буду читать комментарии, я буду читать комментарии....

Для меня комментарии были очень ценны.

Из интересного на счёт скриптов ld.

http://books.gigatux.nl/mirror/kerneldevelopment/0672327201/ch10lev1sec3.html

В linux линкером наложили 32 и 64 битный счетчики друг на друга.

Ну хз, когда в девяносто лохматом у меня был 386, там уже был Shadow ROM. И эта зараза отъедала какое-то количество "расширенного ОЗУ" (около 40кб). Для винды рекомендовалось эту опцию отключить в биосе, т.к. там дрова 16-битного реального режима, и винда ими не пользовалась. А вот для доса скорее помогало.

Ну хз, когда в девяносто лохматом у меня был 386, там уже был Shadow ROM.

Век жив, век учись

Помню на третьем пне у меня был пункт Bios Cacheable что видимо тоже схоже по функционалу.

Это немножко другое, ЕМНИП это разрешение чипсету использовать в этом регионе кэш-память процессора.
Shadow ROM народ массово отключал во времена выхода DOOM, чтобы DOOM-у хватило памяти для запуска. ;)

насколько я помню в старых стартап кодах, было в некоторых режимах выделение рам области, копирование туда переменных, потом только запуск main.

а почему вспомнил - смотрел стартапы для cosmic компилятора stm8 и stm32, и тот код напомнил то, с чем сталкивался в начале 90х, до перехода на Windows-NT 3.51 и 4.0 и Vax/VMS.

не помню, на каком компиляторе я сталкивался с таким кодом.

почитал комментарии, возможно с внедрением ShadowRam в биосе убрали возможность работы даже без озу совсем. надо попробовать на 80286 маме.

Да, и надо тогда проверять наличие памяти, т.е. выполнять memory test

Насколько помню, копирование ROM в RAM появилось в замечательном, прямо таки революционном чипсете для 286 процессора: Chips&Techologies NEAT в далеком 1988 году.

https://en.wikipedia.org/wiki/NEAT_chipset

Там внизу есть ссылки на документацию. Технология называлась Shadow RAM и реализуется в чипе контроллера памяти 82С212.

"The Shadow RAM feature allows faster execution of code stored in EPROM, by downloading code from EPROM to RAM. The RAM then shadows the EPROM for further code execution. "

Производителям мамок на чипсете C&T и биосо-писателям давался "кит" с примерами, как правильно программировать чипсет.

Да ну. В bios для 286 даже была такая опция - "использовать Shadow memory".. или типа того, сейчас не вспомнить

“shadow memory” – это так называемая “теневая” память. В адресах памяти от 640 КБ до 1 МБ (a0000h – fffffh) находятся “окна”, через которые “видно” содержимое различных системных ПЗУ. Например, адреса f0000h – fffffh занимает системное ПЗУ, содержащее bios системы, окно c0000h – c7fffh – ПЗУ видеоадаптера (видео-bios) и т.п. При включении режима “shadow” для каких-либо адресных диапазонов, соответствующих системным ПЗУ либо картам расширения, содержимое их ПЗУ копируется в участки основной памяти, которые затем подключаются к этим же адресам вместо ПЗУ, “затеняя” их.

UFO just landed and posted this here

Это очень интересно! Пожалуйста, напишите!

UFO just landed and posted this here
это никому не интересно

Если хорошо написано это всегда интересно почитать. А так всегда кто то спрашивает а зачем вам X когда есть Y.

Нынче имеются "убежавшие" (пссс...) исходники MS-DOS примерно beta 6.xx . Можно посмотреть, как многие вещи реализованы на самом деле, в частности мифический DOS List-of-Lists.

Тоже когда-то писал свой BIOS :) Тогда кроме coreboot'a очень помогли статьи Pinczakko's Guide to BIOS Reverse Engineering.

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

Почему не C++?

Думаю как бы вежливее ответить.

Есть ли проект ROM BIOS на плюсах? И вообще, много ли проектов под железо на плюсах (ардуино не берём, это скорее недоразумение). Ничего не имею против языка, но он избыточен для этой задачи. Ну и плюс, я его не люблю.

Есть ли проект ROM BIOS на плюсах?

Не знаю, но не вижу ни одной причины, по которой не следовало бы их делать.

много ли проектов под железо на плюсах

Для современных МК (того же STM32) - достаточно, ибо это и удобнее, и надежнее, чем на чистом C.

ардуино не берём

И совершенно зря. Я несколько лет назад развлекался, переписывая программки для ATTiny13 с C на C++, применяя наследование, виртуальные функции и шаблоны, и получая идентичный (с точностью до мелких различий в CRT) двоичный код. Нескольких знакомых разработчиков для МК на это подсадил. :)

он избыточен для этой задачи

В каком смысле "избыточен"? Слава богу, даже современные компиляторы C++ не вставляют неявных вызовов функций CRT для подавляющего большинства возможностей языка, а код почти всегда получается идентичным аналогичному по смыслу коду на C. Если вдруг кто-то заявит, что программирование на C++ непременно подразумевает использование контейнеров std, исключений, многоярусных шаблонов и прочего - плюньте ему в глаза, и дело с концом. :)

Там, где на C Вы определите структуру и набор функций для работы с нею, на C++ Вы определите ту же структуру в виде класса, и те же функции в виде методов, но при этом сможете задать ряд ограничений и автоматизмов, которые на C придется делать вручную, а двоичный код все равно будет одинаковым. Если какие-то структуры расширяют уже существующие, на C++ Вы просто определите производный класс, и за правильностью преобразования указателей/ссылок будет следить компилятор, а на C это придется делать руками, вылавливая ошибки только на стадии выполнения. Даже более строгие ограничения на преобразования типов помогают избежать ряда ошибок.

А возможность создания временных объектов "на лету" (в стеке) очень удобна для отладки, чтобы выводить в лог в разных форматах. Тут уже код получается не самый оптимальный, но для отладочных вариантов сгодится.

я его не люблю

У меня была неприязнь к C++ в начале 90-х, когда на фоне компактного, быстрого и очень удобного TC 2.0 пытался освоить TC++ 2.0, который был значительно более тормозным, а сам язык тогда изобиловал подводными камнями. Не последнюю роль сыграла и тогдашняя массовая практика - "в программе на C++ положено использовать множественное наследование, виртуальные функции, исключения, сложные шаблоны и прочее, иначе это нецелевое использование языка". :)

А вот MS VC++ 4.0 как-то сразу зашел, я на нем довольно долго писал виртуальные драйверы ядра (VxD) для Win9x, которые традиционно было положено писать только на чистом C.

Каждый кулик своё болото хвалит. Но правда ваша есть в этом.


Но не спроста всё низкоуровневое пишут на сях, linux, BIOS, uefi. Причина проста, код на сях проще отлаживать чем на плюсах. На плюсах прекрасно писать, но отлаживать, а особенно легаси — это адовый ад. Поэтому большие проекты часто на си. И, к моему счастью, это будет долго.

Объективная причина писать на сях только одна - отсутствие адекватного компилятора под платформу. Остальные - или привычка, или религия. :)

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

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

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


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


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

быстрая разработка, шикарная работа со строками

Вы плюсы с питоном не путаете? :-)

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

Мне вот последнее время платят деньги за подпиливание мелких фишек в древнем софте. Один - на сях, второй - на плюсах. И вот плюсовый на порядок лучше структурирован.

Настоящий ад в легаси

Не может там быть никакого ада лишь потому, что компилятор работает в режиме C++, а не C. Вот есть у Вас программа на чистом C, отлаживать которую Вам легко и приятно. Вы переименовали файлы из .c в .cpp и обработали их в режиме C++ (тут, возможно, придется подавить ряд предупреждений, ибо в C++ более строгие правила преобразования типов). Должен ли с этого момента начаться ад? Если да, то почему?

Далее, у Вас в программе на C есть структура, с которой работает несколько функций. Вы переносите объявления этих функций, сделанные в виде обычных прототипов, внутрь определения структуры (можно даже пока не менять struct на class), в определениях этих функций добавляете квалификатор - имя структуры/класса через "::", убираете из параметров указатель на структуру (это будет неявный this), а из тел функций - этот указатель с "->" для обращения к каждому полю. Все, у Вас получился класс и методы (функции-члены) работы с ним. :) В вызовах этих функций меняете "func (strptr, ...)" на "strptr->func (...)", и вуаля. :).

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

В каком месте здесь возникает ад? Все остается таким же, как и было, ничто не теряется, но добавляется автоматизация контроля - как синтаксиса, так и поведения. Неужели это не имеет для Вас ценности?

Плюсы имеют много крутых преимуществ: быстрая разработка, шикарная работа со строками

То, что Вы перечислили - это не плюсы. Это то, что их обычно сопровождает - стандартная библиотека шаблонов и функций, фреймворки и т.п. Там почти все, кстати, сделано на плюсах же.

Собственно плюсы - это именно ядро языка, базовые возможности, реализуемые на уровне компилятора, а не внешних средств.

ещё чел писал как ему было удобно

Напиши он в том же стиле на C - было бы легче?

Не стоит его пихать везде, особенно там где он не нужен от слова совсем

А если я Вам предложу в программах на C избавиться, например, от условной операции, цикла for, модификатора const и еще чего-нибудь, поскольку без всего этого можно обойтись - а значит, оно и не нужно "от слова совсем"? :) Где провести границу между полезным и бесполезным,и как ее обосновать? Я вот когда-то писал огромные программы на ассемблерах, и искренне считал, что и C на фиг не нужен... :)

Вы не поняли о чём я, но уже начали что-то доказывать.

Значит, Вы не сумели донести свою мысль. То, что Вы подаете, как недостатки C++, на самом деле не имеет к нему никакого отношения.

Лет 20 назад был у меня проект под AVR на плюсах. Там работа с разными похожими индикаторами была сделана через полиморфизм - для core модуля это всегда выглядело одинаково, а функции вызывались для каждого индикатора свои. Было довольно удобно. Потом на основе этого же кода был написан эмулятор, который работал на PC и за интерфейсом индикаторов скрывалось уже графическое окошко на WinAPI.

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


Меня скорее удивляет вопрос: а почему это, а не то? Почему синее, а не красное, почему си, не си плюс плюс? Ну люблю я синее больше.

пока в основном рулит си

Я уже пояснял, почему - исключительно в силу привычки и ложных представлений. Вот как у Вас. :) А объективных, не зависящих от личных предпочтений, доводов в пользу чистого C просто нет, ибо C++ его и полностью перекрывает, и нигде не ущемляет.

мне не очень нравится объектно-ориентированное программирование

То есть, в Ваших программах все переменные определены россыпью, без группировки, и нет ни одной структуры, для работы с полями которой написаны специальные функции, в которые передается указатель на структуру? Если такое есть, то у Вас самое, что ни на есть, объектно-ориентированное программирование. :)

Почему синее, а не красное, почему си, не си плюс плюс?

Потому, что красное не содержит в себе синего, а C++ содержит в себе C. :)

Более того, я в программах на си пихаю указатели на функции в структуру. Но тем не менее, я сторонник лампового си.


C++ содержит в себе C.

На первый взгляд только. И это заблуждение.


Я уже пояснял, почему — исключительно в силу привычки и ложных представлений.

Это ваше заблуждение.

И это заблуждение

Аргументы будут?

Потому что для этого придумали С--.

Вот если б придумщики C-- взяли за основу разумное подмножество C++, цены б им не было. :)

Вот бы настройки BIOS обернуть во что-то попригляднее, например в Kolibri OS, хотя уже есть красивые UEFI, но им не хватает хакерства :)

Sign up to leave a comment.