2015-03-06 4 views
2

Недавно я начал интересоваться темами операционных систем. У меня есть пара вещей, которые взвешиваются на моем уме, но я решил разделить вопросы.Голые кости Программирование ядра ОС

Предположим, мы разрабатываем ядро ​​для новой архитектуры набора инструкций, которая выходит на рынок. Нет библиотек времени выполнения C, ничего нет. Только совместимый компилятор для этой ISA.

Предположительно, это означает, что единственными конструкторами C, доступными программисту ядра, являются только базовые операторы присваивания, побитовые операторы и циклы. Это верно?

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

Что значит тогда, когда ядро ​​должно быть написано на C (например, Linux). Являются ли некоторые части ядра неотъемлемо записаны в сборке?

+2

Библиотеки времени исполнения компилируются «совместимым компилятором для этой ISA». Так в чем проблема?Операции ввода-вывода памяти выполняются с помощью кода низкого уровня, написанного для конкретной архитектуры, с использованием того же «совместимого компилятора». Планирование процесса - это задача высокого уровня, поэтому я даже не буду упоминать об этом. –

+0

Пожалуйста, имейте в виду, что C был изначально написанные для облегчения построения ОС. –

+2

Перейдите на сайт kernel.org и посмотрите на источник для себя. Почти все это в C - даже драйверах устройств и других очень низкоуровневых материалах, но да, есть бит сборка для таких вещей, как переключения режимов процессора и т. д. –

ответ

7

Предположительно, это означает, что единственными конструкторами C, которые доступны для программиста ядра, являются только базовые операторы присваивания, побитовые операторы и циклы. Это верно?

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

Однако библиотеки, такие как Standard C Library, не будут доступны, вам придется написать свою собственную реализацию. В частности это означает, что нет malloc и free, пока вы их не реализуете самостоятельно.

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

Memory I/O is something much more low level, который обрабатывается процессором, BIOS и другим оборудованием на вашем компьютере. OS, к счастью, не должна беспокоиться об этом (за некоторыми исключениями, например, зарезервированными адресами и некоторыми функциями управления памятью).

Планирование процесса - это концепция, которая на самом деле не существует на уровне машинного кода для большинства архитектур. x86 имеет a concept of tasks и коммутацию аппаратных задач, но nobody uses it. Это абстракция, созданная ОС по мере необходимости, вам придется реализовать ее самостоятельно, или вы можете решить, иметь ОС с одной задачей, если вы не хотите тратить силы, она все равно будет работать.

Что значит тогда, когда ядро ​​должно быть записано в C (например, linux). Являются ли некоторые части ядра неотъемлемо записаны в сборке?

Некоторые части ядра будут в значительной степени зависимыми от архитектуры и должны быть записаны в ASM. Например, on x86 switching between modes (например, для запуска 16-битного кода или как часть процесса загрузки), или обработка прерываний может быть выполнена только с некоторыми защищенными инструкциями ASM. Справочное руководство по вашей архитектуре выбора, например, Intel® 64 and IA-32 Architectures Software Developer’s Manual для x86, - это первое место, где можно найти эти детали.

Но C - это портативный язык, он не нуждается в таких концепциях архитектуры с низким уровнем архитектуры (хотя теоретически можно было бы сделать все, начиная с файла .c с использованием встроенных ASM-компиляторов). Более полезно отвлечь это в ассемблерных подпрограммах и создать свой код на вершине чистого интерфейса, который вы могли бы поддерживать, если бы вы хотели перенести свою ОС на другую архитектуру.

Если вас интересует предмет, я настоятельно рекомендую вам посетить the OS Development Wiki, это отличный источник информации об операционных системах, и вы найдете много любителей, которые разделяют ваши интересы.

+0

И как реализовать malloc? Это вопрос бухгалтерии? – Mark

+1

@Mark В принципе, да. Одна простая реализация заключается в сохранении компактного связанного списка блоков используемой памяти. Каждый кусок имеет заголовок, сообщающий вам, если он используется, его размер (так что вы можете найти следующий) и, возможно, волшебное число, чтобы обнаружить повреждения памяти. Когда кто-то называет 'malloc', вы обнаруживаете свободный кусок соответствующего размера, отмечаете его и возвращаете указатель на него. Когда кто-то называет 'free', вы заходите в заголовок этого чанка и отмечаете его как неиспользованный. Конечно, существует еще много возможных реализаций, и вы можете попробовать реализовать его и в пользовательском режиме. – tux3

+0

Спасибо за ваши проницательные ответы, все остальные. Еще одна вещь ... Я понимаю, что планирование процесса выполняется на высоком уровне, я, вероятно, должен был спросить о переключении контекста в частности. Это задача ASM? Кроме того, Im не на сто процентов уверен в том, как ОС использует ОЗУ. Призывает ли он упомянутые процедуры низкого уровня каждый раз, когда им нужно что-то хранить в памяти? Как эти процедуры доступны в первую очередь? Это последняя часть, которая просто не собирается вместе ... – Mark

2

О Единственное, что вам нужно код на ассемблере являются:

  • контекстные переключатели (подкачка из состояния машины одного абстрактного процесса на другой)
  • Доступ к регистрам устройств (и вы не даже нужно это, если устройства памяти отображенный)
  • входа и выхода из обработчиков прерываний (это своего рода переключение контекста)

  • Возможно, загрузчик

Everthing еще вы должны быть в состоянии сделать код C.

Если вы хотите, чтобы эта работа была выполнена эффектно, вы должны проверить ОС Multics, начиная с середины 60-х годов, поддерживая широкомасштабные информационные службы (несколько процессоров, виртуальную память, ...). Это было почти полностью закодировано в PL/1 (C-подобный язык) с очень маленькими битами, закодированными на собственном языке ассемблера процессора Honeywell, поддерживающем Multics. Книга Organick на Multics стоит своего веса в золоте с точки зрения того, как Multics работал и насколько чист ли большинство из них. (Вместо этого мы получили «евнухов»).

Есть места, где в любом случае целесообразно кодировать на ассемблере. Независимо от качества генератора кода вашего компилятора, вы сможете вручную запрограммировать определенные процедуры, которые происходят в критичных по времени областях лучше в ассемблере, чем компилятор. Места, которые я ожидал бы от этого вопроса: планировщик, запись системного вызова и выход. Другие места только по мере того как измерение показывает. (В более старых, гораздо меньших системах, один из них, как правило, записывал ОС с использованием большого количества ассемблера, но это было так же важно для экономии пространства, как и для эффективности исполнения, компиляторы C были не так хороши).

+1

Я бы добавил к этому списку переключение режима CPU, создание зависимых от архитектуры структур данных (think lidt/lgdt/lldt/ltss/... на x86), доступ к регистрам отладки, счетчикам производительности, низкоуровневому управлению аппаратным обеспечением через Порты ввода-вывода CPU и т. Д. И т. Д. На самом деле существует довольно много вещей, которые редко используются тем, что вы не могли бы обойтись без серьезной ОС. – tux3

+1

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

+1

Я имел в виду [переключение режима] (https://i.imgur.com/dPYsATF.png), как в случае, например, Виртуальный режим 8086 или переход в длинный режим, который требует записи в EFLAGS или некоторые MSR. Не требуется ввода-вывода портов и не переключается на другую задачу/контекст, который будет выполнен, например. через инструкцию IRET. Но я понимаю. – tux3

1

Мне интересно, как новая архитектура, «выходящая на рынок», уже не будет иметь какой-либо тип операционной системы.

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

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

Смежные вопросы