Как операционные системы могут работать без операционной системы?

Мне действительно интересно сейчас. Я программист на Python, и этот вопрос просто озадачил меня: вы пишете ОС. Как вы его запускаете? Его нужно каким-то образом запустить, и этот путь находится в пределах другой ОС?

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

Это связано с ядром UNIX? Если да, то что такое ядро ​​Unix или ядро ​​вообще?

Я уверен, что ОС более сложны, но как это работает?

163 голоса | спросил Thor Correia 24 +04002012-10-24T08:43:29+04:00312012bEurope/MoscowWed, 24 Oct 2012 08:43:29 +0400 2012, 08:43:29

12 ответов


258

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

Он начинается с прошивки на материнской плате, которая пытается запустить и запустить CPU. Затем он загружает BIOS, который похож на мини-операционную систему, которая запускает и запускает другое оборудование. После этого он ищет загрузочное устройство (диск, компакт-диск и т. Д.) И, после его обнаружения, находит MBR (главную загрузочную запись) и загружает его в память и выполняет его. Именно этот маленький фрагмент кода знает, как инициализировать и запускать операционную систему (или другие загрузчики, поскольку ситуация усложнилась). Именно в этот момент такие вещи, как ядро, будут загружены и запущены.

Довольно невероятно, что он работает вообще!

ответил Bill 24 +04002012-10-24T09:08:56+04:00312012bEurope/MoscowWed, 24 Oct 2012 09:08:56 +0400 2012, 09:08:56
170

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

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

В любом случае, в то время как ОС может быть реализована в (например) C, у нее не будут доступны все обычные библиотеки C. В частности, у него не будет нормальных библиотек 'stdio'. Скорее, он реализует (например) драйвер дискового устройства, который позволяет ему читать и записывать блоки диска. Он будет реализовывать файловую систему поверх слоя блока диска, и, кроме того, он будет реализовывать системные вызовы, которые библиотеки исполняемых файлов пользовательского приложения создают (например), создают, читают и записывают файлы ... и так далее.

  

Как приложение может работать без использования ОС?

Это должен быть особый вид приложения (например, операционная система), который знает, как напрямую взаимодействовать с оборудованием ввода /вывода и т. д.

  

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

Нет.

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

Там (как правило) нет «запуска C и выполнения команд» в приложении, если это не полнофункциональная операционная система. И в этом случае операционная система несет ответственность за реализацию всей необходимой инфраструктуры, чтобы это произошло. Никакой магии. Просто много кода.

ответ Билла охватывает bootstrapping , который является процессом, в котором вы переходите от выключенной машины на машину, в которой работает обычная операционная система. Однако стоит отметить, что, когда BIOS завершает свои задачи, он (как правило) полностью контролирует аппаратное обеспечение основной операционной системы и не играет никакой дополнительной роли - до следующей перезагрузки системы. Основная ОС, конечно, не работает «внутри» BIOS в обычном смысле.

  

Это связано с ядром UNIX? Если да, то что такое ядро ​​unix или ядро ​​вообще?

Да, да.

Ядро UNIX является ядром операционной системы UNIX. Это часть UNIX, которая выполняет все описанные выше «голые металлы».

Идея «ядра» заключается в том, что вы пытаетесь разделить системное программное обеспечение на основной материал (который требует физического доступа к устройству, всю память и т. д.) и непрофильные вещи. Ядро состоит из основного материала.

В действительности различие между ядром /ядром и не-ядром /неядерным является более сложным, чем это. И было много споров о том, что действительно принадлежит ядру, а что нет. (Посмотрите, например, на микроядро.)

ответил Stephen C 24 +04002012-10-24T09:11:38+04:00312012bEurope/MoscowWed, 24 Oct 2012 09:11:38 +0400 2012, 09:11:38
62

В начале в CPU не было власти.

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

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

Наконец, приветливый экран предложил вам войти в систему.

ответил mouviciel 24 +04002012-10-24T12:01:11+04:00312012bEurope/MoscowWed, 24 Oct 2012 12:01:11 +0400 2012, 12:01:11
29

