Код context_switch() для РРС делает немного больше работы для получения того же результата. В отличие от регистра сгЗ на архитектуре х86, РРС использует функцию юпирования для указания на окружение контекста. Следующий код для switch_mm() изсается этой функции, но в гл. 4, «Управление памятью», находится его более подробное описание.
Здесь приведена функция switch_mm(), которая, в свою очередь, вызывает функцию set_context ().
include/asm-ppc/mmu_context.h 155 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,struct task_struct *tsk)
1:6 {
Функция context_switch (), вызываемая из schedule () в /kernel/sched. с, вы-шадняет специфическую для системы работу по переключению окружения памяти и состояния процесса. На абстрактном уровне context_switch переключает текущую за-JB4Y и следующую задачу. Функция context_switch () начинает выполнение следующей задачи и возвращает указатель на структуру задачи, которая выполнялась до вызова:
ismel/sched. с
1143 /*
1149 * context_switch - переключение на новый ММ и новое
1X53 * состояние регистра потока.
1151 */
1152 static inline
После того как процесс инициализирован и размещен в очереди выполнения, в какой то момент он должен получить доступ к процессору для выполнения. За передачу управления процессором другому процессу отвечают две функции: schedule () и scheduler_tick (); scheduler_tick () - это системный таймер, который периодически вызывается ядром и помечает процессы, выполнение которых нужно распланировать. При наступлении события таймера текущий процесс замирает и ядро Linux берет управление процессором на себя.
В ядре Linux 2.6 представлен полностью новый планировщик, называемый также планировщиком 0(1). Это значит, что планировщик выполняет планирование выполнения шач за константное время . Гл. 3 описывает базовые структуры планировщика, их инициализацию при создании процессов. Этот раздел описывает, как задачи выполняются на единственном процессоре. Мы будем упоминать о планировщике для многопроцессорной системы (SMP), но в общем процессы внутри всех планировщиков совпадают.
Ядро Linux является многозадачным, что означает, что в системе может выполняться множество процессов таким образом, как будто выполняется только один процесс. Способ, которым операционная система выбирает, какому процессу в данный момент разрешено получить доступ к системному процессору (процессорам), называется планировщиком.
Мы создаем простое приложение, которое открывает наш модуль и начинает бинарный отчет на штырьках с DO до D7.
Этот код компилируется с помощью дсс арр. с. По умолчанию программа собира¬ется в а. out.
арр. с
ООО //Приложение,
использующее драйвер параллельного порта
#include finclude 004 #include "parll.h"
main() {
int fptr;
int i,retval,parm =0; printf("\nopening driver now"); 012 if((fptr = open("/dev/parll",0_WR0NLY))<0) {
printf ("\nopen failed, returned=?%d", fptr); exit(l);
}
018 {
020 021 022
024
for(i=0;i<0xff ;i++)
Модуль инициализации используется для связи модуля с операционной системой. Он может применяться для ранней инициализации необходимых структур данных. Так как драйверу параллельного порта не требуется сложных структур данных, мы просто регистрируем модуль.parll.с
static int parll_init (void) {
int retval;
retval= register_chrdev(Major, MODULE_NAME, &parlport_fops);
if(retval < 0)
{
printkf "\n%s: can't register",MODULE_NAME); return retval;
}
else {
Maj or=retval;
Нижеследующее обсуждение посвящено соответствующей функции для этого проекта. Полный листинг программы для parll. с вместе с файлом parll. л приведен в конце этой книги.
1) Настройка файловых операций (fops)
Как говорилось ранее, этот модуль использует open (), close () и ioctl (), как и описанные ранее init и cleanup.
Любой поиск в сети о параллельном порте выдает огромный массив информации. Так как нашей целью в этой главе является описание модулей Linux, мы коснемся только основ этого устройства.
В этом проекте мы будем экспериментировать на х86-системе. Структуру драйвера легко портировать на PowerPC; для этого нужно просто обратиться к другому устройству на уровне ввода-вывода. Несмотря на то что параллельный порт существует на многих встроенных реализациях PowerPC, он слабо распространен на десктопах (таких, как G4 и G5).
Этот проект представляет вашему вниманию основы контроллера параллельного порта и во что сливаются ранее описанные функции ввода-вывода. Параллельный порт обычно интегрирует в Superio часть чипсета и является хорошим примером для написания осно¬вы драйвера символьного устройства. Этот драйвер, или динамически загружаемый модуль (module), не особенно полезен, хотя и годится для дальнейшего усовершенство¬вания. Так как мы адресуем устройство на уровне регистров, этот модель может исполь¬зоваться на системах PowerPC для доступа к вводу-выводу, как описано в документации по отображению в память.