Pull to refresh

Comments 45

Довольно интересно. Помню прошлым летом тоже решил заморочиться, попробовать для общего развития написать «свой процессор». Я правда тогда остановился на армовской системе команд, правда реализовал довольно ограниченное их количество. Только самое необходимое. Я так понял вам еще и свой компилятор пришлось писать из-за не стандартных команд? Меня на такой подвиг уже не хватило, не знаю как вы решились на такое, я честно говоря не вижу на первый взгляд у вашей системы команд особых преимуществ, чтобы тратить на нее столько времени. Использовали ли вы конвеер и скольки уровневый он получился? Что-то не нашел об этом упоминаний в тексте
Коневейер пока не использовали. Есть некоторые идеи относительно конвейера, есть даже мысли об одновременном исполнении нескольких инструкций, поместившихся на 40-битную шину, но сейчас нам более интересно движение в сторону микроядра — довольно новая область, которой пока никто серьёзно не занимался.

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

Наконец, что касается компилятора, то тут всё сложно — его научили лексическому и синтаксическому разбору, но до генерации кода руки не дошли. В общем, о компиляторе я пока не готов говорить — это половина компилятора. С другой стороны — есть несколько сторонних разработчиков, котрые пишут компиляторы. У нас есть взаимный интерес и при удачных обстоятельствах эти разрааботчики могли бы добавить поддержку нашего процессора в свои продукты.

А вы не думали о том, что можно решить задачу написанием соответствующего кодогенератора для LLVM? Вы тогда ещё как минимум получите бесплатный компилятор для C/C++ в виде clang.
Спасибо, статья реально вставила. Всячески залюсовал.
Приятно что не перевелись в сети люди вроде Вас!
По поводу регистров — IMHO стоит разделять адресные и арифметические регистры (как в MC68xxx и BlackFin). Во первых, это увеличивает число регистров без увеличения размера команд. Во вторых упрощает регистровые файлы и коммуникации.
Про моделирование — я участвовал в проектах моделирования на SystemC и Haskell (даже без специальных библиотек). Haskell оказался практически идеальным языком для этого. Для C для разбора системы команд мы использовали The New Jersey Machine-Code Toolkit — поделка старая и не подерживаемая, но удобная и работающая. Если Haskell не устроит, может пригодится :-).

А как у Вас с компилятором?
Пока только лексический и синтаксический анализаторы — генерации кода нет.
Честно говоря даже немного завидно — такой героический труд проделан…
С другой стороны, мне кажется нет особого смысла делать процессор, который принципиально не отличается от многих других подобных. Совсем другое дело — это сделать процессор принципиально иной архитектуры (вот сам все время думаю об этом).
Не знаю точно, что можно подразумевать под принципиально «иной» архитектурой, но уверен, такие появятся, может быть уже скоро. Может быть это будут процессоры на лету меняющие архитектуру под конкретную задачу. Может быть это будут процессоры с какой-то нелинейной адресацией памяти. Может вместо памяти в компьютерной системе будут логические блоки и сама запись или чтение из памяти уже смогут выполнять некоторое действие…
Кто придумает это «иное» и сможет сделать «это» популярным, тот и выиграет.
Спасибо за статью.
Идея интересная. Но вспомнился один иследовательский проект для военных. Там лозунг был, что можно некоторые функции ОС реализовать в железе. Предполагалось, что это позволит сделать более защищенную систему.
В общем у нас товарищи разработали технологию HaSCol. И утверждали, что с помощью нее могут сделать процессор + компилятор за пару месяцев. В реальности все оказалось более прозаично. После первого года удалось сделать ядро процессора без периферии и gcc без оптимизации. Не было средств синхронизации, не были поддержаны даже прерывания, а некоторые вещи даже не в командах ассемблера приходилось писать, а их численным эквивалентом. С трудом удалось портировать маленькую собственную ОС Embox. В которой только shell показали (Заказчик хотел Linux). На следующем этапе удалось убедить разработчиков, что нужно использовать стандартную архитектуру, чтобы свой компилятор не писать. И с помощью этой технологии уже была разработана своя реализация процессора с архитектурой DLX, более известный как Microblaze от компании Xilinx. А уже в стандартной архитектуре сделали улучшения и какую то аппаратную поддержку ОС.

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

