Linux驱动的编写,大致分为两个过程,第一个过程为测试阶段,即为某一具体的设备,添加必要的驱动模块,为了节省编译时间,需要将代码单独放在一处,在编译时,只需要要调用内核的头文件即可;第二个过程为布置阶段,即为某一具体设备,添加完整、可靠的驱动模块,即该过程将驱动模块编译到内核镜像文件中,它需要将驱动模块的代码,添加到内核源码树中。
阶段一:
1 编写测试文件
#include "linux/init.h"
#include "linux/module.h"
static __init int hello_init(void)
{
printk(KERN_ALERT"Hello World linux-driver-modulen");//注意,必须是KERN_ALEAT及以上级别,不然不会打印
return 0;
}
static __exit void hello_exit(void)
{
printk(KERN_ALERT"Goodbye linux-driver-modulen");
return 0;
}
module_init(hello_init);
module_exit(hello_init);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("gjianw217@163.com");
ps:
(1)init.h 定义了驱动的初始化和退出相关的函数,几乎每个linux驱动都有个module_init(与module_exit的定义在Init.h (includelinux) 中)。
(2)module.h 定义了内核模块相关的函数、变量及宏。 如上面的MODULE_LICENSE("GPL")和 MODULE_AUTHOR("gjianw217@163.com")。其MODULE_LICENSE指定许可,必须指定;MODULE_AUTHOR,声明作者;还有MODULE_DESCRIPTION,对这个模块作一个简单的描述,这个描述是"human-readable"的;MODULE_VERSION,模块的版本;MODULE_ALIAS,模块的别名;MODULE_DEVICE_TABLE,告诉用户空间这个模块支持什么样的设备等。
2 编写Makefile文件
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
obj-m := demo.o
KDIR := /home/rabbit/bbg/kernel-for-BBB/
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
ps:
(1)这个Makefile算是一个通用的模板,其中CROSS_COMPILE和APP_COMPILE=arm-linux-指定交叉编译器的位置,obj-m指定驱动模块的目标文件(如将驱动模块命令为app-drv.c,则此处应该为app-drv.o);KDIR指定内核的位置。
(2)当执行make时,进行内核模块的编译;当执行make app时,进行应用测试程序的编译;当执行make clean时,删除编译的过程文件。
3 加载运行
阶段二:
1 将驱动代码按类型放到内核源码树相应目录下(drivers/demo/demo.c)
2 在当前目录下,分别添加编译文件在driver/demo/Makefile文件里
#driver module demo
obj-$(CONFIG_HELLODRV) += hello.o
在driver/demo/Kconfig文件里
menu USER_DEVICE_DRIVERS//4中可以看到它
config HELLODRV
tristate "Hello"
help
This is a demo driver programming.
endmenu
3 修改上层目录文件,将其添加到内核中
在driver/Makefile文件里
obj-$(CONFIG_HELLODRV)+=demo
在文件里driver/Kconfig 里
source drivers/demo/Kconfig
在arch/arm/Kconfig文件里
source "drivers/demo/Kconfig"
4 进行系统配置并编译
make menuconfig
make
5 加载内核镜像文件到板上,使用命令检查
lsmod dmesg
Linux驱动的编写,大致分为两个过程,第一个过程为测试阶段,即为某一具体的设备,添加必要的驱动模块,为了节省编译时间,需要将代码单独放在一处,在编译时,只需要要调用内核的头文件即可;第二个过程为布置阶段,即为某一具体设备,添加完整、可靠的驱动模块,即该过程将驱动模块编译到内核镜像文件中,它需要将驱动模块的代码,添加到内核源码树中。
阶段一:
1 编写测试文件
#include "linux/init.h"
#include "linux/module.h"
static __init int hello_init(void)
{
printk(KERN_ALERT"Hello World linux-driver-modulen");//注意,必须是KERN_ALEAT及以上级别,不然不会打印
return 0;
}
static __exit void hello_exit(void)
{
printk(KERN_ALERT"Goodbye linux-driver-modulen");
return 0;
}
module_init(hello_init);
module_exit(hello_init);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("gjianw217@163.com");
ps:
(1)init.h 定义了驱动的初始化和退出相关的函数,几乎每个linux驱动都有个module_init(与module_exit的定义在Init.h (includelinux) 中)。
(2)module.h 定义了内核模块相关的函数、变量及宏。 如上面的MODULE_LICENSE("GPL")和 MODULE_AUTHOR("gjianw217@163.com")。其MODULE_LICENSE指定许可,必须指定;MODULE_AUTHOR,声明作者;还有MODULE_DESCRIPTION,对这个模块作一个简单的描述,这个描述是"human-readable"的;MODULE_VERSION,模块的版本;MODULE_ALIAS,模块的别名;MODULE_DEVICE_TABLE,告诉用户空间这个模块支持什么样的设备等。
2 编写Makefile文件
ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
obj-m := demo.o
KDIR := /home/rabbit/bbg/kernel-for-BBB/
PWD := $(shell pwd)
default:
make -C $(KDIR) M=$(PWD) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
ps:
(1)这个Makefile算是一个通用的模板,其中CROSS_COMPILE和APP_COMPILE=arm-linux-指定交叉编译器的位置,obj-m指定驱动模块的目标文件(如将驱动模块命令为app-drv.c,则此处应该为app-drv.o);KDIR指定内核的位置。
(2)当执行make时,进行内核模块的编译;当执行make app时,进行应用测试程序的编译;当执行make clean时,删除编译的过程文件。
3 加载运行
阶段二:
1 将驱动代码按类型放到内核源码树相应目录下(drivers/demo/demo.c)
2 在当前目录下,分别添加编译文件在driver/demo/Makefile文件里
#driver module demo
obj-$(CONFIG_HELLODRV) += hello.o
在driver/demo/Kconfig文件里
menu USER_DEVICE_DRIVERS//4中可以看到它
config HELLODRV
tristate "Hello"
help
This is a demo driver programming.
endmenu
3 修改上层目录文件,将其添加到内核中
在driver/Makefile文件里
obj-$(CONFIG_HELLODRV)+=demo
在文件里driver/Kconfig 里
source drivers/demo/Kconfig
在arch/arm/Kconfig文件里
source "drivers/demo/Kconfig"
4 进行系统配置并编译
make menuconfig
make
5 加载内核镜像文件到板上,使用命令检查
lsmod dmesg