1. hello world(.ko)
/ lib/ modules/ 3.10 .0 - 327. el7. x86_64/ build/ include/ linux
#include <linux/init.h>
#include <linux/module.h>
static int hello_init ( void )
{
printk ( KERN_ALERT "hello world\n" ) ;
return 0 ;
}
static void hello_exit ( void )
{
printk ( KERN_ALERT "goodbye world\n" ) ;
}
module_init ( hello_init) ;
module_exit ( hello_exit) ;
2. Makefile(.ko)
obj- m: = hello. o
KDIR: = / lib/ modules/ $( shell uname - r) / build
PWD: = $( shell pwd)
default :
$( MAKE) - C $( KDIR) M= $( PWD) modules
3. insmod / rmmod
INSMOD ( 8 ) insmod INSMOD ( 8 )
NAME
insmod - Simple program to insert a module into the Linux Kernel
SYNOPSIS
insmod [ filename] [ module options. . . ]
RMMOD ( 8 ) rmmod RMMOD ( 8 )
NAME
rmmod - Simple program to remove a module from the Linux Kernel
SYNOPSIS
rmmod [ - f] [ - s] [ - v] [ modulename]
4. dmesg
DMESG ( 1 ) User Commands DMESG ( 1 )
NAME
dmesg - print or control the kernel ring buffer
SYNOPSIS
dmesg [ options]
dmesg -- clear
dmesg -- read- clear [ options]
dmesg -- console- level level
dmesg -- console- on
dmesg -- console- off
5. 设备的主、次编号
if ( scull_major)
{
dev = MKDEV ( scull_major, scull_minor) ;
result = register_chrdev_region ( dev, scull_nr_devs, "scull" ) ;
}
else
{
result = alloc_chrdev_region ( & dev, scull_minor, scull_nr_devs, "scull" ) ;
scull_major = MAJOR ( dev) ;
}
if ( result < 0 )
{
printk ( KERN_WARNING "scull: can't get major %d\n" , scull_major) ;
return result;
}
6. 文件系统相关操作(如何打开、读、写、关闭设备)
struct file_operations {
struct module * owner;
loff_t ( * llseek) ( struct file * , loff_t, int ) ;
ssize_t ( * read) ( struct file * , char __user * , size_t, loff_t * ) ;
ssize_t ( * write) ( struct file * , const char __user * , size_t, loff_t * ) ;
ssize_t ( * aio_read) ( struct kiocb * , const struct iovec * , unsigned long , loff_t) ;
ssize_t ( * aio_write) ( struct kiocb * , const struct iovec * , unsigned long , loff_t) ;
int ( * readdir) ( struct file * , void * , filldir_t) ;
unsigned int ( * poll) ( struct file * , struct poll_table_struct * ) ;
long ( * unlocked_ioctl) ( struct file * , unsigned int , unsigned long ) ;
long ( * compat_ioctl) ( struct file * , unsigned int , unsigned long ) ;
int ( * mmap) ( struct file * , struct vm_area_struct * ) ;
int ( * open) ( struct inode * , struct file * ) ;
int ( * flush) ( struct file * , fl_owner_t id) ;
int ( * release) ( struct inode * , struct file * ) ;
int ( * fsync) ( struct file * , loff_t, loff_t, int datasync) ;
int ( * aio_fsync) ( struct kiocb * , int datasync) ;
int ( * fasync) ( int , struct file * , int ) ;
int ( * lock) ( struct file * , int , struct file_lock * ) ;
ssize_t ( * sendpage) ( struct file * , struct page * , int , size_t, loff_t * , int ) ;
unsigned long ( * get_unmapped_area) ( struct file * , unsigned long , unsigned long , unsigned long , unsigned long ) ;
int ( * check_flags) ( int ) ;
int ( * flock) ( struct file * , int , struct file_lock * ) ;
ssize_t ( * splice_write) ( struct pipe_inode_info * , struct file * , loff_t * , size_t, unsigned int ) ;
ssize_t ( * splice_read) ( struct file * , loff_t * , struct pipe_inode_info * , size_t, unsigned int ) ;
RH_KABI_REPLACE ( int ( * setlease) ( struct file * , long , struct file_lock * * ) , int ( * setlease) ( struct file * , long , struct file_lock * * , void * * ) )
long ( * fallocate) ( struct file * file, int mode, loff_t offset,
loff_t len) ;
int ( * show_fdinfo) ( struct seq_file * m, struct file * f) ;
} ;
struct file_operations scull_fops = {
. owner = THIS_MODULE,
. llseek = scull_llseek,
. read = scull_read,
. write = scull_write,
. ioctl = scull_ioctl,
. open = scull_open,
. release = scull_release,
} ;
7. 注册字符设备
#ifndef _LINUX_CDEV_H
#define _LINUX_CDEV_H
#include <linux/kobject.h>
#include <linux/kdev_t.h>
#include <linux/list.h>
struct file_operations;
struct inode;
struct module;
struct cdev {
struct kobject kobj;
struct module * owner;
const struct file_operations * ops;
struct list_head list;
dev_t dev;
unsigned int count;
} ;
void cdev_init ( struct cdev * , const struct file_operations * ) ;
struct cdev * cdev_alloc ( void ) ;
void cdev_put ( struct cdev * p) ;
int cdev_add ( struct cdev * , dev_t, unsigned ) ;
void cdev_del ( struct cdev * ) ;
void cd_forget ( struct inode * ) ;
extern struct backing_dev_info directly_mappable_cdev_bdi;
8. 未完待续 …