驱动人生(雾

Hello world

hello.c

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("youzhiyuan");

int hello_init(void)
{
    printk(KERN_INFO "Hello World\n");
    return 0;
}

void hello_exit(void)
{
    printk(KERN_INFO "Goodbye World\n");
}

module_init(hello_init);
module_exit(hello_exit);

Makefile

ifneq ($(KERNELRELEASE),)

    obj-m := hello.o

else

    KERN_DIR ?= /usr/src/linux-headers-`uname -r`/
    PWD := $(shell pwd)

default:
	$(MAKE) -C $(KERN_DIR) M=$(PWD) modules

endif


clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

啊,说到这个makefile,它一定得是Makefile啊,我之前是makefile,然后就报错,报一大堆错以至于我一开始直接放弃查找问题了(雾,后来看了第一条报错就看到了,改完一瞬间一条报错都没了,太真实了

Param Array

myparam.c

#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("youzhiyuan");


static char* array[3] = {"1","22","333"};
static int at = 0;
static int n_array;
module_param(at, int, S_IRUGO);
module_param_array(array, charp, &n_array, S_IRUGO);


int my_init(void)
{
    printk(KERN_INFO "init called\n");
    printk(KERN_INFO "array[%d] = %s\n",at, array[at]);
    return 0;
}

void my_exit(void)
{
    printk(KERN_INFO "exit called\n");
}

module_init(my_init);
module_exit(my_exit);

Makefile

ifneq ($(KERNELRELEASE),)

    obj-m := myparam.o

else

    KERN_DIR ?= /usr/src/linux-headers-`uname -r`/
    PWD := $(shell pwd)

default:
	$(MAKE) -C $(KERN_DIR) M=$(PWD) modules

endif


clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

Char Drivers

chardriver.c

#include<linux/init.h>
#include<linux/module.h>
#include<linux/types.h>
#include<linux/cdev.h>
#include<linux/fs.h>
#include<linux/uaccess.h>
#include<linux/slab.h>

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("youzhiyuan");


int i;
dev_t  dev;
int result;
int err;
int major;
struct cdev *my_cdev;
static int param = 100;
module_param(param, int, S_IRUGO);
static char *my_buf;


static ssize_t my_read (struct file *filep, char __user *buf, size_t  count, loff_t *offset)
{
    printk(KERN_INFO "read\n");
    if(count > 4096)
    {
        my_buf = kmalloc(param, GFP_KERNEL);
    }
    else
    {
        my_buf = kmalloc(4096, GFP_KERNEL);
    }
    if(!my_buf)
    {
        printk(KERN_WARNING "Malloc failed\n");
        return -1;
    }
    for(i = 0; i < count; i++)
    {
        my_buf[i] = param;
    }
    
    // printk(KERN_INFO "my_buf[2] = %c", my_buf[2]);
    // printk(KERN_INFO "count = %ld", count);

    result = copy_to_user(buf, my_buf, count);
    if(result)
    {
        printk(KERN_WARNING "copy_to_user fail!\n");
        return result;
    }
    return count;
}

static int my_open(struct inode *inodep, struct file *filep)
{
    printk(KERN_INFO "Open success\n");
    return 0;
}


static const struct file_operations my_fops = {
    .owner = THIS_MODULE,
    .read = my_read,
    .open = my_open,
};


static int __init my_init(void)
{
    if(param > 255)
    {
        printk(KERN_WARNING "Param should smaller than 256");
        return 0;
    }
    printk(KERN_INFO "Will produce \'%c\' infinitely\n",param);

    err = alloc_chrdev_region(&dev, 0, 1, "char_driver");
    major = MAJOR(dev);
    if(err < 0)
    {
        printk(KERN_WARNING "inf: can't get major %d\n", major);
        return err;
    }
    else
    {
        printk(KERN_INFO "Got a device number %d\n", major);
    }
    
    my_cdev = cdev_alloc();
    my_cdev->owner = THIS_MODULE;
    cdev_init(my_cdev, &my_fops);
    err = cdev_add(my_cdev, dev, 1);
    if(err)
    {
        printk(KERN_NOTICE "Error %d adding chardriver\n", err);
        return err;
    }

    return 0;
}

static void  __exit my_exit(void)
{
    if(my_buf)
    {
        kfree(my_buf);
    }
    cdev_del(my_cdev);
    unregister_chrdev_region(dev, 1);
    printk(KERN_INFO "Goodbye\n");
}

module_init(my_init);
module_exit(my_exit);

Makefile

ifneq ($(KERNELRELEASE),)

    obj-m := chardriver.o

else

    KERN_DIR ?= /usr/src/linux-headers-`uname -r`/
    PWD := $(shell pwd)

default:
	$(MAKE) -C $(KERN_DIR) M=$(PWD) modules

endif


clean:
	rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions

test.py

f = open('inf')
print('f.read(10) = ' + f.read(10))

test.sh

make
insmod chardriver.ko param=98
dmesg | tail -n 1
mknod inf c 244 0
python test.py
rmmod chardriver
dmesg | tail

说点什么

avatar

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

  Subscribe  
提醒