作为一项作业,我需要完成以下 C 代码,以便生成一个能够充当内存的内核模块,但从它的编写方式来看,我无法理解它是如何工作的,以及为什么不使用许多变量而只是使用它宣布。我已经尝试查看他们给我的教材,这更加令人困惑,而且我在网上找不到一个好的网站来查找有关这些功能的文档。
代码如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#define DEVICE_NAME "my_device"
#define MAJOR_DEVICE_NUMBER 60
#define MINOR_DEVICE_NUMBER 0
#define BUF_LEN 1024
static char msg[BUF_LEN];
static char *msg_ptr; // I'm pretty sure this should become msg_reading_offset
static int major;
MODULE_AUTHOR("<YOUR NAME>");
MODULE_LICENSE("GPL");
static ssize_t my_read (
struct file *filp, char __user *buf,
size_t length, loff_t *offset);
static ssize_t my_write (
struct file *filp, const char __user *buf,
size_t length, loff_t *offset);
static int my_open (struct inode *inode,
struct file *filp);
static int my_close (struct inode *inode,
struct file *filp);
static int __init my_init (void);
static void __exit my_cleanup (void);
static struct file_operations fops = {
.read = my_read,
.write = my_write,
.open = my_open,
.release = my_close,
};
// I need to implement this function
static int my_open (struct inode *inode,
struct file *filp)
{
return 0;
}
// and this function
static int my_close (struct inode *inode,
struct file *filp)
{
return 0;
}
static ssize_t my_read (
struct file *filp, char __user *buf,
size_t length, loff_t *offset)
{
int nc = 0;
// if no more "valid" bytes can be read, stop
if (*msg_reading_offset == 0) return 0;
// no-negative values allowed
if (length < 0)
return -EINVAL;
// read the whole msg, nothing more
if (length > strlen(msg)) {
length = strlen(msg);
}
nc = copy_to_user(buf, msg_reading_offset, length);
/*
updates the current reading offset pointer so that a
recursive call due to not original
full length will get a 0 (nothing to read)
*/
msg_reading_offset += sizeof(char) * (length-nc);
// returns the number of REAL bytes read.
return length - nc;
}
static ssize_t my_write (
struct file *filp, const char __user *buf,
size_t length, loff_t *offset)
{
int nc = 0;
if (length > BUF_LEN)
return BUF_LEN-length;
nc = copy_from_user(msg,buf,length);
msg_ptr = msg;
return length - nc;
}
static int __init my_init (void)
{
register_chrdev (MAJOR_DEVICE_NUMBER,
DEVICE_NAME,
&fops);
}
module_init(my_init);
static void __exit my_cleanup (void)
{
unregister_chrdev (major, DEVICE_NAME);
}
module_exit(my_cleanup);
目前这些是我最大的问题:
- 所有 *inode、*filp 变量都去哪儿了?我应该使用它们吗?
- 这个程序是如何运作的?我知道我需要用我提供的 makefile 来编译它,但是我应该如何访问这些函数呢?
- 这应该是由内核执行的真实程序,还是只是我应该在另一个 C 程序中使用的函数集合?
如果这些问题看起来很愚蠢,我很抱歉,但我不知道该怎么解决这个问题。
最佳答案
你的问题有点宽泛,但我会尽力给你一些提示。
Where are all the *inode, *filp variables going? Am I supposed to use them?
首先阅读一个如何实现典型字符设备的示例,例如 here 。
How is this program even working? I know I need to compile it with a makefile I've been give, but then how am I supposed to access these functions?
Is this supposed to be a real program executed by the kernel or is it just a collections of functions I should use in another C program?
这不是一个正常的可执行程序。当您编写内核模块时,您正在扩展内核功能。您需要告诉内核这一点,通常是通过 insmod
调用。例如,
insmod chardev.ko
然后创建对应的字符设备:
mknod /dev/chardev c 60 0 # 60 being your MAJOR_DEVICE_NUMBER
然后您可以创建自己的程序来读取
和写入
您的字符设备。或者,您可以使用现有的用户空间工具:
echo "12345678" > /dev/chardev # write to the device
并且,
cat /dev/chardev # read from the device
关于c - 我需要帮助来理解以下用 C 编写的内核模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34704739/