Загрузчик в C / C ++? - PullRequest
       33

Загрузчик в C / C ++?

20 голосов
/ 24 июля 2011

Можно ли создать загрузчик в C или C ++ без использования какого-либо типа Ассемблера (и желательно без использования __asm)? Я пишу операционную систему и хотел бы, чтобы она была полностью написана на C и C ++.

Ответы [ 4 ]

21 голосов
/ 24 июля 2011

Это довольно зависит от системы. В большинстве случаев ответ будет отрицательным - вам нужно написать какую-то пользовательскую сборку, чтобы настроить среду выполнения C перед тем, как вы начнете запускать код C. Однако есть некоторые исключения. Например, ARM Cortex-M0 может выполнять код C сразу после сброса.

Предположительно, однако, вы не используете M0, поэтому вам нужно написать какую-то сборку. Опять же, это зависит от системы / микросхемы, но вам, возможно, удастся сделать что-то простое:

reset_vector:
    mov  sp, SOME_KNOWN_GOOD_STACK_ADDRESS
    call c_entry_point

, который просто инициализирует указатель стека и вызывает точку входа вашей C-программы. Конечно, эта простая установка зависит от того, есть ли у вашего чипа таблица векторов / векторов сброса, которая его поддерживает, ОЗУ (или что-то вроде ОЗУ) инициализируется до вызова вектора сброса и так далее. В ранней инициализации системы, как правило, много «ошибок».

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

Удачи!

6 голосов
/ 24 июля 2011

Предполагая, что это для x86, вы, вероятно, можете получить что-то , работающее в 16-битном режиме, если у вас есть правильные параметры компилятора и вам удастся получить правильную компоновку вашего загрузочного сектора с помощью правильной магии компоновщика.

Но вы не доберетесь далеко с простым C (или C ++): вам нужно будет очень быстро маскировать прерывания, и для этого нет функции C.Требуется сборка.

Это вероятно то же самое для большинства других архитектур: в C и C ++ эти функции просто не встроены (хотя некоторые расширения компилятора могут вам помочь).

Отличный ресурс для того, что вы пытаетесь сделать: OSDev .

3 голосов
/ 24 июля 2011

Предполагается, что защищенный режим x86:

Я полагаю, что ответ Нет , потому что вам нужно сделать что-то подобное, чтобы переключиться в защищенный режим:

    lgdt[GDTR]
    jmp CODESEL:FLUSH
FLUSH:
    ...

Iне думаю, что есть способ выполнить инструкцию jmp на чистом C / C ++, хотя я могу ошибаться.(Я ни в коем случае не эксперт здесь; я просто ссылаюсь на загрузчик, который я сделал некоторое время назад.)

2 голосов
/ 24 июля 2011

Нет, это невозможно с "чистым" C, по крайней мере, на x86 ... В дополнение к тому факту, что машина x86 будет загружаться в 16-битном реальном режиме (требуется компилятор для генерации 16-битных, а не 32-битный код), вам понадобится возможность маскировать прерывания, настраивать регистры сегментов, загружать код в память с аппаратного устройства (т. Е. С диска), настраивать стек, получать доступ к портам ввода-вывода и т. Д. x86 и другие платформы требуют доступа к регистрам ЦП и / или конкретным командам сборки.

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

...