Добавятся инструкции захвата и освобождения буфера сообщений. Добавится самая главная инструкция, ради которой всё это затвевлось — «Inter Process Communication». Пока что есть мысли реализовать эту инструкцию через микрокод. Видите, даже мненмонику ей ещё не придумали — аббревиатура IPC будет не очень удачной, поскольку среди электроников аббревиатура IPC имеет устоявшееся значеие «Instructions Per Cycle».

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

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

Вот такие планы на будущее.

Понятно.
По нашему опыту, очень большой прирост производительности давала аппаратная реализация MMU. Сравнивали реализации была на SPARC (Leon3) и Microblaze собственной разработки и оригинальная версия. Аппаратная поддержка таблиц при переключении контекстов которая есть в SPARC просто ни в какое сравнение не лезет с вариантами где есть только TLB. Но это для Линукс, где используются процессы.
Думаю, переключение контекста сделать довольно реально. А вот с IPC возможны большие проблемы, хотя если делать на микрокоде то можно получиться.
Вообще проект интересный! Удачи!
Такой объём работы и настолько крутые планы тянут на десяток статей.

Я однозначно хочу L4 в процессоре!
В какой-то момент нам перестали нравиться существующие решения — что-то оказалось сложным, что-то неоптимальным, что-то просто недоделанным, что-то, чего уж скрывать, имело не очень подходящую лицензию и условия использования.

Какая лицензия вам бы подошла? Какую лицензию планируете для конечного продукта?
Рассматривали ли вы коммерческие конфигурируемые процессоры, например xtensa или ARC?

Набравшись смелости и скрепя зубами мы начали авантюру, решив разрабатывать процессор с самого начала.

пойдёт речь о 32-битном микропроцессоре с оригинальной системой команд

32 бита — несколько странный выбор для процессора общего назначения в наше время.
пойдёт речь о 32-битном микропроцессоре с оригинальной системой команд
32 бита — несколько странный выбор для процессора общего назначения в наше время.
Объясните пожалуйста, почему?
Потому что раньше (больше 10 лет назад :) 4Г памяти были либо недоступны, либо занимали много места. Сейчас даже встраиваемая мелочь идёт с гигабайтами на борту, не говоря уже о системах общего назначения. Если 32 бита — это «пробный шар», а дальше планируется расширение, тогда понятно. Если не планируется, то полезность данной разработки сильно падает.
32-битность не означает ограничение какой бы то ни было памяти четырьмя гигабайтами.
Ну привет, а виртуальные адреса вы из чего делать будете, если не из регистров?
Ладно. Я сливаюсь — пошёл курить гугл. Но что-то мне подсказывает, что всё не так просто.
UFO just landed and posted this here
Ячейки ПЛИС удовольствие дорогое.

А время разработчиков, стало быть, дешёвое?
UFO just landed and posted this here
Как вы лихо всё поняли,
Это не серверный процессор
,
32 бита им хватит
, я вот не вижу откуда это следует.
UFO just landed and posted this here
Для начала нужно осилить 32 бита. Огромное кол-во микроконтроллеров на 32 битных ядрах ARM Cortex сейчас приходят на смену 8 битных контроллеров. Или вы хотите, чтобы они сразу замену х86-64 сделали сходу?
Я (не великий, впрочем, специалист в проектировании процессоров) не вижу существенной разницы, разрабатывать 32-битный процессор или 64-битный. А зачем делать хуже, если можно сделать лучше? И, к тому же, для «поиграться и выкинуть»
мы просто помешаны на компактности, поэтому все команды переходов имеют три формы — знаковые смещения размерностью 1, 2 и 3 байта.
— тоже странно.
Даже текущие 64 битные процессоры архитектуры х86-64 являются 32 битными с 64 битной надстройкой. Itanium, который полностью 64 битный уже давно вымирающий вид. 64 битные ядра пока не нужны рынку микроконтроллеров, там балом будут править 32 битные и ещё очень долго. Там ещё только идёт переход на 32 бита с 8 бит. Это огромный рынок носимой электроники и интернета вещей.
Например умные часы Сони и Самсунг используют 32битные ARM Cortex. Подавляющее большинство современных смартов на 32 битах.

К чему это я, 64 бита будет сделать сложнее, потребуется больше времени, места на чипе для логики и так далее. И это не требуется. Кроме того, в будущем архитектуру можно будет расширить. Если бы это была коммерческая оплачиваемая разработка с достаточным бюджетом, то конечно имело бы смысл рассмотреть, но у коммерции были бы свои чёткие цели. А так, ребята сами пилят и взлетать нужно не на боинге, а на цессне.
Ваша мысль мне понятна.

