这是一个简单的linux内核模块代码来反转一个字符串,它应该在insmod之后进行Oops,但它运行良好,为什么?
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
static char *words = "words";
static int __init words_init(void)
{
printk(KERN_INFO "debug info\n");
int len = strlen(words);
int k;
for ( k = 0; k < len/2; k++ )
{
printk("the value of k %d\n",k);
char a = words[k];
words[k]= words[len-1-k];
words[len-1-k]=a;
}
printk(KERN_INFO "words is %s\n", words);
return 0;
}
static void __exit words_exit(void)
{
printk(KERN_INFO "words exit.\n");
}
module_init(words_init);
module_exit(words_exit);
module_param(words, charp, S_IRUGO);
MODULE_LICENSE("GPL");
答案 0 :(得分:0)
static
!= const
。
static
表示&#34;仅在当前文件中显示&#34;。见What does "static" mean?
const
只是意味着&#34;可以看到此声明的代码不应该更改变量&#34;。但在某些情况下,您仍然可以创建一个指向同一地址的非const指针并修改内容。
Space removal from a String - In Place C style with Pointers建议不应该写入字符串值。
由于static
是您的代码与问题代码之间的唯一区别,因此我进一步了解了这一点:Global initialized variables declared as "const" go to text segment, while those declared "Static" go to data segment. Why?
尝试static const char *word
,这应该可以解决问题。
答案 1 :(得分:0)
哈哈!我自己从linux内核源代码中得到答案;当你使用insmod时,它将调用init_moudle,load_module,strndup_usr然后调用memdup_usr函数; memdup_usr函数将使用kmalloc_track_caller来分配来自slab的memery和然后使用copy_from_usr将模块paragram复制到内核中;这意味着linux内核模块paragram存储在堆中,而不是在常量存储区域!所以我们可以改变它的内容!