linux驱动程序开发 1

linux驱动程序分成三类:字符设备,块设备,网络设备。

字符设备:能像字节流一样访问的设备,通过/dev下的字符设备文件来访问。

块设备:按照块为单位来访问数据,比如一块为512KB,是通过/dev下的文件系统节点来访问的。与字符设备的区别是接口不同,除了提供同字符设备一样的接口外,还提供专门面向块设备的接口,块设备必须支持挂装文件系统,应用程序一般通过文件系统来访问块设备上的内容,而不是直接跟块设备打交道。

网络设备:不使用/dev下的文件节点来操作,而是通过单独的网络接口eth0、eth1等来操作。内核和网络设备的接口不同于字符和块设备,有一套专门的函数。


操作模块的命令:

1 insmod  加载模块

   #sudo insmod ./scull.ko

2 rmmod 卸载模块

3 lsmod 列出当前内核使用的模块,或者查看/proc/modules文件

4 depmod 扫描/lib/modules/<kernel version>/目录下的所有内核模块,从而给内核模块生成依赖文件/lib/modules/<kernel version>/modules.dep

5 modprobe 根据depmod生成的modules.dep探测并加载内核模块,只需要给出模块名称自动寻找适合的模块文件,insmod需要给出模块的路径

6 modinfo 查看模块文件的基本信息

   #sudo modinfo scull.ko


内核模块的编译方法:

首先要得到内核源代码,并且成功的编译过后生成已编译过的内核源码树,即成功执行过make uImage的内核源码树。然后编写驱动代码后,如果已编译的内核源码树就是此驱动需要运行的内核,则编写Makefile即可将模块代码编译成模块:

ifeq($(KERNELRELEASE),)

  KERNELDIR ?= /work/sysbuild/linux-2.6.22.6

  PWD:=$(shell pwd)

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

else

  obj-m:=hello.o

endif

执行make即可

其中已编译内核源码树目录为:/work/sysbuild/linux-2.6.22.6,模块obj为hello.o,编译后生成hello.ko


最简单的模块例子:

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

stataic int hello_init(void)

{

  printk("hello world\r\n");

  return 0;

}

static void hello_exit(void)

{

  printk("goodbye,cruel world\r\n");

}

module_init(hello_init);

module_exit(hello_exit);


可以加载模块时传入参数,使用宏module_param(变量名,变量类型,权限)声明参数,模块运行期间,参数变量会以文件形式出现在/sys目录下,例如#ls /sys/module/hello/parameters/ -l

变量类型有:short,ushort,int,uint,long,ulong,charp,bool

使用方法:

static char *chp="test_char_p";

static int num=1;

module_param(num, int, S_IRUGO|S_IWUSR);

module_param(chp, charp, S_IRUGO);

#insmod hello.ko num=3 chp="test"


把模块集成到内核

1 确保模块工作正常

2 把模块文件hello.c复制到内核的指定目录,例如/drivers/char

3 修改指定目录的Kconfig和Makefile

   Kconfig:  config HELLO tristate "New Hello"

   Makefile:  obj -$(CONFIG_HELLO) += hello.o

4 重新配置内核选中将功能编译进内核,而不是编译成模块

5 重新编译内核,得到新内核

6 测试新内核,确保内核模块集成成功


查看系统的设备:

1 查看系统中的字符设备驱动,块设备驱动及其主设备号

   #cat /proc/devices

2 查看系统的启动信息

  #dmesg

3 查看设备的IO内存物理地址

  #cat /proc/iomem

4 查看正在使用的中断号

  #cat /proc/interrupts


字符设备驱动体验:

#insmod ./scull.ko

#cat /proc/devices|grep scull

252 scull

#sudo mknod scull0 c 252 0

#sudo chmod 666 scull0

#cat scull0

#sudo echo test>>scull0

#cat scull0

装载scull.ko后寻找这个设备的主设备号,创造这个设备的设备文件(c代表字符设备,0代表第一个从设备号),更改文件属性后操作设备



发布了30 篇原创文章 · 获赞 21 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/oushaojun2/article/details/62871412