Написать ОС для Raspberry Pi на С


19

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

.section .init
.globl _start
_start:

bl main

loop$:
b loop$

к другому объектному файлу и связывая их вместе и таким образом получая kernel.img. Затем я заменил уже существующее ядро ​​своим собственным, но оно не выполняет код Си. Код C, который я написал, должен просто включить светодиод OK и затем вернуться (затем приходит loop$: b loop$). Но светодиод OK несколько раз мигает случайным образом, а затем просто гаснет. Вот мой код C:

int main(int argc, char ** argv) {
    volatile unsigned *gpioAddr = (volatile unsigned *)0x20200000;
    *(gpioAddr + 4) = 1 << 18;
    *(gpioAddr + 40) = 1 << 16;
    return 0;
}

Как использовать C для разработки операционной системы на Raspberry Pi?

Я сомневаюсь, что это ошибка в коде (хотя я просто любитель). Я знаю, что настройка C может быть сложной, но я не первый, кто делает это. AFAIK, все доминирующие в настоящее время ОС написаны в основном на C, поэтому должна быть статья, объясняющая процесс. Я был бы очень счастлив со списком шагов, так что я могу поискать эти шаги в Google и, возможно, задать вопрос чуть менее широкий.

Примечание: эквивалент сборки кода ARM вышеупомянутого кода C работает просто отлично. Включается светодиод (после небольшого мигания). Я думаю (надеюсь), что означает, что мой Raspberry Pi в порядке.


C был разработан, чтобы быть переносимым языком ассемблера для Unix. Linux написан на C, вы можете сэкономить немало времени, посмотрев, как это делается.
Турбьёрн Равн Андерсен

1
@ ThorbjørnRavnAndersen Я думаю, что я не до чтения источника Linux. Linux гораздо сложнее, чем то, что я хочу знать, скрывая для меня интересные части.
11684

1
«Подключите» несколько светодиодов.
11684

1
Спасибо, но я хочу сделать большинство вещей сам. Это учебный проект.
11684

1
Должен признаться, я никогда не видел вопроса о том, как писать ОС. И есть несколько интересных ответов. Это просто сумасшествие ...
Петр Кула

Ответы:


14

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

  • отключить прерывания во время процесса загрузки
  • если у Pi есть контроллер памяти, вам нужно настроить его
  • установить таймер
  • настроить контроллер прерываний
  • установить стек, чтобы вы могли выполнять код C

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

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

Если вы хотите написать простую многозадачную операционную систему, вам нужно написать несколько процедур на ассемблере для сохранения регистров ЦП в стеке и загрузки другого набора значений регистров из стека другого потока. И вам нужно написать API для создания разных потоков.


1
Трудно выбрать между этим ответом и ответом Жоржа Дюперона. Я принял это и дал другому голос.
11684

13

Я не посмотрел ваш код подробно, но мне кажется, вы на правильном пути. Убедись, что:

  • Этот _startсимвол действительно используется при компиляции и компоновке вашего сборочного файла и вашего C-файла (и main()вместо этого он не используется)
  • При звонке main()необходимо использовать соглашение о вызовах C:
    • вставьте в стек адрес инструкции, следующей за вашим вызовом (адрес возврата, который будет использоваться returnоператором в C)
    • выдвинуть аргументы для функции. В вашем случае вы можете выдвинуть два 32-битных значения (всего 8 байт), но для упрощения вы также можете удалить аргументы и простоint main() { ... }
    • возможно зарезервировать некоторое место в стеке для возвращаемого значения
    • Я не могу вспомнить, в каком порядке эти вещи нужно толкать
    • Чтобы точно знать, что ожидает функция C, разберите ее ( objdump -S main.o) и посмотрите, как она манипулирует стеком.
  • Если вы не соблюдаете соглашение о вызовах, то ассемблерный код, сгенерированный компилятором C, может повлиять на адрес возврата в стеке, и в вашем случае вы даже не выдвинули адрес возврата, поэтому инструкция возврата куда-то переместится случайно, вместо того, чтобы идти loop$.

OSDev вики будет очень полезным Ressource - это в основном связано с развитием x86 , но большая часть информации по - прежнему применимы к Raspberry Pi.

Еще несколько специфических ресурсов для raspberry-pi osdev:


Трудно выбрать между этим ответом и ответом Стива. Я дал тебе голос и принял другое. Я сожалею о 5 повторениях.
11684

OSDev Wiki хороша - и даже имеет некоторые специфические вещи RasPi
Wally

2

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


Спасибо за ответ на мой вопрос (и извините за столь поздний ответ). Но (сюрприз!) Я купил свой пи, чтобы узнать об этом, немного о процессах низкого уровня (я бы не стал делать это на дорогом рабочем столе с риском уничтожения личных файлов / писем / фотографий). Не могли бы вы добавить, как я настраивал стек, или статью / учебник / какой-то ресурс, объясняющий это? (И что еще мне может понадобиться для запуска C).
11684

2

Попробуйте это вместо этого:

http://www.valvers.com/open-software/raspberry-pi/step01-bare-metal-programming-in-cpt1/

Кроме того, опыт x86 немного отличается. Это может быть применимо к обычному программированию ОС на ARM. Но для Пи, извините, сначала запускается gpu, и он настраивается немного раньше кода вашей ОС (?).


1
Немного подробнее было бы здорово, что произойдет, если ссылка в вашем ответе сломается?
Дарт Вейдер

Это все еще там, но я думаю, что для тех, кто приезжает сюда, может гуглить "клапаны голые по металлу" и лучше попробовать серию OSDEV (чтобы пройти перекрестную разработку, как я боролся, читайте форум; я выкладываю один, вы можете попробовать Google "OSDEV" форум шестимесячного кросса ")
Денис Нг

Я знаю, что это старый ответ на еще более старый вопрос, но страница находится на web.archive.org в случае, если он не работает.
anonymoose

1

s-matyukevich/raspberry-pi-os

https://github.com/s-matyukevich/raspberry-pi-os

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

Кроме того, он рассматривает, как работает ядро ​​Linux, и комментирует код ядра Linux.

Посмотрите первый урок для минималистичной установки: https://github.com/s-matyukevich/raspberry-pi-os/tree/43f682d406c8fc08736ca3edd08a1c8e477c72b0/src/lesson01/src

Я очень рекомендую это.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.