(LKM char device drivers ) Simple Linux Kernel Module 从用户空间读写到内核空间
(LKM char device drivers ) Simple Linux Kernel Module Read and write from userspace to kernelspace
1 sudo tail -f /var/log/syslog
2用户space程序输出。
无法使用用户space程序写入和读取内核space模块。
我认为 copy_to_user
函数返回 0,这意味着但实际上没有任何内容被复制。
我正在使用 derekmolloy 示例,但根本不起作用 (Ubuntu LTS 16.04.1)
其次想到我想问问我如何打印这个。 char* buffer dev_read 函数,因为当我想使用 printk 打印这个时,模块被杀死了。
dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
ebbchar.c (LKM)
static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
{
int error_count = 0;
error_count = copy_to_user(buffer, message, size_of_message);
if (error_count==0)
{ // if true then have success
printk(KERN_INFO "EBBChar: Sent %d characters to the user\n",
size_of_message);
return (size_of_message=0); // clear the position to the
//start and
return 0;
}
else
{
printk(KERN_INFO "EBBChar: Failed to send %d characters to the
user\n", error_count);
return -EFAULT; // Failed -- return a bad address message (i.e.
//-14)
}
}
static ssize_t dev_write(struct file *filep, const char *buffer, size_t
len, loff_t *offset)
{
int error;
// sprintf(message, "%c", buffer, len); // appending received
//string with its length
error = copy_to_user(message, buffer , size_of_message);
//ssize_t simple_read_from_buffer(void *to, size_t count, loff_t
//*ppos, const void *from, size_t available)
// error = simple_read_from_buffer(&message, 256, offset , buffer ,
// len);
int i = 0;
printk (KERN_INFO "KERNEL-SPACE copying copy_to_user() %d",error
size_of_message = strlen(message);
printk ( KERN_INFO "KERNEL-SPACE size of message recivied is %d \n
", size_of_message);
for (i = 0 ; i < len ; i ++)
{
printk(KERN_INFO "KERNEL-SPACE message[%d]=%s \n" , i ,
message[i] );
}
printk(KERN_INFO "EBBChar: Received %zu characters from the
user the message is %s\n", len, message);
return len;
}
用户-space 程序
int main()
{
int ret,
int fd;
char stringToSend[BUFFER_LENGTH];
fd = open("/dev/ebbchar", O_RDWR);// Open the device with
if (fd < 0)
{
perror("USER-SPACE : Failed to open the device...");
return errno;
}
for (int i = 0 ; i < BUFFER_LENGTH ; i++)
{
stringToSend[i] = 'a';
}
printf(" USER-SPACE : Writing message to the device [%s].\n",
stringToSend);
ret = write(fd, stringToSend, BUFFER_LENGTH); // Send the string to
//the LKM
if (ret < 0)
{
perror(" USER-SPACE : Failed to write the message to the
device.");
return errno;
}
printf("USER-SPACE : Press ENTER to read back from the
device...\n");
getchar();
printf("USER-SPACE : Reading from the device...\n");
ret = read(fd, receive, BUFFER_LENGTH); // Read the response from
// the LKM
if (ret < 0)
{
perror("USER-SPACE : Failed to read the message from the
device.");
return errno;
}
printf("USER-SPACE : The received message is: [%s]\n", receive);
printf("USER-SPACE : End of the program\n");
return 0;
}
用户-space程序的输出
须藤./a.out
USER-SPACE:启动设备测试代码示例...
USER-SPACE : Writing message to the device [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa��� �].
USER-SPACE : 按 ENTER 从设备读回...
USER-SPACE:从设备读取...
USER-SPACE : 收到的消息是:[]
USER-SPACE : 程序结束
river@mystic-computer:~$ ^C
sudo tail -f /var/log/syslog
的输出
2 月 8 日 22:11:05 神秘计算机内核:[21689.104780] EBBChar:设备已成功关闭
2 月 8 日 22:12:15 神秘计算机内核:[21758.895624] EBBChar:设备已打开 2 次
2 月 8 日 22:12:15 神秘计算机内核:[21758.895674] KERNEL-SPACE 复制 copy_to_user() 0
Feb 8 22:12:24 神秘计算机内核:[21758.895678] KERNEL-SPACE 接收到的消息大小为 0 KERNEL-SPACE message[0]=KERNEL-SPACE message[116 ]=KERNEL-SPACE message[152]=KERNEL-SPACE message[154]=<6>[21767.721994] EBBChar:向用户发送了 0 个字符
2 月 8 日 22:12:24 神秘计算机内核:[21767.722145] EBBChar:设备已成功关闭
2 月 8 日 22:13:08 神秘计算机内核:[21812.346367] EBBChar:LKM 再见!
2 月 8 日 22:13:25 神秘计算机内核:[21829.177728] EBBChar:初始化 EBBChar LKM
2 月 8 日 22:13:25 神秘计算机内核:[21829.177743] EBBChar:使用主编号 243 正确注册
2 月 8 日 22:13:25 神秘计算机内核:[21829.177773] EBBChar:设备 class 已正确注册
2 月 8 日 22:13:25 神秘计算机内核:[21829.177943] EBBChar:正确创建设备 class
2 月 8 日 22:13:40 神秘计算机内核:[21844.080308] EBBChar:设备已打开 1 次
2 月 8 日 22:13:40 神秘计算机内核:[21844.080649] KERNEL-SPACE 复制 copy_to_user() 0
Feb 8 22:13:40 神秘计算机内核:[21844.080654] KERNEL-SPACE 接收到的消息大小为 0
Feb 8 22:13:40 神秘计算机内核:[21844.080654] <6>[21844.080660] KERNEL-SPACE message[0]=(null)
2 月 8 日 22:11:05 神秘计算机内核:[21689.104780] EBBChar:设备已成功关闭
2 月 8 日 22:12:15 神秘计算机内核:[21758.895624] EBBChar:设备已打开 2 次
2 月 8 日 22:12:15 神秘计算机内核:[21758.895674] KERNEL-SPACE 复制 copy_to_user() 0
Feb 8 22:12:24 神秘计算机内核:[21758.895678] KERNEL-SPACE 接收到的消息大小为 0 KERNEL-SPACE message[0]=KERNEL-SPACE message[116 ]=KERNEL-SPACE message[152]=KERNEL-SPACE message[154]=<6>[21767.721994] EBBChar:向用户发送了 0 个字符
2 月 8 日 22:12:24 神秘计算机内核:[21767.722145] EBBChar:设备已成功关闭
2 月 8 日 22:13:08 神秘计算机内核:[21812.346367] EBBChar:LKM 再见!
2 月 8 日 22:13:25 神秘计算机内核:[21829.177728] EBBChar:初始化 EBBChar LKM
2 月 8 日 22:13:25 神秘计算机内核:[21829.177743] EBBChar:使用主编号 243 正确注册
2 月 8 日 22:13:25 神秘计算机内核:[21829.177773] EBBChar:设备 class 已正确注册
2 月 8 日 22:13:25 神秘计算机内核:[21829.177943] EBBChar:正确创建设备 class
2 月 8 日 22:13:40 神秘计算机内核:[21844.080308] EBBChar:设备已打开 1 次
2 月 8 日 22:13:40 神秘计算机内核:[21844.080649] KERNEL-SPACE 复制 copy_to_user() 0
Feb 8 22:13:40 神秘计算机内核:[21844.080654] KERNEL-SPACE 接收到的消息大小为 0
Feb 8 22:13:40 神秘计算机内核:[21844.080654] <6>[21844.080660] KERNEL-SPACE message[0]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081224] KERNEL-SPACE message[247]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081226] KERNEL-SPACE message[248]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081228] KERNEL-SPACE message[249]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081230] KERNEL-SPACE message[250]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081233] KERNEL-SPACE message[251]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081235] KERNEL-SPACE message[252]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081237] KERNEL-SPACE message[253]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081239] KERNEL-SPACE message[254]=(null)
Feb 8 22:13:40 神秘计算机内核:[21844.081242] KERNEL-SPACE message[255]=(null)
2 月 8 日 22:13:40 神秘计算机内核:[21844.081245] EBBChar:从用户那里收到 256 个字符消息是
不确定这是否能解决您的问题,但您需要使用 NULL 字符终止 stringToSend 数组,即 stringToSend[BUFFER_LENGTH - 1] = '\0'
否则,
printf("USER-SPACE : The received message is: [%s]\n", 接收);
无法正常工作,因为 printf() 不知道没有 NULL 字符的字符串在哪里终止。
至少要解决这个问题才能正确打印出来。
终于啊!!想通了。实际上 dev_write 没有工作,因为内存 (static char[256] *message) 不是使用 kmalloc
获取的
消息=kmalloc(len,GFP_KERNEL);
遇到此问题的任何人都可以使用 kmalloc。在内核 space 中获取内存。您可以在 __init 或 dev_write 函数中使用 kmalloc
1 sudo tail -f /var/log/syslog
2用户space程序输出。
无法使用用户space程序写入和读取内核space模块。
我认为 copy_to_user
函数返回 0,这意味着但实际上没有任何内容被复制。
我正在使用 derekmolloy 示例,但根本不起作用 (Ubuntu LTS 16.04.1)
其次想到我想问问我如何打印这个。 char* buffer dev_read 函数,因为当我想使用 printk 打印这个时,模块被杀死了。
dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
ebbchar.c (LKM)
static ssize_t dev_read(struct file *filep, char *buffer, size_t len, loff_t *offset)
{
int error_count = 0;
error_count = copy_to_user(buffer, message, size_of_message);
if (error_count==0)
{ // if true then have success
printk(KERN_INFO "EBBChar: Sent %d characters to the user\n",
size_of_message);
return (size_of_message=0); // clear the position to the
//start and
return 0;
}
else
{
printk(KERN_INFO "EBBChar: Failed to send %d characters to the
user\n", error_count);
return -EFAULT; // Failed -- return a bad address message (i.e.
//-14)
}
}
static ssize_t dev_write(struct file *filep, const char *buffer, size_t
len, loff_t *offset)
{
int error;
// sprintf(message, "%c", buffer, len); // appending received
//string with its length
error = copy_to_user(message, buffer , size_of_message);
//ssize_t simple_read_from_buffer(void *to, size_t count, loff_t
//*ppos, const void *from, size_t available)
// error = simple_read_from_buffer(&message, 256, offset , buffer ,
// len);
int i = 0;
printk (KERN_INFO "KERNEL-SPACE copying copy_to_user() %d",error
size_of_message = strlen(message);
printk ( KERN_INFO "KERNEL-SPACE size of message recivied is %d \n
", size_of_message);
for (i = 0 ; i < len ; i ++)
{
printk(KERN_INFO "KERNEL-SPACE message[%d]=%s \n" , i ,
message[i] );
}
printk(KERN_INFO "EBBChar: Received %zu characters from the
user the message is %s\n", len, message);
return len;
}
用户-space 程序
int main()
{
int ret,
int fd;
char stringToSend[BUFFER_LENGTH];
fd = open("/dev/ebbchar", O_RDWR);// Open the device with
if (fd < 0)
{
perror("USER-SPACE : Failed to open the device...");
return errno;
}
for (int i = 0 ; i < BUFFER_LENGTH ; i++)
{
stringToSend[i] = 'a';
}
printf(" USER-SPACE : Writing message to the device [%s].\n",
stringToSend);
ret = write(fd, stringToSend, BUFFER_LENGTH); // Send the string to
//the LKM
if (ret < 0)
{
perror(" USER-SPACE : Failed to write the message to the
device.");
return errno;
}
printf("USER-SPACE : Press ENTER to read back from the
device...\n");
getchar();
printf("USER-SPACE : Reading from the device...\n");
ret = read(fd, receive, BUFFER_LENGTH); // Read the response from
// the LKM
if (ret < 0)
{
perror("USER-SPACE : Failed to read the message from the
device.");
return errno;
}
printf("USER-SPACE : The received message is: [%s]\n", receive);
printf("USER-SPACE : End of the program\n");
return 0;
}
用户-space程序的输出
须藤./a.out USER-SPACE:启动设备测试代码示例... USER-SPACE : Writing message to the device [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa��� �]. USER-SPACE : 按 ENTER 从设备读回...
USER-SPACE:从设备读取... USER-SPACE : 收到的消息是:[] USER-SPACE : 程序结束 river@mystic-computer:~$ ^C
sudo tail -f /var/log/syslog
的输出2 月 8 日 22:11:05 神秘计算机内核:[21689.104780] EBBChar:设备已成功关闭 2 月 8 日 22:12:15 神秘计算机内核:[21758.895624] EBBChar:设备已打开 2 次 2 月 8 日 22:12:15 神秘计算机内核:[21758.895674] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:12:24 神秘计算机内核:[21758.895678] KERNEL-SPACE 接收到的消息大小为 0 KERNEL-SPACE message[0]=KERNEL-SPACE message[116 ]=KERNEL-SPACE message[152]=KERNEL-SPACE message[154]=<6>[21767.721994] EBBChar:向用户发送了 0 个字符 2 月 8 日 22:12:24 神秘计算机内核:[21767.722145] EBBChar:设备已成功关闭 2 月 8 日 22:13:08 神秘计算机内核:[21812.346367] EBBChar:LKM 再见! 2 月 8 日 22:13:25 神秘计算机内核:[21829.177728] EBBChar:初始化 EBBChar LKM 2 月 8 日 22:13:25 神秘计算机内核:[21829.177743] EBBChar:使用主编号 243 正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177773] EBBChar:设备 class 已正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177943] EBBChar:正确创建设备 class 2 月 8 日 22:13:40 神秘计算机内核:[21844.080308] EBBChar:设备已打开 1 次 2 月 8 日 22:13:40 神秘计算机内核:[21844.080649] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] KERNEL-SPACE 接收到的消息大小为 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] <6>[21844.080660] KERNEL-SPACE message[0]=(null) 2 月 8 日 22:11:05 神秘计算机内核:[21689.104780] EBBChar:设备已成功关闭 2 月 8 日 22:12:15 神秘计算机内核:[21758.895624] EBBChar:设备已打开 2 次 2 月 8 日 22:12:15 神秘计算机内核:[21758.895674] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:12:24 神秘计算机内核:[21758.895678] KERNEL-SPACE 接收到的消息大小为 0 KERNEL-SPACE message[0]=KERNEL-SPACE message[116 ]=KERNEL-SPACE message[152]=KERNEL-SPACE message[154]=<6>[21767.721994] EBBChar:向用户发送了 0 个字符 2 月 8 日 22:12:24 神秘计算机内核:[21767.722145] EBBChar:设备已成功关闭 2 月 8 日 22:13:08 神秘计算机内核:[21812.346367] EBBChar:LKM 再见! 2 月 8 日 22:13:25 神秘计算机内核:[21829.177728] EBBChar:初始化 EBBChar LKM 2 月 8 日 22:13:25 神秘计算机内核:[21829.177743] EBBChar:使用主编号 243 正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177773] EBBChar:设备 class 已正确注册 2 月 8 日 22:13:25 神秘计算机内核:[21829.177943] EBBChar:正确创建设备 class 2 月 8 日 22:13:40 神秘计算机内核:[21844.080308] EBBChar:设备已打开 1 次 2 月 8 日 22:13:40 神秘计算机内核:[21844.080649] KERNEL-SPACE 复制 copy_to_user() 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] KERNEL-SPACE 接收到的消息大小为 0 Feb 8 22:13:40 神秘计算机内核:[21844.080654] <6>[21844.080660] KERNEL-SPACE message[0]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081224] KERNEL-SPACE message[247]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081226] KERNEL-SPACE message[248]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081228] KERNEL-SPACE message[249]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081230] KERNEL-SPACE message[250]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081233] KERNEL-SPACE message[251]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081235] KERNEL-SPACE message[252]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081237] KERNEL-SPACE message[253]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081239] KERNEL-SPACE message[254]=(null) Feb 8 22:13:40 神秘计算机内核:[21844.081242] KERNEL-SPACE message[255]=(null) 2 月 8 日 22:13:40 神秘计算机内核:[21844.081245] EBBChar:从用户那里收到 256 个字符消息是
不确定这是否能解决您的问题,但您需要使用 NULL 字符终止 stringToSend 数组,即 stringToSend[BUFFER_LENGTH - 1] = '\0'
否则,
printf("USER-SPACE : The received message is: [%s]\n", 接收);
无法正常工作,因为 printf() 不知道没有 NULL 字符的字符串在哪里终止。
至少要解决这个问题才能正确打印出来。
终于啊!!想通了。实际上 dev_write 没有工作,因为内存 (static char[256] *message) 不是使用 kmalloc
获取的消息=kmalloc(len,GFP_KERNEL);
遇到此问题的任何人都可以使用 kmalloc。在内核 space 中获取内存。您可以在 __init 或 dev_write 函数中使用 kmalloc