Makefile
TARGET := hello_drv
obj-m += $(TARGET).o
ROOTFS = /home/flinn/smart210-SDK/fs/drv
KERNEL = /home/flinn/smart210-SDK/linux-3.10.79
all:
make -C $(KERNEL) M=`pwd` modules
clean:
make -C $(KERNEL) M=`pwd` clean
install:
sudo cp $(TARGET).ko $(ROOTFS)
make.sh
#!/bin/bash
echo -e "\e[1;31m##make clean \e[0m"
make clean
echo -e "\e[1;31m##make \e[0m"
make
echo -e "\e[1;31m##make install \e[0m"
make install
hello_drv.c
/*
* linux-3.10.27
* arm-linux-gcc-4.5.1
*
* @ hello driver
*/
#include <linux/module.h>
#include <linux/init.h> /* module_init, ... */
#include <linux/kernel.h> /* everything */
#include <linux/cdev.h> /* cdev_init, ... */
#include <linux/fs.h> /* file_operations, */
#include <linux/device.h> /* class_create,... */
#define DEVICE_NAME "hello"
struct priv_data
{
char *name;
int major;
dev_t dev;
struct cdev *cdev;
struct class *pri_class;
};
static struct priv_data priv_data;
static int hello_open (struct inode *inode, struct file *file)
{
return 0;
}
static int hello_close (struct inode *inode, struct file *file)
{
return 0;
}
const struct file_operations ops = {
.owner = THIS_MODULE,
.open = hello_open,
.release = hello_close,
};
static int hello_drv_init(void)
{
int ret = 0;
pr_info("%s called . \n", __func__);
priv_data.name = DEVICE_NAME;
if(priv_data.major)
{
priv_data.dev = MKDEV(priv_data.major, 0);
ret = register_chrdev_region(priv_data.dev, 1, priv_data.name);
}
else
{
ret = alloc_chrdev_region(&priv_data.dev, 0, 1, priv_data.name);
priv_data.major = MAJOR(priv_data.dev);
}
if(ret < 0)
{
pr_err("chrdev register fail.\n");
return ret;
}
/* add cdev */
priv_data.cdev = cdev_alloc();
if(!priv_data.cdev){
pr_err("cdev alloc fail.\n");
goto cdev_err;
}
cdev_init(priv_data.cdev, &ops);
priv_data.cdev->owner = THIS_MODULE;
priv_data.cdev->ops = &ops;
cdev_add(priv_data.cdev, priv_data.dev, 1);
/* add class */
priv_data.pri_class = class_create(THIS_MODULE, priv_data.name);
ret = PTR_ERR(priv_data.pri_class);
if(IS_ERR(priv_data.pri_class))
{
goto class_err;
}
return 0;
class_err:
cdev_del(priv_data.cdev);
cdev_err:
unregister_chrdev_region(priv_data.dev, 1);
return -EFAULT;
}
static void hello_drv_exit(void)
{
pr_info("%s called . \n", __func__);
class_destroy(priv_data.pri_class);
cdev_del(priv_data.cdev);
unregister_chrdev_region(priv_data.dev, 1);
}
module_init(hello_drv_init);
module_exit(hello_drv_exit);
MODULE_LICENSE("GPL");