Извините, что опоздал, но я опишу его как таковой:

  • Материнская плата получает питание.

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

      

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

    - jkerian в 5:20 25 октября

  • Мощность передается ЦПУ и ОЗУ.

  • CPU загружает (на основе его внутренней проводки) данные из BIOS. На некоторых компьютерах BIOS может быть зеркально отображен в ОЗУ и затем выполнен оттуда, но это редкий вариант IIRC.

      

    При включении x86-совместимые процессоры начинаются с адреса 0xFFFFFFF0 в адресном пространстве ...

    -Micheal Steil, 17 ошибок Microsoft, сделанных в системе безопасности Xbox (< a href = "http://web.archive.org/web/20090416175601/http://www.xbox-linux.org/wiki/17_Mistakes_Microsoft_Made_in_the_Xbox_Security_System" rel = "nofollow noreferrer"> архив )

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

  • Код BIOS (с помощью настроек CMOS, хранящихся на аппаратных средствах) использует команды низкого уровня IDE или SATA для чтения загрузочного сектора каждого диска в порядке, указанном CMOS или переопределением пользователя с помощью меню.

  • Первый диск с загрузочным сектором получает свой загрузочный сектор. Этот загрузочный сектор представляет собой сборку с инструкциями по загрузке большего количества данных с диска, загрузке более крупного NTLDR , последующих этапов GRUB и т. Д.

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

Затем вы получаете дружественную панику ядра, задыхающийся пингвин или ваш диск измельчается до остановки в результате крушения головы. =) В альтернативном сценарии ваше ядро ​​устанавливает таблицы процессов, структуры в памяти и монтирует диски, загружает драйверы, модули и графический интерфейс или набор сервисов (если на сервере). Затем программы выполняются, когда их заголовки считываются, а их сборка вводится в память и соответствующим образом отображается.

ответил hexafraction 24 +04002012-10-24T15:40:30+04:00312012bEurope/MoscowWed, 24 Oct 2012 15:40:30 +0400 2012, 15:40:30
15

Есть много хороших ответов, но я хотел бы добавить это: вы упомянули, что вы пришли из фона Python. Python является интерпретированным (или «запрограммированным» или каким-либо другим, по крайней мере, типичным языком использования CPython). Это означает, что у вас есть другое программное обеспечение (интерпретатор Python), которое смотрит на источник и каким-то образом его выполняет. Это прекрасная модель и позволяет довольно приятным языкам высокого уровня хорошо абстрагироваться от реального оборудования. Недостатком является то, что вам всегда нужно программное обеспечение для переводчиков.

Такое программное обеспечение интерпретатора, как правило, написано на языке, который компилируется в машинный код, например C или C ++. Машинный код - это то, что может обрабатывать процессор. То, что может сделать ЦП, - это считывать некоторые байты из памяти и в зависимости от значений байта запускать определенную операцию. Таким образом, одна байтовая последовательность - это команда для загрузки некоторых данных из памяти в регистр, другая последовательность для добавления двух значений, другая для сохранения значения из регистра обратно в основную память и вскоре (регистр - специальная область памяти, которая является частью процессора, где он может работать лучше всего), большинство из этих команд довольно низки на этом уровне. Человеком, читаемым для этих инструкций машинного кода, является ассемблерный код. Этот машинный код, в основном, является тем, что хранится в файлах .exe or.com на окнах или в двоичных файлах Linux /Unix.

Теперь, если компьютер запущен, он немой, он имеет некоторую проводку, хотя и будет читать инструкции машинного кода. На ПК это обычно (в настоящее время) является чипом EEPROM на материнской плате, содержащем BIOS (базовая система ввода-вывода), эта система не может многое сделать, она может облегчить доступ к некоторому оборудованию и т. Д., А затем выполнить ключевую операцию: перейдите к загрузите и скопируйте первые несколько байтов (например, главную загрузочную запись, MBR) в память, а затем сообщите CPU: «Здесь есть ваша программа», тогда процессор будет обрабатывать эти байты там как машинный код и выполнять его. Обычно это какой-то загрузчик операционной системы, который загружает ядро ​​с некоторыми параметрами, а затем передает управление этому ядру, которое затем загружает все его доступ к всем аппаратным средствам, загружает какую-либо рабочую программу или программу оболочки или что-то еще, и позволяет пользователю входить в систему и используйте систему.

