Как писал Мэт, это, вероятно, необоснованно ограничено. Тем не менее, я постараюсь уделить сумме вопросов не меньше внимания, чем одному разумно ограниченному вопросу, в надежде, что это поможет вам начать исследование.
1 В чем разница между «вытеснением» и «переключением контекста»?
Упреждение — это акт прерывания процесса без его участия. В этом контексте это, вероятно, означает, что сработает прерывание таймера. Это слово происходит от юридического понятия преимущественного права: действие или право требования или покупки до или в предпочтении перед другими. Для ваших целей это означает, что когда срабатывает прерывание по таймеру, процедура обслуживания прерывания (ISR) имеет приоритет над кодом, который выполнялся ранее. Это не обязательно должно включать ядро; у вас может быть код, работающий в любом ISR, который будет выполняться с упреждением.
Переключение контекста — это то, что происходит, когда код ОС (работающий упреждающе) изменяет состояние процессора (регистры, режим и стек) между контекстом одного процесса или потока и другим. Состояние процессора может быть на определенной строке кода в одном потоке. Он будет иметь временные данные в регистрах, указатель стека на определенную область памяти и другую информацию о состоянии. Упреждающая ОС может сохранять это состояние (либо в статической памяти, либо в стеке процессов) и загружать состояние предыдущего процесса. Это известно как переключение контекста.
2 Каковы основные различия между вытесняющим и невытесняющим ядром? Какая работа требуется от программиста, чтобы сделать ядро вытесняющим?
В вытесняющем ядре прерывание может срабатывать между любыми двумя ассемблерными инструкциями (известными как «точки последовательности»). В невытесняющем ядре работающий процесс должен вызвать функцию yield()
, чтобы разрешить выполнение других потоков. Упреждающие ядра более сложны, но обеспечивают лучшую иллюзию параллелизма. Невытесняющие ядра можно очень просто реализовать с помощью setjmp.h
, но каждый поток должен регулярно вызывать yield()
, иначе другие потоки не будут выполняться.
Когда вызывается такая функция, как yield()
, состояние процессора сохраняется автоматически. Если вы хотите сделать свою ОС вытесняющей, вы должны сохранить эту информацию вручную.
3 Как создать и работать с пользовательским режимом?
В документах ARM говорится, что в пользовательском режиме любая инструкция, переключающаяся в привилегированный режим, будет рассматриваться как неопределенная инструкция.
Правильный. Однако они также говорят, что любое прерывание будет выполняться в привилегированном режиме автоматически. В системе ARM вы можете использовать инструкцию svc
для генерации программного прерывания. После этого код SVC (часть вашей ОС) сможет работать в привилегированном режиме.
4 Если да, то единственный способ для программы пространства пользователя использовать код ядра — это системные вызовы?
Правильный. По крайней мере, это единственный безопасный или правильный путь.
5 Как тогда ядро реагирует или взаимодействует с пользовательским пространством?
В ARM инструкция SVC может иметь 8-битное значение. Это можно использовать для генерации 256 системных вызовов, таких как yield, enable interrupts, disabled interrupts и т. д., что вам нужно. Вы также можете создать общую память или механизм обмена сообщениями, если вам это нужно.
6 Означает ли это, что единственным потоком ядра после загрузки (в простой системе) будет бездействующий поток?
Это полностью зависит от того, как вы проектируете свою систему. Вероятно, будет проще, если вы решите запустить ядро только после того, как все ваши потоки будут созданы — таким образом вам не нужно беспокоиться о динамическом распределении потоков. Или вы можете начать с бездействующего потока и добавить другие потоки позже (через удаленную оболочку? Я думаю, вы хотите, чтобы хотя бы один пользовательский поток работал последовательно...)
7 Если страница, на которой находятся код ядра и данные, не отображается при переключении на пользовательский процесс, то при системном вызове или прерывании, как выполняется код ядра без отображения в виртуальном адресном пространстве?
Точно так же, как код режима ядра выполняется в привилегированном режиме, даже если код ранее выполнялся в пользовательском режиме, код режима ядра будет выполняться из указателя основного стека (MSP), даже если код процесса использует другое адресное пространство.
8. Означает ли «вытесняемое ядро» только то, что ядро было спроектировано таким образом, чтобы было безопасно переключать контекст во время выполнения кода ядра? или это требует дополнительной работы, если таковая имеется?
Я думаю, это означает, что ядро может вытеснять пользовательский код, а не само ядро. Было бы сложно и необычно прерывать работу ядра. Это потребует больше работы, и я изо всех сил пытаюсь понять, зачем вам это нужно.
person
Kevin Vermeer
schedule
22.07.2012