Linux驱动编译

1、Linux内核的整体结构非常庞大,包含组件也非常多,使用所需的组件有两种方法:

(1)编译为内核模块,随时安装,随时卸载。
(2)直接编译进内核。
2、驱动源码和Makefile:
驱动源码:
hello.c

#include 
#include 

static int hello_init(void)
{
    printk(KERN_WARNING"Hello, world !\n");
    return 0;
}
static void hello_exit(void)
{
    printk(KERN_INFO "Goodbye,  world\n");
}
module_init(hello_init);
module_exit(hello_exit);

(1)必须包含头文件:

#include 
#include 

(2)输出必须用 printk(内核空间用),不能用printf(用户空间用)
(3)必须用的两个宏:

module_init(hello_init);        //模块加载函数:hello_init
module_exit(hello_exit);        //模块卸载函数:hello_exit

makefile

ifneq ($(KERNELRELEASE),)

obj-m :=hello.o

else
KDIR:= /lib/modules/3.2.0-61-generic-pae/build
PWD:= /home/shiyan/4-1-2

all:
    make -C $(KDIR) M=$(PWD) modules 
clean:
    rm -f *.ko *.o *.mod.o *.mod.c .symvers

endif

(1)比较KERNELRELEASE与,后边的变量比较。即变量与NULL比较,未定义,也为空,所以不相等。

(2)Obj-m := (源文件名).o
(3)KDIR:=Ubuntu下/lib/modules/(内核版本)/build
Uname-a,查看系统内核版本
(4)PWD:=源码所在目录
进入内核中的makefile,再调用当前makefile编译hello.c成hello.o,内核中makefile定义了KERNELRELEASE
3、模块加载与卸载
加载 insmod (insmod hello.ko)
卸载 rmmod (rmmod hello)
查看 lsmod
加载 modprobe (modprobe hello)

modprobe 如同 insmod, 也是加载一个模块到内核。它的不同之处在于它会根据文件/lib/modules/Ubuntu版本/modules.dep来查看要加载的模块, 看它是否还依赖于其他模块,如果是,modprobe 会首先找到这些模块, 把它们先加载到内核。

动态挂载内核模块:
sudo insmod hello.ko
这里写图片描述
查看已挂载模块
lsmod
这里写图片描述
卸载模块
rmmod hello
这里写图片描述
dmesg 查看输出内容
Linux驱动编译_第1张图片
static 限制函数不能被外部调用

/*
1、许可证申明
宏MODULE_LICENSE用来告知内核, 该模块带有一个许可证,没有这样的说明,加载模块时 内核会抱怨。有效的许可证有”GPL“、”GPL v2”、”GPL and additional rights”、”Dual BSD/GPL”、”Dual MPL/GPL”和”Proprietary”。
2、作者申明(可选)
MODULE_AUTHOR(“Simon Li”);
3、模块描述(可选)
MODULE_DESCRIPTION(“Hello World Module”);
4、模块版本(可选)
MODULE_VERSION(“V1.0”);
5、模块别名(可选)
MODULE_ALIAS(“a simple module”);
*/

你可能感兴趣的:(驱动,Linux)