想要学习linux驱动,首先要知道,
linux对文件的操作方式(read、write、ioctl),
模块的相关知识(ko的编译和安装),
内核空间与用户空间内存
在linux中模块的编写需要符合一定的规范,
ko安装后会一直存在于内核中,直到被卸载
在安装时,需要对模块的资源进行初始化,如内存分配、gpio的申请等,一般都会放在模块的初始化函数中,然后通过module_init调用,初始化函数的原型如下:
static int __init init(void)
同样在退出时,有个对应的退出函数,用于资源的释放
static void __exit exit(void)
linux对文件的操作方式(read、write、ioctl),
模块的相关知识(ko的编译和安装),
内核空间与用户空间内存
一、模块的编写
在linux中模块的编写需要符合一定的规范,
ko安装后会一直存在于内核中,直到被卸载
在安装时,需要对模块的资源进行初始化,如内存分配、gpio的申请等,一般都会放在模块的初始化函数中,然后通过module_init调用,初始化函数的原型如下:
static int __init init(void)
同样在退出时,有个对应的退出函数,用于资源的释放
static void __exit exit(void)
下面是一个简单的例子,基本上什么用处也没有
#include <linux/module.h> /*它定义了模块的 API、类型和宏(MODULE_LICENSE、MODULE_AUTHOR等等),所有的内核模块都必须包含这个头文件。*/
#include <linux/init.h>
static int __init char_init(void)//__init一个标记,表明是初始化函数
{
//初始化的代码
printk("char device driver init \n");
return 0;
}
static void __exit char_exit(void)
{
printk("char device driver exit \n");
}
MODULE_LICENSE("Dual BSD/GPL");
//当模块被加载时,执行moudle_init函数,该函数会调用初始化函数
module_init(char_init);
//模块卸载时,调用,释放资源
module_exit(char_exit);
printk类似于c中的printf,只不过没有参数,要查看它的输出信息,在命令行执行dmseg即可
二、模块的编译
模块的编译非常简单,如果是自己编译的内核话,将 —C 后面换成自己内核的源码路径即可(例如开发板的linux系统)obj-m := CharDeviceDemo.o
KDIR_6410 :=/home/cui/work/kernel/linux-2.6.38
CURRENT_PATH :=$(shell pwd) #模块所在的当前路径
LINUX_KERNEL :=$(shell uname -r) #Linux内核源代码的当前版本
LINUX_KERNEL_PATH :=/usr/src/linux-headers-$(LINUX_KERNEL)
all:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules #编译
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
三、模块的安装和卸载
通过insmod和rmmod命令。