ответил johannes 24 +04002012-10-24T16:22:28+04:00312012bEurope/MoscowWed, 24 Oct 2012 16:22:28 +0400 2012, 16:22:28
12

Вы спрашиваете: «Как приложение может работать без участия в ОС». Легкий ответ: «ОС - это не приложение». Хотя ОС можно создавать с помощью тех же инструментов, что и приложение, и из одного и того же исходного материала, это не одно и то же. OS не должна играть по тем же правилам, что и приложение.

OTOH, вы можете думать о фактическом оборудовании и прошивке как о «ОС», в которой работает «приложение» ОС. Аппаратное обеспечение - очень простая ОС - он знает, как запускать команды, написанные машинным кодом, и знает, что при запуске он должен посмотреть на очень специфический адрес памяти для своей первой инструкции. Итак, он запускается, а затем сразу запускает эту самую первую инструкцию, затем вторую и так далее.

Итак, ОС - это просто машинный код, который существует в известном месте и который может напрямую взаимодействовать с оборудованием.

ответил Bryan Oakley 25 +04002012-10-25T18:10:07+04:00312012bEurope/MoscowThu, 25 Oct 2012 18:10:07 +0400 2012, 18:10:07
6

Ответ на ваш вопрос требует знания того, как выглядит собственный (для CPU) код и как он интерпретируется процессором.

Обычно весь процесс компиляции основан на переводе вещей, которые вы пишете на C, Pascal или даже на Python (с использованием pypy) и C # на то, что понимает процессор, т.е. простые инструкции, такие как «хранить что-то под [адресом памяти]», «добавлять сохраненные номера» под регистрами eax и ebx "," call function foo "," compare eax to 10 ". Эти инструкции, выполненные один за другим, делают то, что вы хотели сделать с вашим кодом.

Теперь подумайте об этом: вам действительно не нужна ОС для выполнения этого собственного кода! Все, что вам нужно, - загрузить этот код в память и сообщить CPU, что он есть, и вы хотите, чтобы он был выполнен. Однако не беспокойтесь об этом. Это задача BIOS, о которой нужно беспокоиться - она ​​загружает ваш код (только один и один сектор) сразу после запуска ЦП под физическим адресом 0x7C00. Затем CPU начнет выполнение этого одного сектора (512 B) вашего кода. И вы можете делать все, что вы себе представляете! Без, конечно, никакой поддержки со стороны ОС. Это потому, что вы - операционная система. Круто, да? Нет стандартной библиотеки, нет boost, нет python, нет программ, нет драйверов! Вы должны написать все сами.

И как вы общаетесь с оборудованием? Ну, у вас есть два варианта:

  1. Вы остаетесь внутри «Реального режима» - режим выполнения ЦП с объемом памяти 1 МБ (и даже меньше), отсутствие продвинутых функций ЦП, таких как расширения ЦП, защита памяти, многозадачность; 16-битный исполняемый код, старинный режим адресации ... Но с некоторыми программами, предоставляемыми BIOS, включая простой экранный вывод, поддержку клавиатуры, дисковый ввод-вывод и управление питанием. Одним словом, вы вернулись во времена MS-DOS и 16-битных процессоров.
  2. Вы переходите в «Защищенный режим» со всеми функциями вашего процессора, всей установленной вами памятью и т. д. Но в защищенном режиме вы полностью одиноки, и вам нужно все делать самостоятельно (и вы общаетесь с аппаратными средствами, используя инструкции «in» и «out» для ввода /вывода данных на порты ввода-вывода и с использованием прерываний. /О). Должен ли я сказать каждую ОС с Windows 95, и первый Linux выбирает эту опцию?

Теперь вы спрашиваете, что такое ядро. Вскоре ядро ​​- это все, что вы не видите и не испытываете напрямую. Он управляет, наряду с драйверами, всем, начиная с вашей клавиатуры и почти на каждом аппаратном обеспечении вашего ПК. Вы общаетесь с ним графической оболочкой или терминалом. Или с помощью функций внутри вашего кода, которые теперь выполняются, к счастью, с поддержкой ОС.

Для лучшего понимания я могу дать вам один совет: попробуйте написать свою собственную ОС. Даже если он собирается написать «Привет мир» на экране.

