一、模块
insmod调用module_init
rmmod调用module_exit
module_init(simple_driver_init);
module_exit(simple_driver_exit);
main.c
#include "device_file.h"
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Danil Ishkov, Apriorit");
/*===============================================================================================*/
static int simple_driver_init(void)
{
int result = 0;
printk( KERN_NOTICE "Simple-driver: Initialization started" );
result = register_device();
return result;
}
/*-----------------------------------------------------------------------------------------------*/
static void simple_driver_exit(void)
{
printk( KERN_NOTICE "Simple-driver: Exiting" );
unregister_device();
}
/*===============================================================================================*/
module_init(simple_driver_init);
module_exit(simple_driver_exit);
二、字符设备
register_chrdev
unregister_chrdev
device_file.h
#ifndef DEVICE_FILE_H_
#define DEVICE_FILE_H_
#include
__must_check int register_device(void); /* 0 if Ok*/
void unregister_device(void);
#endif //DEVICE_FILE_H_
device_file.c
#include "device_file.h"
#include
#include
#include
#include
#include
#include
static const char g_s_Hello_World_string[] = "Hello world from kernel mode!\n\0";
static const ssize_t g_s_Hello_World_size = sizeof(g_s_Hello_World_string);
/*===============================================================================================*/
static ssize_t device_file_read(
struct file *file_ptr
, char __user *user_buffer
, size_t count
, loff_t *possition)
{
printk( KERN_NOTICE "Simple-driver: Device file is read at offset = %i, read bytes count = %u"
, (int)*possition
, (unsigned int)count );
if( *possition >= g_s_Hello_World_size )
return 0;
if( *possition + count > g_s_Hello_World_size )
count = g_s_Hello_World_size - *possition;
if( copy_to_user(user_buffer, g_s_Hello_World_string + *possition, count) != 0 )
return -EFAULT;
*possition += count;
return count;
}
/*===============================================================================================*/
static struct file_operations simple_driver_fops =
{
.owner = THIS_MODULE,
.read = device_file_read,
};
static int device_file_major_number = 0;
static const char device_name[] = "Simple-driver";
/*===============================================================================================*/
int register_device(void)
{
int result = 0;
printk( KERN_NOTICE "Simple-driver: register_device() is called." );
result = register_chrdev( 0, device_name, &simple_driver_fops );
if( result < 0 )
{
printk( KERN_WARNING "Simple-driver: can\'t register character device with errorcode = %i", result );
return result;
}
device_file_major_number = result;
printk( KERN_NOTICE "Simple-driver: registered character device with major number = %i and minor numbers 0...255"
, device_file_major_number );
return 0;
}
/*-----------------------------------------------------------------------------------------------*/
void unregister_device(void)
{
printk( KERN_NOTICE "Simple-driver: unregister_device() is called" );
if(device_file_major_number != 0)
{
unregister_chrdev(device_file_major_number, device_name);
}
}
三、实现file_operations
static struct file_operations simple_driver_fops =
{
.owner = THIS_MODULE,
.read = device_file_read,
};
reference: https://www.apriorit.com/dev-blog/195-simple-driver-for-linux-os