Даже текущие 64 битные процессоры архитектуры х86-64 являются 32 битными с 64 битной надстройкой. Itanium, который полностью 64 битный уже давно вымирающий вид.

Да что ж вы всё на intel оглядываетесь, который тут ни к селу ни к городу? У них долгая история, намеренная обратная совместимость, они ещё и немного 16-битные изнутри. Вы этого же желаете Алексею и компании? За пределами Intel Architecture тоже, кстати, есть жизнь: POWERPC, S390x, SPARC.

64 битные ядра пока не нужны рынку микроконтроллеров, там балом будут править 32 битные и ещё очень долго

Вопрос — нужно ли там L4?
Да что ж вы всё на intel оглядываетесь


У Itanium как раз нет обратной совместимости, если не считать эмуляцию х86. Остальные на рынке представлены весьма слабо в настоящих реалиях. PowerPC чтобы не заглохнуть теперь доступен для лицензирования. SPARC и остальные тоже редки. Это не рынок для L4. Тягаться с серверными процами после скольких лет разработки можно будет? А на Интел и АМД поскольку они главные разработчики массовых процессоров были. Теперь к ним подтянулись по полной программе ARM-ядра.

Вопрос — нужно ли там L4?

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

Так что на рынке МК путь открыт, хотя и конкурентов тьма, но они вообще продают системы на ПЛИС. Это курорт для разработчика процессоров.

А вот на рынок PowerPC, SPARC и иже с ними, им не в путь, там без мощной инфраструктуры делать нечего со своей новой архитектурой.
Я с вами согласен, что для процессора общего назначения 32 бита маловато. Но для концепта или под встроенные системы вполне приемлемо. ARM-ы 64 разрядные только начали появляться, а 32 разрядные вовсю используются. Тут, как мне кажется, речь вряд ли идет о масс продакшен.
в архитектуре нет ни одной команды перехода по абсолютному адресу — все переходы осуществляются относительно текущей команды

А как же «перейти по адресу в регистре» (частным случаем которой является return)? Или у вас такой команды нет? А как у вас виртуальные функции работают?
Есть такой процессор Z80. Он хоть и восьмибитный, но у него есть некоторые средства работы с 16-битными числами, ну и шина адреса тоже 16-битная. Может быть, подобным образом можно сделать 64-битную шину адреса у 32-битного процессора и тем самым решить вопрос с размерами линейного адресного пространства, который не дает покоя многим комментаторам.

Что же касается скорости работы — то на сегодняшний день многие 32-битные приложения на архитектуре x86 работают быстрее, чем 64-битные, из-за проблем с плотностью 64-битного кода. Потому что узкое место в скорости работы таких приложений — это не разрядность обрабатываемых чисел или количество регистров, а размер кэша и скорость доступа к памяти команд.
Есть такой процессор Z80. Он хоть и восьмибитный, но у него есть некоторые средства работы с 16-битными числами, ну и шина адреса тоже 16-битная. Может быть, подобным образом можно сделать 64-битную шину адреса у 32-битного процессора и тем самым решить вопрос с размерами линейного адресного пространства, который не дает покоя многим комментаторам.
— Вы только что изобрели PAE.
проблем с плотностью 64-битного кода
— А плотность 64-битного кода плохая не потому, что он 64-битный (спасибо относительным адресам, абсолютные 64-битные не поддерживаются в x86-64), а потому, что у AMD руки и ноги растут из одного места.
Вы только что изобрели PAE

Нет, это не PAE. PAE появилось в 1995г и только в контексте процессоров IA-32. К тому же, PAE не увеличивает линейное адресное пространство сверх 32 бит. Описанное мною явление возникло гораздо раньше. Практически все 8-битные процессоры и контроллеры имеют 16-разрядную шину адреса и линейное 16-битное адресное пространство. Также характерны 16-битные операции со стеком адресов возврата. Адреса вызовов и переходов 16-битные, также обычно имеются какие-то возможности косвенных переходов по адресам, хранящимся в паре регистров. Именно в Z80 объединение 8-битных регистров в 16-битные пары реализовано наиболее развито.

И все это при том, что процессоры формально 8-битные. Они имеют 8-битное АЛУ и, таким образом, одновременно обрабатывают только 8 бит информации.
А плотность 64-битного кода плохая не потому, что он 64-битный