ответил Mateusz K. 24 +04002012-10-24T19:53:01+04:00312012bEurope/MoscowWed, 24 Oct 2012 19:53:01 +0400 2012, 19:53:01
3

Существуют некоторые отличия от того, как работает операционная система, зависящая от системы. Чтобы быть полезным, система должна иметь предсказуемое поведение при запуске, например, «начать выполнение по адресу X». Для систем, имеющих энергонезависимое хранилище (например, флэш-память), отображаемых в их программном пространстве, это довольно просто, так как вы просто убедитесь, что ставите код запуска в нужном месте в программном пространстве процессора. Это чрезвычайно распространено для микроконтроллеров. Некоторым системам необходимо выполнить запуск своих программ запуска из какого-либо другого места перед его выполнением. Эти системы будут иметь некоторые операции, жестко подключенные (или почти жестко подключенные) к ним. Есть некоторые процессоры, которые извлекают свой код запуска через i2c из другого чипа, поэтому процессор выполняет нетривиальные операции, не выполняя никаких инструкций по сборке, а затем начинает выполнять инструкции по предопределенному адресу.

Системы, использующие семейство процессоров x86, обычно используют многоступенчатый процесс загрузки, который является довольно сложным из-за его проблем с эволюцией и обратной совместимостью. Система выполняет некоторую прошивку (называемую BIOS - базовая система ввода /вывода или аналогичная), которая находится в некоторой энергонезависимой памяти на материнской плате. Иногда некоторые или все эти прошивки копируются (перемещаются) в ОЗУ, чтобы ускорить выполнение. Этот код был написан со знанием того, какое оборудование будет присутствовать и может использоваться для загрузки.

Запуск прошивки обычно записывается с предположениями о том, какое оборудование будет присутствовать в системе. Много лет назад на машине 286, вероятно, было бы предположение о том, что контроллер ввода-вывода X будет иметь контроллер флоппи-дисковода и будет загружать сектор 0 в определенное место памяти, если ему задан определенный набор команд (и код в секторе 0 знает, как использовать собственные функции BIOS для загрузки большего количества кода, и в конечном итоге достаточно кода для загрузки ОС). На микроконтроллере может быть допущено, что есть последовательный порт, работающий с определенными настройками, который должен ждать команд (для обновления более сложной прошивки) за X промежуток времени, прежде чем продолжить процесс загрузки.

Точный процесс запуска данной системы не так важен для вас, как знание того, что оно отличается от разных систем, но также и то, что все они имеют общие черты. Часто в процессе запуска (начальной загрузки) кода при выполнении ввода-вывода устройства ввода-вывода проверяются, а не полагаются на прерывания. Это связано с тем, что прерывания сложны, используйте стек стека (который еще не полностью настроен), и вам не нужно беспокоиться о блокировке других операций, когда вы являетесь единственной операцией.

При первом загрузке ядро ​​ОС (ядро является основной частью большинства ОС) первоначально будет действовать так же, как и прошивка. Он должен быть запрограммирован с помощью знания или обнаружения оборудования, установки некоторой ОЗУ в виде пространства стека, проведения различных тестов, настройки различных структур данных, возможно обнаружения и монтирования файловой системы, а затем, вероятно, начнется какая-то программа, которая больше как программы, которые вы используете для записи (программа, которая полагается на существующую ОС).

Код ОС обычно записывается в виде смеси С и сборки. Самый первый код для ядра ОС, вероятно, всегда находится в сборке и делает такие вещи, как настройка стека, который использует C-код, а затем вызывает функцию C. Другая рукописная сборка также будет присутствовать там, потому что некоторые операции, которые должна выполнять ОС, часто не выражаются в C (например, переключение контекста /свопинг). Часто для компилятора C необходимо передать специальные флаги, чтобы не полагаться на стандартные библиотеки, которые используют большинство программ на C, и не ожидать, что существует int main (int argc, char * argv []) в программе. Кроме того, необходимо использовать специальные параметры компоновщика, которые большинство программистов не используют. Это может привести к тому, что программа ядра будет загружена на определенном адресе или настроена так, чтобы в некоторых местах были внешние переменные, хотя эти переменные никогда не были объявлены ни в одном коде C (это полезно для ввода /вывода с отображением памяти или другие специальные ячейки памяти).

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

