0

我在一个驱动程序中声明了一个静态 const int 变量并导出了该变量符号。在另一个驱动程序中,我正在修改该变量。另一个驱动程序打印修改后的值,但原始驱动程序保留原始值。当两个驱动程序看到的变量的虚拟地址和物理地址都相同时,这怎么可能呢?它是内核错误吗?

[root@localhost bug]# uname -a
Linux localhost.localdomain 3.5.3 #3 SMP Mon Sep 3 21:52:12 IST 2012
i686 i686 i386 GNU/Linux

[root@localhost bug]# cat driver.c

#include <linux/module.h>

static const int value = 123;

int init_module()
{
        printk("Base driver (init): value                     = %d\n", value);
        printk("Base driver (init): virtual address of value  = %p\n", (void *)&value);
        printk("Base driver (init): physical address of value = %p\n", (void
*)__pa(&value));
        return 0;
}

void cleanup_module()
{
        printk("Base driver (exit): value                     = %d\n", value);
        printk("Base driver (exit): virtual address of value  = %p\n", (void *)&value);
        printk("Base driver (exit): physical address of value = %p\n", (void
*)__pa(&value));
}
EXPORT_SYMBOL(value);

[root@localhost bug]# cat hacker.c

#include <linux/module.h>

extern int value;

int init_module()
{
        value = 987;
        printk("Hacker driver (init): value                     = %d\n", value);
        printk("Hacker Base driver (init): virtual address of value  = %p\n",
(void *)&value);
        printk("Hacker Base driver (init): physical address of value = %p\n",
(void *)__pa(&value));
        return 0;
}

void cleanup_module()
{
        printk("Hacker driver (exit): value                     = %d\n", value);
        printk("Hacker driver (exit): virtual address of value  = %p\n",
(void *)&value);
        printk("Hacker driver (exit): physical address of value = %p\n",
(void *)__pa(&value));
        return;
}


[root@localhost bug]# insmod driver.ko

基本驱动程序 (init):值 = 123 基本驱动程序 (init):值的虚拟地址 = f89d61c8 基本驱动程序 (init):值的物理地址 = 389d61c8

[root@localhost bug]# insmod hacker.ko

Hacker 驱动程序 (init): value = 987 Hacker Base driver (init): value 的虚拟地址 = f89d61c8 Hacker Base driver (init): value 的物理地址 = 389d61c8

[root@localhost bug]# rmmod hacker.ko

黑客驱动(退出):值 = 987 黑客驱动(退出):值的虚拟地址 = f89d61c8 黑客驱动(退出):值的物理地址 = 389d61c8

[root@localhost bug]# rmmod driver.ko

基本驱动程序(退出):值 = 123 基本驱动程序(退出):值的虚拟地址 = f89d61c8 基本驱动程序(退出):值的物理地址 = 389d61c8

[root@localhost bug]# cat /proc/kallsyms | grep value

f89f91c8 R 值 [驱动程序] f89f9088 r __ksymtab_value [驱动程序] f89f91cc r __kstrtab_value [驱动程序]

有趣的是,当我在 driver.c 中将变量声明更改为“volatile”为“static const volatile int”时,driver.ko 在 rmmod 期间打印修改后的值“987”,原始值“123”丢失。这个和之前的声明有什么区别?

4

1 回答 1

5

这与内核无关。这是基本的 C 行为。一旦你声明了一个变量 const,编译器就可以自由地将你分配给它的值内联在同一个编译单元中访问它的任何地方。获取一个指向 const 变量的指针会强制编译器在数据部分中添加该变量的副本,假设它是只读的。

如果您运行objdump -d一个结果内核模块并查看 init_module,您会看到在传递给的参数中printk,它并不是真正访问变量,而是使用值的内联副本。

于 2012-09-04T12:29:32.473 回答