设备驱动(一)

驱动是模块程序,模块程序不一定都是驱动
模块三要素
  1. 模块许可声明
    1. MODULE_LICENSE("GPL");
  2. 加载函数
    1. 默认是int init_module(void)
    2. 成功返回0
    3. 失败返回负数错误码
  3. 卸载函数
    1. 默认是void cleanup_module(void)
模块与应用程序的区别
 modulesapp
运行空间内核空间用户空间
程序入口加载函数main函数
资源管理自己申请与回收系统自动申请与回收

模块编译与运行的两个前提条件:
  1. 使用配置并编译后的内核源码
  2. 编译模块所用内核版本必须与运行模块时内核版本一致
模块编译
     进入模块源码目录,执行make
     Makefile    如下:
ifeq ($(KERNELRELEASE),)

#KERNELDIR ?= /home/lht/kernel2.6/linux-2.6.14

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

modules:
     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install

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

.PHONY: modules modules_install clean

else
    obj-m := hello.o
    hello-objs := hello.c
endif
格式
     obj-m := <finall_module>.o
     <finall_module>-m := <module1>.c <module2>.c ...
静态编译模块与动态编译模块
 静态编译模块动态编译模块
编译方式以<*>方式编译模块以<M>方式编译模块
模块加载时间在kernel启动时加载需要时由用户加载
模块存放位置zImage中以.ko方式存在模块

内部模块与外部模块
 内部模块外部模块
编译方式在kernel目录下 make module,动态编译模块目录下 make,动态编译
模块编译位置模块位于kernel源码内部模块在kernel源码外部
加载方式modprobe,insmodinsmod
卸载方式modprobe -r,rmmodrmmod
模块依赖度会有模块依赖很少有模块依赖
modinfo:intreeY没有该项
modprobe 在加载与卸载时,能够根据kernel源码下的modules.dep,modules.dep.bin处理依赖
insmod,rmmod 不能处理模块依赖,需要手动解决模块依赖
modprobe在加载模块时,先加载依赖的模块,再加载指定的模块
modprobe在卸载模块时,如果当前模块没有被依赖,先卸载该模块,再检查依赖,如果其依赖没有被别的依赖,则该模块也被卸载。

模块代码格式
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("xufeng");
MODULE_DESCRIPTION("hello device");
MODULE_SUPPORTED_DEVICE("testdevice");

static int __init hello_init(void) {
     printk("hello world\n");
     return 0;
}
static void __exit hello_exit(void) {
     printk("goodbye world\n");
}
module_init(hello_init);
module_exit(hello_exit);

引入指定的kernel头文件
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
指定加载模块的加载,卸载函数
module_init ();
module_exit ();
__init关键字效果
静态加载时,添加到kernel的.init初始化段,之后不能被卸载
动态加载时,无效果
__exit关键字效果
静态加载时,不编译,因为静态编译的模块不能卸载
动态加载时,无效果
static关键字效果
          防止函数名重复
添加模块详细信息
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lvxinliang sciencelxl@gmail.com");
MODULE_DESCRIPTION("hello device");
MODULE_SUPPORTED_DEVICE("testdevice");
模块导出符号表
EXPORT_SYMBOL(符号名);
EXPORT_SYMBOL(符号名);

Linux内核模块的程序结构
  • 模块加载函数
  • 模块卸载函数
  • 模块许可声明
  • 模块参数
  • 模块导出符号
  • 模块作者等信息声明

有关命令
查看内核打印信息
     dmesg         显示消息
     dmesg -c     清空消息
加载模块
     insmod <模块名.ko>
     modprobe <模块名>
列出所有加载的模块
     lsmod 
卸载模块
     rmmod <模块名>
     modprobe -r <模块名>
查看模块详细信息
     modinfo <模块文件名>
查看内核符号表
     cat  /proc/kallsyms


     
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值