Himik писал(а):
Я хочу частично вытесняемое ядро, т.к. в ядре будут различные модули. При обработке данных процедура может прерваться, и по идее перейти на другой ядерный или пользовательский поток.
Я для себя принял, что во время работы кода ядра программные прерывания вообще происходить не могут -- любое такое прерывание свидетельствует об ошибке в ядре и ведёт к БСОДу (образно говоря, естественно). Ну и никакой вытесняемости тоже нет: пока один отложенный обработчик не отработал, он вытеснен не будет. (Понятно, что первичные обработчики прерываний могут прервать отложенные, но они выполняются короткое время и либо возвращают управление прямо прерванному коду, либо сами запрашивают отложенную обработку -- и тогда их запрос будет помещён в очередь, а управление опять-таки вернётся прерванному обработчику.) Благодаря этим ограничениям ядро получается простым и предсказуемым: никакой тебе обработки исключений для ядра, никакой тебе подгрузки страниц ядра (оно всегда целиком должно быть в физической памяти), и даже неожиданной подгрузки страниц пользователя быть не может (если ядру требуется доступ к адресному пространству пользователя, оно должно предварительно зафиксировать соответствующие страницы, а подпрограмма фиксирования, если обнаружит, что страниц в памяти нет, не только инициирует их загрузку, но и "усыпит" вызвавший её отложенный обработчик, сохранив его стек, о чём я уже писал выше).
Вытесняемость, как по мне, имеет смысл только при необходимости выполнения "тяжёлой", потенциально долгой работы. У меня ядро в узком смысле слова такие вещи просто не выполняет: любое действие ядра может быть выполнено достаточно быстро. Однако, поскольку такое всё же может требоваться, у меня предусмотрены потоки режима ядра. Например, такой поток будет пересылать значительный объём информации из временного буфера ввода-вывода в памяти ядра в буфер задачи, если вдруг возникнет такая необходимость (такое может потребоваться, например, в ситуации, когда на конкретной платформе некое устройство может работать только по DMA, но при этом невозможна передача в произвольный участок памяти, или когда некая реализация устройства имеет аппаратный баг, из-за чего DMA требует очень жёсткого выравнивания буфера -- скажем, на границу 16 Кбайт). Ну а потоки ядра, естественно, подчиняются самому что ни на есть обычному планировщику, имеют свои приоритеты и т.д. и т.п., а соответственно, являются вытесняемыми на общих основаниях.