【发布时间】:2016-01-10 11:16:25
【问题描述】:
作为一项作业,我需要完成以下 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 程序中使用的函数集合?
如果这些问题看起来很愚蠢,我很抱歉,但我不知道我应该如何解决这个问题。
【问题讨论】:
-
太宽泛了。 SO 不是“解释代码”网站。
-
第一步是了解内核模块是什么。这应该可以清除一堆东西。
-
@Mat 这就是我过去 2 天一直在尝试做的事情。
-
@Olaf 我应该编辑它还是有这样一个“解释代码”的网站?
-
您阅读了哪些有关 Linux 内核模块的书籍和网站?