首页 > 代码库 > 驱动开发之路——1.1

驱动开发之路——1.1

一、什么是模块:

     模块(module)是在内核空间运行的程序,实际上是一种目标对象文件,没有链接,不能独立运行,但是可以装载到系统中作为内核的一部分运行,从而可以动态扩充内核的功能。模块最主要的用处就是用来实现设备驱动程序。

使用模块的优点: 
1,将来修改内核时,不必全部重新编译整个内核,可节省不少时间 
2,系统中如果需要使用新模块,不必重新编译内核,只要插入相应的模块即可。

         静态编译,把所需要的功能都编译到linux内核,会导致生成的内核会很大,如果我们要在现有的内核中新增或删除功能,将不得不重新编译内核。

        动态编译,linux提供这样一种机制,称为模块(Module)。此机制的特点是,模块本身不被编译入内核映像,从而控制了内核的大小。内核一旦被加载,它就和内核中的其他部分完全一样。

        在linux中,使用lsmod命令可以获得系统中加载了的所有模块以及模块间的依赖关系,lsmod命令实际上读取并分析"/proc/modules"文件。内核中已加载模块的信息也存在于/sys/module目录下。

        modprobe命令比insmod命令要强大,它在加载某模块时,会同时加载该模块所依赖的其它模块。以modprobe -r filename的方式加载将同时卸载其依赖的模块。


二、简单的内核实例:

实例一:

#include<linux/kernel.h>

#include <linux/init.h>    
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
      printk(KERN_ALERT "Hello,world\n");
      return 0;
}
static void hello_exit(void)
{
      printk(KERN_ALERT "Goodbye,Cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);



实例二:

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kdev_t.h>
#include<linux/cdev.h>
#include<linux/fs.h>

MODULE_LICENSE("GPL");

dev_t devno;   //设备结构体
int major=1000;  //主设备号
int minor=0;   //此设备号
int count=1;   //申请一个设备

int hello_init(void)
{
	int ret;
	devno=MKDEV(major,minor);
	 ret=register_chrdev_region(devno,count,"hello");   //静态申请设备号
	 if(ret)
	 {
		return ret;
		
	 }
	 printk(KERN_INFO "devno register ok\n");
	 return 0;

}

void hello_exit(void)
{
     unregister_chrdev_region(devno,count);  //释放设备号
}

module_init(hello_init);
module_exit(hello_exit);

实例三:

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kdev_t.h>
#include<linux/cdev.h>
#include<linux/fs.h>

MODULE_LICENSE("GPL");

dev_t devno;
int major=1000;
int minor=0;
int count=1;

int hello_init(void)
{
	int ret;

	ret=alloc_chrdev_region(&devno,0,count,"helldyn");  //动态申请设备号
	 if(ret)
	 {
		return ret;
		
	 }
	 printk(KERN_INFO "devno register ok, major = %d ,minor = %d\n",major,minor);

	 return 0;

}

void hello_exit(void)
{
     unregister_chrdev_region(devno,count);
}

module_init(hello_init);
module_exit(hello_exit);


实例四:

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/kdev_t.h>
#include<linux/cdev.h>
#include<linux/fs.h>

MODULE_LICENSE("GPL");

dev_t devno;
int major=1000;
int minor=0;
int count=1;


struct cdev *hello_dev;

struct file_operations hello_ops= {
       .owner = 	THIS_MODULE,
};


int hello_init(void)
{
	int ret;
	devno=MKDEV(major,minor);
	 ret=register_chrdev_region(devno,count,"hello");
	 if(ret)
	 {
		return ret;
		
	 }
	 printk(KERN_INFO "devno register ok\n");

	 hello_dev=cdev_alloc();   //动态获取描述字符设备的结构体
	 if(hello_dev==NULL)
	      return -ENODEV;

	 cdev_init(hello_dev,&hello_ops);//初始化字符设备的结构体
	 hello_dev->owner=THIS_MODULE;
	 ret=cdev_add(hello_dev,devno,count);

	 if(ret)
	 {
		 unregister_chrdev_region(devno,count);
	 }
	 return 0;

}

void hello_exit(void)
{
  	cdev_del(hello_dev);
     unregister_chrdev_region(devno,count);
}

module_init(hello_init);
module_exit(hello_exit);