Вы можете не получить ответы, так как ваше понимание вещей не очень хорошо, и кому-либо из списка linux-arm-kernel потребуется некоторое время, чтобы ответить. Прочитайте kprobes.txt и подробно изучите архитектуру ARM.
Если kprobe обрабатывает исключение неопределенной инструкции (только bcos kprobe), то почему вызывается __und_svc()
. какова роль обработчика __und_svc()
по отношению к kprobes?
В ARM режим 0b11011
является режимом неопределенных инструкций. Последовательность действий при выполнении неопределенной инструкции следующая:
- lr_und = pc инструкции undef + 4
- SPSR_und = CPSR режима, в котором произошла инструкция.
- Измените режим на ARM с отключенным прерыванием.
- PC = векторное основание + 4
Основная векторная таблица четвертого шага находится по адресу __vectors_start
, и это просто переходит к vector_und
. Код представляет собой макрос с именем vector_stub
, который принимает решение о вызове __und_svc
или __und_usr
. Стек — это страница размером 4/8 КБ, зарезервированная для каждого процесса. Это страница ядра, которая содержит как структуру задач, так и стек ядра.
kprobe работает, помещая неопределенные инструкции в кодовые адреса, которые вы хотите проверить. Т.е. он включает неопределенный обработчик инструкций. Это должно быть довольно очевидно. Он вызывает две процедуры: call_fpe
или do_undefinstr()
. Вас интересует второй случай, который получает код операции и вызывает call_undef_hook()
. Добавьте хук с помощью register_undef_hook(); который вы можете увидеть arch_init_kprobes()
. Основной обратный вызов kprobe_handler
вызывается с struct pt_regs *regs
, что является дополнительной памятью, зарезервированной в __und_svc
. Обратите внимание, например, на kretprobe_trampoline()
, который шутит со стеком, с которым он выполняется в данный момент.
Если 64 байта памяти обязательно, то как выделить без компиляции ядра. т.е. как это сделать динамически.?
Нет. Вы можете использовать другой механизм, но вам, возможно, придется изменить код kprobes. Скорее всего, вам придется ограничить функциональность. Также можно полностью перезаписать фрейм стека и зарезервировать лишние 64 байта постфактум. Это не распределение, как в kmalloc()
. Это просто добавление/вычитание числа из указателя стека супервизора. Я предполагаю, что код перезаписывает адрес возврата из неопределенного обработчика для выполнения в контексте (ISR, IRQ нижней половины/потока, work_queue, задача ядра) kprobed эм> адрес. Но, вероятно, есть дополнительные проблемы, с которыми вы еще не сталкивались. Если arch_init_kprobes()
никогда не вызывается, то вы всегда можете сделать резервирование в __und_svc
; он просто съедает 64 байта стека, что повышает вероятность переполнения стека ядра. То есть изменить,
__und_svc:
@ Always reserve 64 bytes, even if kprobe is not active.
svc_entry 64
arch_init_kprobes()
— это то, что на самом деле устанавливает эту функцию.
person
artless noise
schedule
13.12.2013