内核模块开发学习笔记(一)

1.内核有很多模块构成,称为内核模块;
2.驱动程序是一种内核模块,通常是直接访问硬件的内核模块;
3.应用程序无法直接访问底层,只能进行系统调用。
在这里插入图片描述
4.内核模块中不能调用c库函数,只能调用其他内核模块导出的函数。
比如:printk(),在头文件<linux/kernel.h>中,用法和printf类似,但是不能处理浮点数,内核中,一般不处理浮点数。
(1)应用程序通常在/usr/include
(2)驱动程序头文件路径
在这里插入图片描述

5.驱动有两种形态
(1)直接编译到内核;
在内核启动时,该驱动就被自动加载了,并且不能卸载。
Makefile中是obj-m:=hello.o
(2)编译成模块*.ko文件,如果只以 . ko文件,可以不开发源代码。
Makefile中是obj-y:=hello.o
在需要时加载(insmod)到内核中,不用时可以卸载(rmmod)掉。lsmod查看加载的模块
6.加载卸载
在这里插入图片描述
7.
(1)如果以*.ko模块存在,可以在需要时加载到内核,不用时卸载调
驱动有一个加载函数和卸载函数
当模块被加载到内核时,会自动调用加载函数
当模块从内核中移除时,会自动调用卸载函数
(2)
如果驱动被直接编译到内核,内核启动时会自动调用加载函数,不能卸载,此时卸载没有用。
__init是说明将该函数放到一个特殊的段中,当内核启动时,自动调用该函数,只执行一次,当内核启动完成,可以将该段空间释放掉。
__exit是说明将该函数放弃,不要编译。
8.
我们在开发驱动时,多数应该使用*.ko形式,只有当已经测试完肯定没有问题了,又很重要的驱动,才会将他们直接编译到内核中。
9.如何编译模块
由于驱动是在内核的一部分,我们需要用到内核源代码编译系统。
(1)在ubuntu上编译
这种情况下我们需要ubuntu的内核源代码编译系统。
在/usr/src/目录下,使用uname -r,显示的是哪个目录再进入。
在这里插入图片描述
在/usr/src/linux-headers-4.15.0-126-generic下面有Ubuntu内核的部分源码;
同时在/lib/modules/4.15.0-126-generic/build下面也有。
通常使用在/lib/modules/4.15.0-126-generic/build的编译系统来编译

代码示例

#include<linux/kernel.h>
#include<linux/module.h>

MODULE_LICENSE("GPL"); //指定本模块所遵循的协议(GPL协议)

int __init init_module(void)
{
	printk("hello world\n");
	return 0;
}
void __exit cleanup_module(void)
{
	printk("goodbye world\n");
}

Makefile示例

obj-m:=hello.o //指定编译那个文件(hello.c)

编译命令:

make -C /lib/modules/4.15.0-126-generic/build M=$(pwd) modules

-C是指定编译系统的路径
-M是表示要回到当程序所在路径。
执行结果
在这里插入图片描述
ubuntu中的printk的信息不会直接打印出来,需要我们运行dmesg来查看。

10.写一个复杂的makefile

ifeq ($(KERNELRELEASE),)    #判断$(KERNELRELEASE)是否定义,为空就是未定义,他是在内核源码中被定义,现在为空;内核源码目录中的Makefile会定义KERNELRELEASE
        KERNELDIR ?= /lib/modules/$(shell uname -r)/build  #KERNELDIR 记录了内核源码的路径
        PWD := $(shell pwd) # PWD记录当前路径
default:
        $(MAKE) -C $(KERNELDIR) M= $(PWD) modules   #$(MAKE)就是执行make,M=$(PWD)意思是当生成模块时,回到当前目录继续编译,因为我们的*.c在当前目录;
clean:
	rm -rf .*.cmd *.ko *.o *.o. *.mod.* module* Module* .tmp*
else
	obj-m := hello.o
endif
ifneq  ($(KERNELRELEASE),)
obj-m:=hello.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD:=$(shell pwd)
all:
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ko *.o *.symvers *.cmd *.cmd.o
endif

现在直接make就行了。
Makefile参考链接
(2)在开发板上如何编译
将Makefile里ubuntu的编译系统的路径修改成开发板上对应的内核源代码的路径.
将*.ko复制到开发板的根文件系统,运行insmod就可以加载了。
运行lsmod查看加载的模块;
开发板上直接rmmod hello移除不了,这个是busybox的问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

<( ̄︶ ̄)Okay.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值