内核模块编写及编译

操作系统

操作系统是运行在硬件层之上的,给应用程序提供运行环境的裸机程序。

目前操作系统有两种典型的内核实现模式:

1、单内核(宏内核):所有子模块代码编译到一个比较大的可执行文件(镜像文件)中。各子模块代码共用同一套运行资源,各模块间的交互直接通过函数调用来进行。如:linux ​

2、微内核:只将任务管理、内存管理、启动管理最其本的三个子模块编译到一个微型可执行文件中。其它子模块则各自编译成独立的后台服务程序,这些服务程序与微型内核以及APP间主要通过各种IPC进行通讯。如:windows ​

Linux是一个单内核,运行在单独的地址空间上。不过,Linux汲取了微内核的精化,具有微内核所所具有的模块化设计、抢占式内核、支持内核线程以及动态装载内核模块的能力。同时,Linux还避免了微内核的设计缺陷,linux让所有模块都运行在内核态,直接调用函数,无须像微内核那样采用消息传递。

内核模块

单独编译的一段内核代码,在需要的时候动态地加载到内核,从而动态地增加内核的功能,在不需要的时候,可以动态地卸载,从而减少内核,并节约一部分内存。而且无论是加载还是卸载都不需要重启整个系统。

模块化的好处:

1、模块本身不被编译到内核镜像里面,可以减小内核体积,节省内存资源。

2、可以在内核中添加或删除功能而不用重新编译内核,解决单内核扩展性差的缺点

3、加载和卸载不重启系统,单独编译,可以提高开发效率

如下为一个模块程序的模板,保存为mod.c

//头文件(必须)
#include <linux/init.h>//初始化头文件
#include <linux/module.h>//模块头文件
​
//加载函数(必须)
static int hello_init(void)//返回值是int类型,函数名自定义,参数是void
{
    printk(KERN_ALERT "Hello World.\n");
    return 0;
}
​
//卸载函数(必须)
static void hello_exit(void)//返回值是void类型,函数名自定义,参数是void
{
     printk(KERN_ALERT "Goodbye World.\n");
}
​
//注册(必须)
module_init(hello_init);//对应加载函数
module_exit(hello_exit);//对应卸载函数
​
//license(必须)
MODULE_LICENSE("Dual BSD/GPL");
​
//作者与描述(可选)
MODULE_AUTHOR("Ono Zhang");
MODULE_DESCRIPTION("A simple Hello World Module");

与应用程序的区别:

#include <stdio.h>

int main(int argc, char *argv[])//参数也可以是void,如int main(void)
{
    printf("Hello world.\n");
    return 0;
}

1、模块的入口有2个,分别是module_init、module_exit里面对应的加载函数和卸载函数,而应用程序只有1个,main函数。

2、模块打印使用printk,应用程序打印使用printf。

3、模块入口函数的参数是void,应用程序参数可以是void或者2个参数。

编译

2种编译方式

           1、编译进内核

把源码放到内核源码的drivers目录的某个目录下面,比如drivers/char目录下

修改目录下的Makefile,加一行 ​ obj-$(CONFIG_MY_MOD) += mod.o,其中mod.o为mod.c对应的编译对象文件

修改Kconfig config MY_MOD tristate "My Module" help support my module device on develop board

进入顶层目录make menuconfig 选中Y Device Drivers->Character devices->My Module

         make

         这样镜像就包含了模块程序文件的代码

        2、单独编译 *.ko

              1)如果在内核源码目录下,同第一点修改,make menuconfig 选中M ,

                   进入顶层目录

                  make,进行编译内核镜像

                  make modules,进行编译模块文件

                   

2)如果在外层目录,自己写Makefile,然后make

Makefile文件如下

obj-m = mod.o
KERNELDIR = /home/linux-kernel
PWD = $(shell pwd)

modules:
     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
    $(MAKE) clean

其中KERNELDIR是内核源码目录所在的路径

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值