ответил nategoose 24 +04002012-10-24T20:00:30+04:00312012bEurope/MoscowWed, 24 Oct 2012 20:00:30 +0400 2012, 20:00:30
3

Чтобы понять, как работают операционные системы, может быть полезно разбить их на две категории: те, которые просто предоставляют услуги приложениям по запросу, и те, которые используют аппаратные функции в ЦП, чтобы предотвратить приложения от действий, которые они не должны , MS-DOS был прежнего стиля; все версии Windows с 3.0 были последним стилем (по крайней мере, при запуске чего-либо более мощного, чем 8086).

Оригинальный IBM PC с ПК-DOS или MS-DOS был бы примером прежнего стиля «ОС». Если приложение пожелало отобразить символ на экране, было бы несколько способов сделать это. Он может вызывать процедуру, которая попросит MS-DOS отправить ее на «стандартный вывод». Если это произойдет, MS-DOS проверит, перенаправляется ли выход, а если нет, он будет вызывать процедуру, хранящуюся в ПЗУ (в коллекции подпрограмм, которые IBM назвала базовой системой ввода /вывода), которая отображает символ на курсора и переместите курсор («write teletype»). Эта программа BIOS затем сохранит пару байтов где-то в диапазоне 0xB800: от 0 до 0xB800: 3999; аппаратное обеспечение адаптера цветной графики будет многократно отображать пары байтов в этом диапазоне, используя первый байт каждой пары для выбора формы символа, а второй - для выбора цветов переднего плана и фона. Байты извлекаются и обрабатываются красным, зеленым и синим сигналами в последовательности, которая дает четкий текстовый дисплей.

Программы на ПК IBM могут отображать текст, используя стандартную процедуру DOS «стандартного вывода», или используя обычную программу «Write teletype» BIOS или сохраняя ее непосредственно для отображения памяти. Многие программы, необходимые для отображения большого количества текста, быстро выбирали последний подход, поскольку он мог быть буквально в сотни раз быстрее, чем при использовании подпрограмм DOS. Это произошло не потому, что процедуры DOS и BIOS были исключительно неэффективными; если дисплей не был заглушен, его можно было записать только в определенное время. Процедура BIOS для вывода символа была спроектирована так, чтобы ее можно было вызвать в любое время; каждый запрос, таким образом, должен был начать заново, ожидая подходящего времени для выполнения операции записи. Напротив, код приложения, который знал, что ему нужно сделать, мог бы организоваться вокруг доступных возможностей для записи дисплея.

Ключевым моментом здесь является то, что, хотя DOS и BIOS обеспечивали средство вывода текста на дисплей, не было ничего особенного «волшебного» в отношении таких способностей. Приложение, которое хотело писать текст на дисплей, могло сделать это так же эффективно, по крайней мере, если аппаратное обеспечение дисплея работало так, как ожидалось приложение (если кто-то установил Monochrome Display Adapter, который был похож на CGA, но имел свою память символов расположенный в 0xB000: 0000-0xB000: 3999), BIOS автоматически выводит символы там; приложение, которое было запрограммировано для работы с MDA или CGA, могло бы это сделать, но приложение, запрограммированное только для CGA, было бы совершенно бесполезно на MDA).

В более новых системах ситуация немного отличается. Процессоры имеют различные режимы «привилегии». Они запускаются в наиболее привилегированном режиме, где коду разрешено делать все, что он хочет. Затем они могут перейти в ограниченный режим, где доступны только выбранные диапазоны памяти или устройства ввода-вывода. Код не может переключиться напрямую из режима ограничения в режим привилегий, но процессор имеет определенные точки входа в привилегированный режим, а код с ограниченным режимом может попросить процессор начать запуск кода в одной из этих точек входа в привилегированном режиме. Кроме того, есть точки входа в привилегированный режим, связанные с рядом операций, которые будут запрещены в ограниченном режиме. Предположим, например, что кто-то хотел запустить несколько приложений MS-DOS одновременно, причем каждый из них имеет свой собственный экран. Если приложения могут писать непосредственно на контроллер дисплея в 0xB800: 0, не было бы способа предотвратить перезапись приложения одним приложением. С другой стороны, ОС может запускать приложение в ограниченном режиме и ловушку при любых обращениях к памяти дисплея; если он обнаружил, что приложение, которое должно было быть в «фоновом режиме», пыталось записать 0xB800: 160, оно могло хранить данные в некоторой памяти, которую он выделил в качестве буферного экрана фонового приложения. Если это приложение будет позднее переключено на передний план, тогда буфер можно будет скопировать на реальный экран.

