所以我需要做的是直接从物理内存读取内核符号。我编写了一个内核模块,使用以下几行导出变量(符号)
int test_var = 5;
EXPORT_SYMBOL(test_var);
使用cat /proc/kallsyms | grep test_var
我得到
ffffffffc04d6064 r __kstrtab_test_var [smigenerator]
ffffffffc04d606d r __kstrtabns_test_var [smigenerator]
ffffffffc04d6054 r __ksymtab_test_var [smigenerator]
ffffffffc04d7000 D test_var [smigenerator]
所以我的符号存储在0xc04d7000
.如果我运行sudo devmem2 0xc04d7000
我会得到它的值(= 5),对吗?
错误的!读取该地址会返回0xFF300A24
.为什么当我读取应该存储变量的内存地址时没有获得变量的值?
我读过一些关于内核基地址的内容,以及从 kallsyms 获得的这个地址是应该添加到内核基地址的偏移量,不确定这是否属实,但如果是这样,我怎样才能获得这个内核基地址?
这可能是一个愚蠢的问题,但我对内核及其概念完全陌生,并且没有找到任何可以帮助我的答案。
根据记录,我使用的是 Ubuntu 22,内核 5.15.0-52-generic
答案1
该符号存储在ffffffffc04d7000
内核内存中的虚拟地址(忽略布局随机化,但这最终并不重要),并且无法从用户空间访问。
如果您想让变量在用户空间中可访问(只读),则应通过 vDSO 使其可用;看看怎么样gettimeofday
已实施。也可以看看如何在 vvar.h 中声明新变量 |在 linux 中创建 vdso。