Ну, даже если оптимизировать систему команд 64-битного процессора, все равно плотность кода обязательно уменьшится по сравнению с таким же, но 32-битным процессором. Как минимум, вырастет размер адресов абсолютных переходов, если мы хотим сохранить линейное адресное пространство. Если же нет — то потребуются пляски с бубном для организации страничной и т.п. адресации, что опять-таки выльется в раздувание размеров программы.

Хотя те же проблемы с плотностью кода появятся в случае реализации 64-битного адресного пространства на 32-битном процессоре.
Вы говорите не о линейном, а о логическом АП. Но логическое АП больше максимального машинного слова — не очень удобно. А в принципе, большинство существующих ОС для IA-32e работают именно так, по модели LP64: integerы 32 бита. Но это — одна из причин низкой плотности кода (спасибо префиксам).
Я говорю именно о линейном АП, когда все указатели имеют одинаковый размер. Противоположные случаи — страничная и сегментная адресация, при этом существует два вида указателей — near и far, которые имеют разную длину. И даже в случае PAE адресное пространство одного процесса и объем доступной ему памяти не превышает 2^32.
Когда АП больше машинного слова — это, конечно, создает некоторые неудобства. Но еще хуже, если АП имеет недостаточный размер. Тут просто выбирается меньшее из двух зол.
Определившись с регистрами, мы решили сделать полностью позиционно независимую систему команд — в архитектуре нет ни одной команды перехода по абсолютному адресу
а RETURN это не команда что ли?) Производит переход по абсолютному адресу в R15
Вообще эта идея сделать любой код полностью релоцируемым — она ведет к затратам. Нужны сумматоры для вычисления адресов перехода, которые можно было бы выкинуть. И, как вы верно заметили, все равно трудно добиться, чтобы любой код был релоцируемым. С другой стороны, проблемы релокации уже давно и успешно решаются программно. Есть исполняемый файл, в нем есть таблица релокации. При загрузке файла происходит настройка его на адрес — и все. А для чего еще нужен релоцируемый код?
При загрузке файла происходит настройка его на адрес

Вот в этом месте и ведутся основные бои в библиотеках С и их динамических линковщиках: как сделать так, чтобы код был и релоцируемым, и разделяемым, т.е. чтобы несколько приложений, загрузивших одну динамическую библиотеку использовали минимальное количество физической памяти. Каждая релокация — это изменение кода или данных, каждый процесс, изменяющий общую страницу получает свою изменённую копию. Если большинство вызовов/переходов — относительные, то релокации им не нужны. Для вызовов, которые точно потребуют модификации, например вызовов между разными библиотеками, применяются специальные техники, например PLT (procedure linkage table), группирующие данные изменяемые релокациями.
Если среди вызовов/переходов попадаются абсолютные — то настройка кода на адрес все равно нужна. Какая при этом разница, сколько нужно изменений? Главное — что невозможно полностью избавиться от них и присущих им проблем.

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

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

Большая: либо изменение каждой страницы, в которой есть такой вызов (при наивной реализации), либо изменение только страниц PLT, в которых собраны все такие переходы/вызовы (при использовании PLT). Т.е. в первом случае 256 вызовов раскиданных по 256 разным страницам — это +256 приватных страниц процесса, а во втором — +1 приватная страница (при размере элемента PLT в 16 байт).

Этот подход делает фактически невозможной какую-либо экономию памяти за счет динамических библиотек

Но не в случае относительной адресации данных/относительных переходов.

существует проблема релокации данных

Их тоже группируют по секциям: нуждающиеся в релокациях/не нуждающиеся.
DLL — это веский аргумент.

Идея заключается в том, что программе в общем случае не нужно знать адрес библиотеки для передачи ей управления. Программа обменивается сообщениями, при этом не происходит явной передачи управления. Соответственно, вместо адреса точки входа в библиотечную функцию, вызвающей программе необходимо знать ID задачи и ID запроса. При этом нет разницы, где расположена библиотечная функция — в соседнем потоке, на другом ядре или вообще, реализована аппаратно.

В системе команд нет инструкций, в которых явно указан абсолютный адреса перехода. Да, неудобно получилось — можно понять двусмысленно.
Вопрос, — данное устройство предназначено исключительно для выполнения микроядра, или системные сервисы / пользовательские процессы будут выполняться на нём же?
Системные сервисы / пользовательские процессы будут выполняться на нём же. Малое количество ОЗУ в этой прошивке объясняется тем, что используется только внутренняя память ПЛИС, а внешнее ОЗУ ещё не задействовано.
Sign up to leave a comment.

Articles