Ключевыми моментами являются (1), хотя часто бывает удобно иметь стандартный набор подпрограмм для выполнения различных стандартных сервисов, таких как отображение текста, они не делают ничего, что приложение, работающее в «привилегированном режиме», не могло не делайте, если он был правильно запрограммирован для работы с установленным оборудованием; (2) Хотя большинству приложений, работающих сегодня, будет предотвращена их операционная система от выполнения такого ввода-вывода напрямую, программа, которая запускается в привилегированном режиме, делает все, что захочет,и может настраивать любые правила, которые он хочет для программ с ограниченным режимом.

ответил supercat 27 +04002012-10-27T22:08:48+04:00312012bEurope/MoscowSat, 27 Oct 2012 22:08:48 +0400 2012, 22:08:48
2

Как сказал Стивен К., речь идет не только о запуске операционной системы, но и о том, как она работает, взаимодействует с оборудованием и с программным обеспечением поверх него.

Я просто добавлю к его ответу, что вы можете взглянуть на «Элементы вычислительных систем» . Это книга и некоторые инструменты, которые объясняют, как взаимодействуют компьютер, операционная система и компиляторы. Уникальная вещь в том, что она дает вам инструменты для очень быстрого создания собственной операционной системы в моделируемой среде, игнорируя множество деталей, необходимых для реального, чтобы вы могли понять понятия . Он отлично справляется с тем, что вы видите лес вместо деревьев.

Если вы хотите подробнее рассказать о взаимодействии операционной системы с аппаратным обеспечением, посмотрите Minix .

ответил Gilad Naor 24 +04002012-10-24T18:00:58+04:00312012bEurope/MoscowWed, 24 Oct 2012 18:00:58 +0400 2012, 18:00:58
1
  

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

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

Операционная система работает в аппаратном обеспечении. Аппаратное обеспечение предоставляет услуги операционной системе, такие как установка скорости передачи данных в последовательном порту и запись в нее байтов. Эти службы обычно предоставляются через регистры с отображением памяти или порты ввода /вывода.


Чтобы дать очень упрощенный пример того, как это работает:

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

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

То, как операционная система сообщает аппаратное обеспечение, сильно варьируется. Одной из функций операционной системы является защита приложений от этих различий. Для примера диска на одном виде оборудования операционная система должна будет записать номер диска и сектора в порт ввода-вывода, а затем записать байты один за другим в отдельный порт ввода-вывода. На другом оборудовании операционная система должна будет скопировать всего 512 байт сектора в область памяти, записать местоположение этой области памяти в специальную ячейку памяти и записать номер диска и сектора в другой специальной памяти.


Современное высокотехнологичное оборудование чрезвычайно сложно. Руководства, дающие всю их информацию о программировании, - это дверные проемы с тысячами страниц; например, новейшее руководство по процессору Intel - семь томов, в общей сложности более 4000 страниц - и это только для CPU. Большинство других компонентов выставляют блоки памяти или порты ввода-вывода, которые операционная система может указать ЦП для сопоставления адресов в своем адресном пространстве. Некоторые из этих компонентов отображают еще больше вещей за несколькими портами ввода /вывода или адресами памяти; в качестве примера, RTC (часы реального времени, компонент, который поддерживает время компьютера при его выключении) предоставляет несколько сотен байтов памяти за пару портов ввода-вывода, и это очень простой компонент, относящийся к оригинальный ПК /AT. Такие вещи, как жесткие диски, имеют целые отдельные процессоры, с которыми операционная система разговаривает с помощью стандартизованных команд. Графические процессоры еще сложнее.

