Энциклопедия разработчика модулей ядра Linux
Шрифт:
Симметричная
Один из самых простых (самый дешевый) способ улучшить аппаратную эффективность: поместить больше чем один CPU на плате. Когда такое сделано, могут быть два варианта: либо CPU берут различные работы (асимметричная многопроцессорная обработка) или они все работают параллельно, делая ту же самую работу (симметрическая многопроцессорная обработка, a.k.a. SMP). Выполнение асимметричной многопроцессорной обработки действительно требует специализированного знания относительно задач, которые компьютер должен делать. Такое знание является недоступным в универсальной операционной системе типа Linux. С другой стороны, симметрическая многопроцессорная обработка относительно проста в реализации.
В симметрической многопроцессорной среде CPU совместно используют ту же самую память, и в результате код, работающий на одном CPU может воздействовать на память используемую другим. Вы больше не можете быть уверены, что переменная, которую вы установили в некоторое значение на предыдущей строке все еще имеет то же самое значение: другой CPU может его поменять, в то время как Вы не смотрели.
В случае программирования процесса это обычно не проблема, потому что процесс будет обычно выполняться только на одном CPU сразу [14] . Ядро, с другой стороны, может быть вызвано различными процессами, работающими на различных CPU.
14
Исключительная ситуация: threaded-процессы, которые могут выполняться на нескольких CPU сразу.
В версии 2.0.x, это не проблема, потому что все ядро находится в одном большом spinlock. Это означает что, если один CPU работает с ядром, и другой CPU хочет обратиться к ядру, например из-за системного вызова, он должно ждать, до тех пор пока первый CPU завершит работу с ядром. Это делает Linux SMP безопасным [15] , но неэффективным.
В версии 2.2.x, несколько CPU могут работать с ядром одновременно. Это авторы модуля должны знать. Я надеюсь, что смогу получить доступ к машине с несколькими процессорами, и следующая версия этой книги будет включать большее количество информации.
15
Значение
безопасно, чтобы использовать с SMP.Общие ловушки
Прежде чем писать ядерные модули, надо учесть несколько важных моментов.
1. Использование стандартных библиотек. Вы не можете делать этого. В модуле, Вы можете использовать только функции, которые Вы можете увидеть в /proc/ksyms.
2. Запрет прерываний. Если Вы на краткое время запретите прерывания, ничего ужасного не произойдет. Но если забудете их разрешить, придется выходить из данной ситуации выключением питания.
Различия между версиями 2.0 и 2.2
Я не знаю, что все ядро достаточно хорошо документирует все изменения. В ходе преобразования примеров (или фактически, адаптации изменений Еммануела Папиракиса) я натолкнулся на следующие различия. Я привожу их все здесь вместе, чтобы помочь программистам, особенно тем, кто обучался на предыдущих версий этой книги и наиболее знакомы с методами, которые я использую, и преобразовываю в новую версию.
Дополнительный ресурс для людей, кто желают преобразоваться в 2.2, находится по адресу: http://www.atnf.csiro.au/~rgooch/linux/docs/porting-to-2.2.htm.
1. asm/uaccess.h: Если Вы нуждаетесь в put_user или get_user: Вы должны #include его.
2. get_user в версии 2.2: get_user получает указатель в памяти пользователя и переменную в памяти ядра, чтобы заполнить информацией. Причина для этого в том, что get_user, может теперь читать два или четыре байта одновременно, если переменная, которую мы читаем длиной два или четыре байта.
3. file_operations: Она теперь выполняет функцию flush между функциями open and close.
4. close в file_operations: В версии 2.2, функция close возвращает целое число, так что она может вернуть код ошибки.
5. read и write в file_operations: Изменились заголовки для этих функций. Они сейчас возвращают ssize_t вместо целого числа, и их список параметра различен. Inode больше не параметр, и с другой стороны смещение в файле.
6. proc_register_dynamic: Функция больше не существует. Вместо нее Вы вызываете proc_register и помещаете ноль в поле inode структуры.
7. Сигналы: Сигналы в структуре task больше не 32 разрядные целые числа, а массив _NSIG_WORDS целых чисел.
8. queue_task_irq: Даже если Вы хотите обратиться к запланированной задаче из внутреннего обработчика прерывания, Вы используете queue_task, а не queue_task_irq.
9. Параметры модуля: Вы объявляете параметры модуля как глобальные переменные. В 2.2 Вы должны также использовать MODULE_PARM, чтобы объявить их тип. Это большое усовершенствование, потому что позволяет модулю получать параметры строкового типа, которые начинаются с цифр.
10. Симметричная многозадачность: Ядро больше не заперто внутри одного огромного spinlock, что означает что два процессора могут одновременно обрабатывать разные части ядра. Модули должны знать о SMP.
Что дальше?
Я мог бы легко добавить еще несколько глав в эту книгу. Я мог бы добавить главу о создании новых файловых систем, или о добавлении новых стеков протоколов (как будто имеется потребность в такой главе: вы должны рыть под землей, чтобы найти стек протоколов, не поддерижаемый Linux). Я мог бы добавить объяснение ядерных механизмов, которых мы не коснулись, типа начальной загрузки или дискового интерфейса.