从头编写linux内核,编写Linux内核模块

#include /* KERN_INFO macros */

#include /* required for all kernel modules */

#include /* module_param() and MODULE_PARM_DESC() */

#include /* struct file_operations, struct file */

#include /* struct miscdevice and misc_[de]register() */

#include /* mutexes */

#include /* memchr() function */

#include /* kzalloc() function */

#include /* wait queues */

#include /* copy_{to,from}_user() */

MODULE_LICENSE("GPL");

MODULE_AUTHOR("your name and email");

MODULE_DESCRIPTION("In-kernel phrase reverser");

//定义接收参数

static unsigned long buffer_size = 8192;

module_param(buffer_size, ulong, (S_IRUSR | S_IRGRP | S_IROTH));

MODULE_PARM_DESC(buffer_size, "Internal buffer size");

//缓存区

struct buffer {

wait_queue_head_t read_queue;

struct mutex lock;

char *data, *end; //data指向缓冲区, end指向结尾后第一个字符

char *read_ptr; //read()开始读取数据的地方

unsigned long size; //保证完整性

};

static struct buffer *buffer_alloc(unsigned long size)

{

struct buffer *buf = NULL;

buf = kzalloc(sizeof(*buf), GFP_KERNEL); //注意是kzalloc()

if (unlikely(!buf))

goto out;

buf->data = kzalloc(size, GFP_KERNEL);

if (unlikely(!buf->data))

goto out_free;

init_waitqueue_head(&buf->read_queue);

mutex_init(&buf->lock);

/* It's unused for now, but may appear useful later */

buf->size = size;

out:

return buf;

out_free:

kfree(buf);

return NULL;

}

static void buffer_free(struct buffer *buffer)

{

kfree(buffer->data);

kfree(buffer);

}

static inline char *reverse_word(char *start, char *end) //真正工作的函数

{

char *orig_start = start, tmp;

for (; start < end; start++, end--) {

tmp = *start;

*start = *end;

*end = tmp;

}

return orig_start;

}

static char *reverse_phrase(char *start, char *end)

{

char *word_start = start, *word_end = NULL;

while ((word_end = memchr(word_start, ' ', end - word_start)) != NULL) {

reverse_word(word_start, word_end - 1);

word_start = word_end + 1;

}

reverse_word(word_start, end);

return reverse_word(start, end);

}

static int reverse_open(struct inode *inode, struct file *file)

{

struct buffer *buf;

int err = 0;

/*

* Real code can use inode to get pointer to the private

* device state.

*/

buf = buffer_alloc(buffer_size);

if (unlikely(!buf)) {

err = -ENOMEM;

goto out;

}

file->private_data = buf;

out:

return err;

}

static ssize_t reverse_read(struct file *file, char __user * out,

size_t size, loff_t * off) //从内核缓冲区复制数据到用户空间

{

struct buffer *buf = file->private_data;

ssize_t result;

if (mutex_lock_interruptible(&buf->lock)) {

result = -ERESTARTSYS;

goto out;

}

while (buf->read_ptr == buf->end) {

mutex_unlock(&buf->lock);

if (file->f_flags & O_NONBLOCK) { //检查以非阻塞模式打开文件,如果没有数据就返回EAGAIN

result = -EAGAIN;

goto out;

}

if (wait_event_interruptible

(buf->read_queue, buf->read_ptr != buf->end)) { //被中断

result = -ERESTARTSYS;

goto out;

}

if (mutex_lock_interruptible(&buf->lock)) {

result = -ERESTARTSYS;

goto out;

}

}

size = min(size, (size_t) (buf->end - buf->read_ptr));

if (copy_to_user(out, buf->read_ptr, size)) { //复制数据到用户空间

result = -EFAULT;

goto out_unlock;

}

buf->read_ptr += size;

result = size;

out_unlock:

mutex_unlock(&buf->lock);

out:

return result;

}

static ssize_t reverse_write(struct file *file, const char __user * in,

size_t size, loff_t * off) //

{

struct buffer *buf = file->private_data;

ssize_t result;

if (size > buffer_size) { //检查是否有足够空间

result = -EFBIG;

goto out;

}

if (mutex_lock_interruptible(&buf->lock)) {

result = -ERESTARTSYS;

goto out;

}

if (copy_from_user(buf->data, in, size)) { //获取数据

result = -EFAULT;

goto out_unlock;

}

buf->end = buf->data + size;

buf->read_ptr = buf->data;

if (buf->end > buf->data)

reverse_phrase(buf->data, buf->end - 1); //反转

wake_up_interruptible(&buf->read_queue); //唤醒read_queue中等待的进程

result = size;

out_unlock:

mutex_unlock(&buf->lock);

out:

return result;

}

static int reverse_close(struct inode *inode, struct file *file)

{

struct buffer *buf = file->private_data;

buffer_free(buf);

return 0;

}

//模块接入点

static struct file_operations reverse_fops = {

.owner = THIS_MODULE,

.open = reverse_open,

.read = reverse_read,

.write = reverse_write,

.release = reverse_close,

.llseek = noop_llseek

};

//注册设备

static struct miscdevice reverse_misc_device = {

.minor = MISC_DYNAMIC_MINOR,

.name = "reverse",

.fops = &reverse_fops

};

static int __init (void) //模块插入

{

if (!buffer_size)

return -1;

misc_register(&reverse_misc_device); //注册

printk(KERN_INFO

"reverse device has been registered, buffer size is %lu bytesn",

buffer_size);

return 0;

}

static void __exit reverse_exit(void) //模块删除

{

misc_deregister(&reverse_misc_device); //注销

printk(KERN_INFO "reverse device has been unregisteredn");

}

module_init(reverse_init); //插入

module_exit(reverse_exit); //删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值