Внутренние переключатели контекста
Я хочу учиться и заполнить пробелы в моих знаниях с помощью этого вопроса.
Итак, пользователь запускает поток (на уровне ядра) и теперь он вызываетyield
(системный вызов, я полагаю). Планировщик должен теперь сохранить контекст текущего потока в TCB (который хранится где-то в ядре), выбрать другой поток для запуска, загрузить его контекст и перейти к нему.CS:EIP
, Чтобы сузить круг вопросов, я работаю над Linux, работающим поверх архитектуры x86. Теперь я хочу углубиться в детали:
Итак, сначала у нас есть системный вызов:
1) Функция-обертка дляyield
поместит аргументы системного вызова в стек. Нажмите адрес возврата и вызовите прерывание с помощью номера системного вызова, помещенного в какой-либо регистр (скажем,EAX
).
2) Прерывание изменяет режим ЦП с пользователя на ядро и переходит к таблице векторов прерываний и оттуда к фактическому системному вызову в ядре.
3) Полагаю, что сейчас вызывается планировщик, и теперь он должен сохранить текущее состояние в TCB. Вот моя дилемма. Поскольку планировщик будет использовать стек ядра, а не пользовательский стек для выполнения своей операции (что означаетSS
а такжеSP
должны быть изменены) как он хранит состояние пользователя без изменения каких-либо регистров в процессе. Я читал на форумах, что существуют специальные аппаратные инструкции для сохранения состояния, но как тогда планировщик получает к ним доступ и кто выполняет эти инструкции и когда?
4) Планировщик теперь сохраняет состояние в TCB и загружает другой TCB.
5) Когда планировщик запускает исходный поток, элемент управления возвращается к функции-обертке, которая очищает стек, и поток возобновляется.
Побочные вопросы: работает ли планировщик как поток только для ядра (то есть поток, который может выполнять только код ядра)? Существует ли отдельный стек ядра для каждого потока ядра или каждого процесса?