我在Linux内核中添加了一个简单的helloworld
系统调用。
sys_helloworld
#include <linux/kernel.h>
asmlinkage long sys_helloworld(void)
{
printk("Hello world\n");
return 0;
}
它只会将Hello world
打印到内核日志中。
我这样调用了sys_helloworld
系统调用:
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
long int a = syscall(314); // 314 is the line number of sys_helloworld in syscall table
printf("System call sys_helloworld returned %ld\n", a);
return 0;
}
以上程序在内核日志中成功打印Hello world
。
我的问题:
如何在程序中获取sys_hello
(将Hello world
打印到内核日志中)的输出?
答案 0 :(得分:3)
您应该向系统调用添加两个参数:要写入的缓冲区及其大小。然后,您可以使用snprintf()
打印您想要的任何字符串。您只需确保使用正确的系统调用定义宏。由于您需要2个参数,因此我们需要SYSCALL_DEFINE2
:
#include <linux/kernel.h> /* For snprintf() */
#include <sys/syscall.h> /* For SYSCALL_DEFINE* macros */
SYSCALL_DEFINE2(sys_helloworld, char *, buff, size_t, buff_sz)
{
snprintf(buff, buff_sz, "Hello world\n");
return 0;
}
为了完整性,并且根据上下文,您可能希望将返回值更改为允许您知道字符串是否被截断的内容。
用户代码可以这样称呼它:
#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
char buf[32];
long int a = syscall(314, buf, sizeof(buf));
printf("System call sys_helloworld returned %ld\n", a);
printf("buf = %s\n", buf);
return 0;
}
请注意,使用SYSCALL_DEFINE*
宏来定义系统调用通常更好的方式,而不是手动输入asmlinkage long ....
,即使对于没有参数的系统调用(您将使用{{1} })。这些宏在SYSCALL_DEFINE0
中定义,您应该使用它们。