Linux 内核 调试笔记
使用kallsyms_lookup_name读取
kallsyms_lookup_name本身也是一个内核符号,如果这个符号被导出了,那么就可以在内核模块中调用kallsyms_lookup_name("do_page_fault")来获得do_page_fault的符号地址。
这种方法的局限性在于kallsyms_lookup_name本身不一定被导出。
CONFIG_KALLSYMS 依赖该内核选项
头文件 linux/kallsyms.h
使用 Kprobes 调试内核
ftrace kprobe调试 - CSDN博客
ARM64内核态 函数打桩
头文件依赖
#include <asm/cacheflush.h>
#include <linux/bitops.h>
#include <linux/sizes.h>
#include <linux/byteorder/generic.h>
后一个头文件待考证
set_memory_rw这个函数需要在内核里面手动export
1、跳转指令
#define BRANCH_INSN 0x14000000
addr_old被打桩函数地址 addr_new新的桩函数地址
offset就是两个函数之间的地址差值小于正负128M
offset = ((long)addr_old- (long)addr_new);
insn = BRANCH_INSN
mask = BIT(26) - 1;
insn &= ~(mask);
insn |= ((offset >> 2) & mask);
2、修改mem属性为RW
set_memory_rw(addr_old&PAGE_MASK, 1);
3、刷新跳转指令到原函数
*(unsigned int *)old = cpu_to_le32(insn);
4、刷新cache
flush_icache_range(addr_old,addr_old + 4);
完成打桩,但打桩前需要备份被打桩的函数,否则无法恢复
linux存储内核架构图参考
Linux Storage Stack Diagram
UIO的事例 包括了多地址映射和用户态select 中断
UIO 示例 - 积极工作,积极生活 - 开源中国
相关文章