How to get physical address of kernel symbol?

272 Views Asked by At

I'm trying to get the physical address of a kernel symbol (because I need it to be read by a system that only accepts phys addr). So I'm using things like __pa(vaddr) and virt_to_phys(vaddr).

Problem is that the conversion is not correct everytime. Sometimes it is, sometimes it's not. How do I know that? Because I'm reading the value on the kernel module as well and comparing to value read using fmem and using my other system.

Ex:

my kernel symbol's address is 0xffffffffb3400000, so when I do printk(KERN_INFO "Addr: 0x%lx , Value: 0x%lx\n", _stext, *_stext) I get => Addr: 0xffffffffb3400000 , Value: 0x4801e03f51258d48.

When it reads right I use fmem and the other system to read the physical address given by __pa and the value matches 0x4801e03f51258d48 in both cases. But sometimes it doesn't work, so the value is different. And how do I know the value itself hasn't changed? Because dereferencing the virtual address still gives me the result 0x4801e03f51258d48.

I know kernel code and data changes on every boot (including kernel symbols addresses), that's not a problem since I'm getting the kernel symbol's addr everytime. But I expected the virtual to phys mapping to be the same every time, shouldn't it be? I mean, what can I do to get the physical address of my kernel symbol correctly?

So right now I have

u64 _stext_pa = __pa(_stext_va)
printk(KERN_INFO "Value of _stext (va: 0x%lx | pa: 0x%x) = 0x%lx\n", _stext_va, _stext_pa, *_stext_va)

Addresses (virtual and physical) change every boot but the value is always the same. That's what I need.

I need a physical address paddr so that I can perform int value = *paddr; on my other system and get the same result I'm getting with the virtual address

Edit: this "other system" I'm refering to is an SMM driver, but that's not relevant, just in case you might be wondering "what is 'other system'"

0

There are 0 best solutions below