Несколько человек в комментариях выше предлагали Arduino. Я согласен с ними, гораздо проще понять, что ATmega328, который делает все на Arduino Uno, кроме разоблачения USB-разъема в качестве последовательного порта, имеет руководство с несколькимистами страниц. На Arduino вы запускаете прямо на аппаратное обеспечение, без операционной системы между ними; просто несколько небольших подпрограмм библиотеки, которые вам не нужно использовать, если вы этого не хотите.

ответил CesarB 26 +04002012-10-26T05:25:01+04:00312012bEurope/MoscowFri, 26 Oct 2012 05:25:01 +0400 2012, 05:25:01
1

Runnable examples

Давайте посмотрим, как создать и запустить некоторые мини-приложения hello world. Аналогичные принципы применимы к «реальным» ОС.

Код всех приведенных ниже примеров представлен на этом репозитории GitHub . Все было протестировано на Ubuntu 14.04 AMD64 QEMU и реальном оборудовании ThinkPad T430.

Загрузочный сектор

В x86 самый простой и самый низкий уровень, который вы можете сделать, - создать Основной загрузочный сектор (MBR) ) , который является тиком загрузочного сектора , а затем установите его на диск.

Пример:

  printf '\ 364% 509s \ 125 \ 252'> main.img
sudo apt-get install qemu-system-x86
qemu-system-x86_64 -hda main.img
 

main.img содержит следующее:

  • \ 364 в восьмеричном == 0xf4 в шестнадцатеричном формате: кодировка для инструкции hlt , которая говорит CPU прекратить работу.

    Поэтому наша программа ничего не сделает: только начните и остановитесь.

    Мы используем восьмеричное значение, потому что шестнадцатеричные числа \ x не заданы POSIX.

    Мы можем легко получить эту кодировку с помощью:

      echo hlt> a.asm
    nasm -f bin a.asm
    hd a
     

    , но он также присутствует в руководстве Intel.

  • % 509s создает 509 пробелов. Необходимо заполнить файл до байта 510.

  • \ 125 \ 252 в восьмеричном == 0x55 , за которым следует 0xaa : магические байты, требуемые аппаратным обеспечением. Они должны быть байтами 511 и 512.

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

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

Запуск на реальном оборудовании

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

  • Запись изображения на USB-накопитель (уничтожит ваши данные!):

      sudo dd if = main.img of = /dev /sdX
     
  • подключите USB к компьютеру

  • включить его

  • скажите, чтобы он загрузился с USB.

    Это означает, что прошивка выбирает USB перед жестким диском.

    Если это не стандартное поведение вашего компьютера, продолжайте нажимать Enter, F12, ESC или другие такие странные клавиши после poweron, пока не получите меню загрузки, в котором вы можете выбрать загрузку с USB.

    Часто можно настроить порядок поиска в этих меню.

Привет мир

Теперь, когда мы выполнили минимальную программу, перейдем к миру привет.

Очевидный вопрос: как сделать IO? Несколько вариантов:

  • BIOS
  • UEFI . Преемник BIOS, более стандартизованный.
  • VGA: специальная область памяти, которая печатается на экране, если она записана. Может использоваться в защищенном режиме.
  • напишите драйвер. Это «правильный» способ сделать это: более мощный, но более сложный.

Здесь мы будем делать пример BIOS, поскольку он проще. Но учтите, что это не самый надежный метод.

Вот код GAS:

  .code16
.global _start
_Начало:
    кли
    mov $ msg,% si
    mov $ 0x0e,% ah
цикл:
    LODSB
    или% al,% al
    jz halt
    int $ 0x10
    jmp loop
остановить:
    HLT
сообщ:
    .asciz "привет мир"
.org 510
.word 0xaa55
 

Помимо стандартных инструкций по сборке пользовательского интерфейса, мы имеем:

  • .code16 : указывает GAS на вывод 16-битного кода

  • cli : отключить программные прерывания. Это может заставить процессор начать работать снова после hlt

  • int $ 0x10 : вызов BIOS. Это то, что печатает символы один за другим.

  • .org 510 и .word 0xaa55 : поместите магические байты в конец

Быстрый и грязный способ скомпилировать это с помощью:

  как -o main.o основной.S
ld -oformat binary -o main.ing -Ttext 0x7C00 main.o
 

и запустите main.img , как раньше.

