向 linux 内核添加一个简单的系统调用
adding a simple system call to linux kernel
我刚刚向 linux 内核添加了一个系统调用。它只需要一个 char*
参数名称并打印 Hello name.
这是系统调用代码:
asmlinkage long sys_hello(char* name) { printk("Hello %s \n", name); return 0; }
这是应该运行测试系统调用的代码:
int main()
{
long int amma = syscall(318,"Winston");
printf("Returned %lu \n" ,amma);
return 0;
}
但是当我 运行 这个时,我得到了一个被杀死的输出。
关于解决这个问题的任何想法?提前致谢。
这是如何不编写内核代码的经典示例之一 - 它试图直接访问用户空间缓冲区,这是一个极端的禁忌。
如果您遇到崩溃,那可能是 SMAP 在起作用。很难确定,因为你没有提供日志。
所以真正的问题是:您从哪里获取上述内容?您正在上一门包含上述内容的大学课程吗?material?
您的代码在内核上下文中执行,而带有数据的缓冲区来自用户空间。如果你需要处理来自用户空间的一些字符串,使用 strncpy_from_user() 函数将它复制到内核内存。如果您不遵循方案而只是尝试直接访问数据,这将导致内存访问冲突。
更好的解决方案(基于您的代码)看起来有点像这样:
asmlinkage long sys_hello(char* name) {
long nb_symbols;
char *name_internal;
long i;
/*
* Estimate the buffer length sufficient
* to accommodate the string
*/
for (i = 1; ; ++i) {
nb_symbols = strnlen_user(name, i);
if (nb_symbols <= 0)
return -EFAULT;
if (nb_symbols < i)
break;
}
/* Allocate the storage */
name_internal = kmalloc(nb_symbols + 1, GFP_KERNEL);
if (name_internal == NULL)
return -ENOMEM;
if (strncpy_from_user(name_internal, name, nb_symbols + 1) !=
nb_symbols) {
kfree(name_internal);
return -EFAULT;
}
printk("The 'name' is '%s'\n", name_internal);
kfree(name_internal);
return 0;
}
但是,请注意,这样的循环(如我的示例中的循环)可能不是缓冲区长度估计的可接受解决方案。理想情况下,您可以放弃它并使用固定长度的静态 char
数组来使用 strncpy_from_user()
with.
我刚刚向 linux 内核添加了一个系统调用。它只需要一个 char*
参数名称并打印 Hello name.
这是系统调用代码:
asmlinkage long sys_hello(char* name) { printk("Hello %s \n", name); return 0; }
这是应该运行测试系统调用的代码:
int main()
{
long int amma = syscall(318,"Winston");
printf("Returned %lu \n" ,amma);
return 0;
}
但是当我 运行 这个时,我得到了一个被杀死的输出。 关于解决这个问题的任何想法?提前致谢。
这是如何不编写内核代码的经典示例之一 - 它试图直接访问用户空间缓冲区,这是一个极端的禁忌。
如果您遇到崩溃,那可能是 SMAP 在起作用。很难确定,因为你没有提供日志。
所以真正的问题是:您从哪里获取上述内容?您正在上一门包含上述内容的大学课程吗?material?
您的代码在内核上下文中执行,而带有数据的缓冲区来自用户空间。如果你需要处理来自用户空间的一些字符串,使用 strncpy_from_user() 函数将它复制到内核内存。如果您不遵循方案而只是尝试直接访问数据,这将导致内存访问冲突。
更好的解决方案(基于您的代码)看起来有点像这样:
asmlinkage long sys_hello(char* name) {
long nb_symbols;
char *name_internal;
long i;
/*
* Estimate the buffer length sufficient
* to accommodate the string
*/
for (i = 1; ; ++i) {
nb_symbols = strnlen_user(name, i);
if (nb_symbols <= 0)
return -EFAULT;
if (nb_symbols < i)
break;
}
/* Allocate the storage */
name_internal = kmalloc(nb_symbols + 1, GFP_KERNEL);
if (name_internal == NULL)
return -ENOMEM;
if (strncpy_from_user(name_internal, name, nb_symbols + 1) !=
nb_symbols) {
kfree(name_internal);
return -EFAULT;
}
printk("The 'name' is '%s'\n", name_internal);
kfree(name_internal);
return 0;
}
但是,请注意,这样的循环(如我的示例中的循环)可能不是缓冲区长度估计的可接受解决方案。理想情况下,您可以放弃它并使用固定长度的静态 char
数组来使用 strncpy_from_user()
with.