块设备: blkdev,可寻址,寻址以块为单位,典型的块设备是硬板。
字符设备:cdev,不可寻址,应用程序直接访问设备节点与之通信。
网络设备:ethernet ,通过套接字API的特殊接口来访问。
模块:内核在运行时插入或者删除一些二进制镜像。
一个内核模块必备的要素:
1,module_init(); 模块在被内核加载的时候来调用。
2,module_exit(); 模块在被卸载的时候调用。
/* hello-2.c - Demonstrating the module_init() and module_exit() macros. This is the
* preferred over using init_module() and cleanup_module().
*
* Copyright (C) 2001 by Peter Jay Salzman
*
* 08/02/2006 - Updated by Rodrigo Rubira Branco <rodrigo@kernelhacking.com>
*/
/* Kernel Programming */
#include <linux/module.h> // Needed by all modules
#include <linux/kernel.h> // Needed for KERN_ALERT
#include <linux/init.h> // Needed for the macros
static int hello_2_init(void)
{
printk(KERN_ALERT "Hello, world 2\n");
return 0;
}
static void hello_2_exit(void)
{
printk(KERN_ALERT "Goodbye, world 2\n");
}
module_init(hello_2_init);
module_exit(hello_2_exit);
MODULE_LICENSE("GPL");
构建模块:
1.模块放在内核源码中。
这时候要清楚模块放在内核中的哪里?字符设备驱动程序放在/driver/char 目录下,块设备放在/driver/block目录下面。
以hello,world 程序为例,字符设备驱动:
(1)新建hello 目录 hello.c 放在driver/char/hello 目录下面。
(2)修改driver/char/ 下面的makefile, 这个makefile 在hello目录的上一级的目录里面。
在这个Makefile 里面加入一句:
obj-$(CONFIG_HELLO) += hello/ (这一句实际上是配置图形界面的驱动选择,用来选择驱动程序编译到内核中,或者以模块的形式来编译,执行make menuconfig 的时候便会看到)
(3)在/driver/char/hello 下面建立Makefile 文件
obj-$(CONFIG_HELLO) += hello.o
2.模块放在内核源码外。
这个比较简单:
(1)在源码树中建立Makefile 文件。
obj-m := hellomodule.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm *.o *.ko *.mod.c Modules.symvers modules.order -f
(2)sudo make
(3) 加载内核模块
sudo insmod hello.ko 这里是ko后缀
(4)检验模块是否加载如内核
lsmod
(5)卸载模块
sudo rmmod hello hello无后缀