Здесь есть два важных флага:

  • - oformat binary : выводить необработанный двоичный код сборки, не деформировать его внутри файла ELF, как это имеет место для обычных исполняемых файлов userland.

  • -Ttext 0x7C00 : нам нужно сообщить компоновщику ld , где будет размещен код, чтобы он мог получить доступ к памяти.

    В частности, это используется во время фазы перемещения. Подробнее об этом здесь .

Лучшим способом компиляции является использование чистого сценария компоновщика как этот . Сценарий компоновщика также может помещать магические байты для нас.

<сильный> Firmware

По правде говоря, ваш загрузочный сектор не является первым программным обеспечением, которое работает на CPU системы.

На самом деле сначала выполняется так называемая прошивка , которая является программным обеспечением:

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

BIOS - это старая всеохватная прошивка x86, а UEFI - новая замена для нее.

QEMU поставляется с собственной версией прошивки BIOS.

Прошивка делает такие вещи, как:

  • прокручивайте каждый жесткий диск, USB, сеть и т. д., пока не найдете что-то загрузочное.

    Когда мы запускаем QEMU, -hda говорит, что main.img - это жесткий диск, подключенный к оборудованию, и

    hda - первый, который нужно попробовать, и он используется.

  • загрузите первые 512 байт в адрес RAM-памяти 0x7c00 , поместите туда RIP CPU и дайте ему запустить

  • показывать такие вещи, как меню загрузки или вызовы печати BIOS на дисплее

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

Прошивки могут даже считаться самими ОС. Например. подмножество Python было перенесено на BIOS /UEFI: https://www.youtube.com /watch? v = bYQ_lq5dcvM

Начальное состояние

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

Итак, сделайте себе одолжение и используйте код инициализации следующим образом: https://stackoverflow.com/a/32509555/895245

Регистры, такие как % ds и % es , имеют важные побочные эффекты, поэтому вы должны их обнулить, даже если вы не используете их явно.

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

GRUB Multiboot

Загрузочные сектора просты, но они не очень удобны:

  • у вас может быть только одна ОС на диск
  • код нагрузки должен быть очень маленьким и помещаться в 512 байт. Это можно решить с помощью вызова вызова int 0x13 .
  • вам нужно сделать много запуска самостоятельно, например, переходить в защищенный режим

Именно по этим причинам GRUB создал более удобный формат файлов, называемый multiboot.

Минимальный рабочий пример: https: //github.com/cirosantilli/x86-bare-metal-examples/tree/d217b180be4220a0b4a453f31275d38e697a99e0/multiboot/hello-world

Если вы подготовите свою ОС как многозадачный файл, GRUB сможет найти ее в обычной файловой системе.

Это то, что делают большинство дистрибутивов, помещая изображения ОС в /boot .

Файлы Multiboot в основном представляют собой файл ELF со специальным заголовком. Они указаны GRUB по адресу: https://www.gnu.org /software/grub/manual/multiboot/multiboot.html

Вы можете включить многозадачный файл на загрузочный диск с помощью grub-mkrescue .

Эль-Торито

Формат, который можно записать на компакт-диски: https: //en.wikipedia .org /вики /El_Torito_% 28CD-ROM_standard% 29

Также возможно создать гибридное изображение, которое работает на ISO или USB. Это можно сделать с помощью grub-mkrescue ( пример ), а также выполняется ядром Linux на make isoimage с помощью isohybrid .

<сильный> ARM

У ARM-land есть свои собственные соглашения (больше не хватает соглашений, так как ARM-лицензии IP-провайдеров, которые его модифицируют), но общие идеи одинаковы:

  • вы записываете код в магический адрес в памяти
  • вы выполняете ввод-вывод с магическими адресами

Некоторые отличия:

  • IO выполняется путем непосредственного написания магических адресов, нет инструкций in и out
  • вам нужно добавитьмагия скомпилировала закрытые исходные капли, предоставленные поставщиками вашему изображению. Это похоже на BIOS, и это хорошо, поскольку это делает обновление прошивки более прозрачным.

Вот пример: https://stackoverflow.com/a/40063032/895245

Ресурсы

ответил Ciro Santilli 新疆改造中心 六四事件 法轮功 31 MaramFri, 31 Mar 2017 10:25:54 +03002017-03-31T10:25:54+03:0010 2017, 10:25:54

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132