Linux Kernel (Ядро линукса) (часть 2)


Подготовка кадра

Чтобы корректно заполнить стек режима пользователя процесса, функция handlesignal ВЫЗЫВает Либо функцию setupf гаше (ДЛЯ СИГНаЛОВ, КОТОрым не нужна таблица siginfo t), либо функцию setup_rt_frame () (ДЛЯ СИГ- налов, которым требуется таблица siginfo t). Чтобы сделать выбор между этими двумя функциями, ядро проверяет флаг SA SIGINFO В ПОЛе sa flags таблицы sigaction, ассоциированной с сигналом.

Функция setup fгаше принимает четыре параметра, имеющие следующий смысл:
- sig — номер сигнала;
- ка — адрес таблицы k sigaction, ассоциированной с сигналом;
- oidset— адрес массива, являющегося битовой маской заблокированных сигналов;
- regs — адрес области в стеке режима ядра, где хранится содержимое регистров режима пользователя.
Функция setupf гаше помещает в стек режима пользователя структуру, называемую кадром, которая содержит информацию, необходимую для обработки сигнала и для корректного возврата в функцию sys_sigreturn. Кадр— это таблица типа sigframe, состоящая из следующих полей
- pretcode — адрес возврата для обработчика сигнала. Это поле указывает на КОД, имеющий метку kernel_sigreturn;
- sig — номер сигнала. Это параметр, необходимый обработчику сигнала;
- sc— структура типа sigcontext, содержащая аппаратный контекст процесса в режиме пользователя непосредственно перед переходом в режим ядра (эта информация копируется из стека режима ядра процесса current). Структура содержит также битовый массив, задающий заблокированные обычные сигналы процесса;
- fpstate — структура типа fpstate, которую можно использовать для хранения регистров операций с плавающей точкой, принадлежащих процессу в режиме пользователя
- extramask— битовый массив, задающий заблокированные сигналы реального времени;
- retcode 8-баЙТОВЫЙ КОД, ВЫПОЛНЯЮЩИЙ СИСТеМНЫЙ ВЫЗОВ sigreturn.
В прежних версиях Linux этот код использовался для возврата из обработчика сигнала, но в Linux он применяется только в качестве сигнатуры, позволяющей отладчикам распознать кадр стека сигнала.
Функция setup f rame начинается С ВЫЗОВа функции get sigframeO, ВЫЧИС- ляющей первую ячейку кадра. Эта ячейка памяти обычно6 принадлежит стеку режима пользователя, поэтому функция возвращает значение:
(regs->esp — sizeof(struct sigframe)) & OxfffffffQ
Поскольку стеки растут в направлении нижних адресов, начальный адрес кадра получается вычитанием его размера из адреса вершины стека и выравниванием результата по числу, кратному 8.
Затем возвращенный адрес проверяется макросом access ok. Если адрес является допустимым, функция многократно вызывает функцию put usero для заполнения всех полей кадра. Поле pretcode инициализируется значением
& kernei_sigreturn, являющимся адресом некоторого "склеивающего" кода,помещенного в страницу vsyscall Сделав это, функция модифицирует область regs в стеке режима пользователя, обеспечивая тем самым передачу управления обработчику сигнала, когда процесс current возобновит свое выполнение в режиме пользователя:
regs->esp = (unsigned long) frame; regs->eip = (unsigned long) ka->sa.sa_handler; regs->eax = (unsigned long) sig; regs->edx = regs->ecx = 0;
regs->xds = regs->xes = regs->xss = USER_DS;
regs->xcs = USER_CS;
Функция setupf rame завершает работу, сбрасывая регистры сегментации, сохраненные в стеке режима ядра, в значения по умолчанию. Теперь инфор
мация, необходимая обработчику сигнала, находится наверху стека режима пользователя.

Функция setup rt fгаше аналогична функции setup frameo, но она помещает в стек режима пользователя расширенный кадр (хранящийся в структуре rt sigframe), КОТОрЫЙ ВКЛЮЧаеТ В себя И содержимое таблицы siginfo_t, ассоциированной с сигналом. Кроме того, данная функция заполняет поле
pretcode так, чтобы оно указывало на код kernei rt sigreturn на странице
vsyscall.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без проблем

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга для вас. А так как к книге прилагается компакт- диск с готовой к работе операционной системой Knoppix Live CD, то лишь достаточно вставить его в привод и перегрузить компьютер,...

Linux Kernel (Ядро линукса) (часть 1)

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть другие прерывания того же типа, и другие процессоры могут приступить к их обработке. Без спин-блокировки к главному дескриптору прерывания могли бы обратиться сразу несколько процессоров. Как мы...

Linux Kernel (Ядро линукса) (часть 2)

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно неуклюже: получив системный вызов fork о, ядро в буквальном смысле дублировало все адресное пространство родителя и присваивало копию процессу-потомку. Такая операция...

Linux Kernel (Ядро линукса) (часть 3)

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer head. Этот дескриптор содержит всю информацию, необходимую ядру для работы с блоком, так что перед обработкой блока ядро обязательно проверяет голову...