【发布时间】:2023-04-08 11:04:01
【问题描述】:
通过vmap 映射内核模块的内存是否有任何限制?在我的系统上,我编写了一个简单的 KMOD,它映射了一个内核函数 (printk) 和一个模块函数 (printx),并检查映射是否相等。结果显示映射模块的printx 存在问题-映射和函数的代码不相等。有人可以解释我做错了什么吗?这是代码:
// vmap-test.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
int printx(void)
{
return 0;
}
void vmap_action(unsigned long address)
{
void * mapping;
struct page * page;
page = virt_to_page(address);
mapping = vmap(&page, 1, VM_MAP, PAGE_KERNEL);
if (mapping) {
int i = 0;
void * data = mapping + offset_in_page(address);
printk("VMAP: src %p -> dst %p\n", (void *)address, data);
for (i=0; i<16; i++) {
printk("%.02x %.02x\n", ((u8 *)address)[i], ((u8 *)data)[i]);
}
vunmap(mapping);
}
}
int my_module_init(void)
{
vmap_action((unsigned long)printk);
vmap_action((unsigned long)printx);
return 0;
}
module_init(my_module_init);
void my_module_exit(void)
{
}
module_exit(my_module_exit);
dmesg 的结果是:
vmap(printk)
[88107.398146] VMAP: src ffffffff813dfaef -> dst ffffc900117ddaef
[88107.398148] 55 55
[88107.398149] 48 48
[88107.398150] 89 89
[88107.398151] e5 e5
[88107.398152] 48 48
[88107.398153] 83 83
[88107.398154] ec ec
[88107.398155] 50 50
[88107.398156] 0f 0f
[88107.398156] 1f 1f
[88107.398157] 44 44
[88107.398158] 00 00
[88107.398159] 00 00
[88107.398160] 48 48
[88107.398161] 8d 8d
[88107.398162] 45 45
vmap(printx)
[88107.398164] VMAP: src ffffffffa009a010 -> dst ffffc900117fd010
[88107.398166] 55 35
[88107.398167] 48 fb
[88107.398168] 89 53
[88107.398169] e5 d5
[88107.398170] 0f f7
[88107.398171] 1f 97
[88107.398171] 44 ee
[88107.398172] 00 fd
[88107.398173] 00 d5
[88107.398174] 31 2d
[88107.398175] c0 bf
[88107.398176] 5d f6
[88107.398177] c3 2d
[88107.398178] 0f bd
[88107.398179] 1f b7
[88107.398180] 00 99
欢迎提出任何建议 :) 谢谢。
【问题讨论】:
-
啊,我明白你现在在问什么了……很有趣。我不知道答案 :-)。我会尝试在您从
vmap获得的地址上打印page以及调用virt_to_page。如果页面不同,下一个问题是弄清楚这两个页面实际上是什么...... -
@Nemo:我找到了解决方案,请参阅我的答案。似乎内核管理模块内存的方式与其自身不同。据我所知,模块内存是从 vmalloc 区域分配的,这可能是差异的原因。
标签: memory-management linux-kernel