gpt4 book ai didi

c - 为什么物理地址值因打印方式而异

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:13:44 27 4
gpt4 key购买 nike

我正在使用 x86 架构。据我所知(并被告知)要获得分配内存的物理地址,我需要执行以下操作:

struct SizeAddr {
size_t size;
u64 addr_uint64;
void* addr_voidp;
unsigned long addr_ul;
};

struct SizeAddr sa;

virtAddr = kmalloc(<some size>, GFP_KERNEL);
physAddr = virt_to_phys(virtAddr);

sa.addr_uint64 = (uint64_t)physAddr;
sa.addr_voidp = (void *)physAddr;
sa.addr_ul = (unsigned long)physAddr;

我决定打印出物理地址的值,因此我执行了以下操作:

    printk(MODULE_NAME " virtAddr(%%p)   = %p\n", virtAddr);
printk(MODULE_NAME " physAddr(%%pap) = %pap\n", &physAddr);
printk(MODULE_NAME " physAddr(%%llx) = %llx\n", sa.addr_uint64);
printk(MODULE_NAME " physAddr(%%p) = %p\n", sa.addr_voidp);
printk(MODULE_NAME " physAddr(%%lx) = %lx\n", sa.addr_ul);

这是我在日志中得到的:

[63898.990593] my_kmodule virtAddr(%p)   = 0000000000000010
[63898.990652] my_kmodule physAddr(%pap) = ffff88020d783eb0
[63898.990711] my_kmodule physAddr(%llx) = 780000000010
[63898.990768] my_kmodule physAddr(%p) = 0000780000000010
[63898.990827] my_kmodule physAddr(%lx) = 780000000010

这就是我真正感到困惑的地方。所有这些值不应该相同吗?为什么 physAddr(%pap) 与其余值不同(虚拟地址除外,我理解的那个)。

最佳答案

kmalloc 中值为 0x10 的虚拟地址 (virtAddr) 毫无意义。那么,在那之后,所有的赌注都落空了?

您确定您有 phys_addr_t physAddr(对比(例如)phys_addr_t *)吗?我猜在堆栈上?

%pap 的输出看起来像一个 [stack] 虚拟地址而不是物理地址。因此,我的原始关于 &physAddr/physAddr 的评论可能会有些影响,具体取决于您的完整代码。

printk("%p\n",&physAddr); 说了什么?或者,printk("%llx\n",(u64) &physAddr);?或者,其他组合(例如 &virtAddr)

虽然文档说 %pap 没问题,但它也说默认是 phys_addr_t(即 %pa)。 应该 工作[并且我对 printk 代码的检查似乎证实了这一点],%pap 只有大约 5 次用法%pa

的数百种用法

我已经检查了 printk 源代码 [重新检查,实际上,因为我之前不得不这样做很多次]。目前,我没有发现任何差异可言。但是,来源有点复杂,所以我会继续这样做。


旁注:这是编辑前的原始帖子 [被否决] [有一些澄清],但它仍然值得尝试。

现在您已经添加了sa 代码...

改变:

struct SizeAddr

进入:

union SizeAddr

添加一个 phys_addr_t 成员并只设置它 [with union]。这是更常用的成语。然后,您会看到哪些被截断了,哪些没有。否则,对于结构 %llx,您将获得与 %pap 匹配的结果。

关于c - 为什么物理地址值因打印方式而异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39045414/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com