我试图将kprobe转换为可加载的内核模块。
我可以运行samples/kprobes/
文件夹中的可用示例
内核树。
如果我们在内核(CONFIG_KPROBES
)中配置kprobes,那么svc_entry
宏将在__und_svc()
处理程序中以64字节进行扩展。
参考: http://lxr.free-electrons.com/source/arch/arm/kernel/entry-armv.S?a=arm#L245
我的目标是不触及内核端,将kprobe作为内核模块。
因此编译内核时不启用CONFIG_KPROBES。所以svc_entry宏将以0 in扩展 __und_svc()
我想从这些怀疑中解脱出来。
如果处理kprobe未定义的指令异常(bcos kprobe
仅创建),然后调用__und_svc()
的原因。 __und_svc()
处理程序对kprobes的作用是什么?
如果64字节内存是强制的,那么如何分配没有 编译内核。即如何动态地进行。??
请分享您的知识。
答案 0 :(得分:5)
您可能无法获得回复,因为您对事物的理解不是很好,并且 linux-arm-kernel 列表中的任何人都需要一些时间才能做出响应。阅读kprobes.txt并详细研究ARM体系结构。
如果处理了kprobe未定义的指令异常(仅创建了bcos kprobe),那么为什么调用
__und_svc()
。__und_svc()
处理程序对kprobes的作用是什么?
在ARM上,模式0b11011
是未定义的指令模式。 未定义指令发生时的流程是,
第四步的主要向量表位于__vectors_start
,这只是分支到
vector_und
。该代码是一个名为vector_stub
的宏,用于调用__und_svc
或__und_usr
。堆栈是每个进程保留的4 / 8k页面。它是包含任务结构和内核堆栈的内核页面。
kprobe 的工作原理是将未定义的指令放在您要探测的代码地址上。即,它涉及未定义的指令处理程序。这应该是非常明显的。它调用两个例程call_fpe
或do_undefinstr()
。您对第二种情况感兴趣,它获取操作码并调用call_undef_hook()
。添加register_undef_hook()的钩子;你可以看到arch_init_kprobes()
。使用struct pt_regs *regs
调用主回调kprobe_handler
,这恰好是__und_svc
中保留的额外内存。例如,注意kretprobe_trampoline()
,它正在使用当前正在执行的堆栈进行技巧。
如果必须使用64字节内存,那么如何在不编译内核的情况下进行分配。即如何动态地进行。?
不,不是。您可以使用其他机制,但可能必须修改 kprobes 代码。您很可能必须限制功能。也可以完全重写堆栈帧并在事后保留额外的64字节。与kmalloc()
中的不是分配。它只是从管理程序堆栈指针中添加/减去一个数字。我猜这段代码会重写未定义处理程序的返回地址,以便在 kprobed的上下文(ISR,下半部/线程IRQ,work_queue,内核任务)中执行地址。但是,您可能还有其他问题尚未遇到。如果永远不会调用arch_init_kprobes()
,那么您可以随时在__und_svc
进行预订;它只占用64个字节的堆栈,这将使内核堆栈更有可能溢出。即,改变,
__und_svc:
@ Always reserve 64 bytes, even if kprobe is not active.
svc_entry 64
arch_init_kprobes()
是实际安装该功能的原因。