Linux编程——内核模块

在FiRa的Android底层实现中,其IEEE 802.15.4协议相关实现均作为内核模块实现,因此,本文简要介绍内核模块的相关定义,并节选相关FiRa实现内核模块的使用。

1. Linux内核模块

内核模块是Linux操作系统中比较独特的机制。模块本身不被编译进内核镜像,这就有效控制了内核的大小;模块一旦被加载,就和内核中的其他部分完全一样。

Linux启动中在完成BIOS加载、读取MBR、BootLoader启动之后,会根据内核映像所在路径,解压缩操作,开始启动内核,调用start_kernel函数来启动一系列的初始化函数并初始化各种设备。

内核启动之后,会运行相关初始化工作,启动相关启动项。

然后根据/etc/modules.conf文件或/etc/modules.d目录下的文件来加载内核模块。

常见的内核模块包括驱动程序、文件系统、网络协议栈、安全模块和系统调用等。

1.1 内核的加载和卸载

内核模块通过insmodmodprobe命令加载内核模块,相应的加载函数就会被内核执行,完成本模块的相关初始化工作。

当通过rmmod命令卸载某模块时,模块的卸载函数会被自动执行,完成与模块加载函数相反的功能(如释放内存等)。
module_init,在内核模块被内核加载时,会调用module_init中的函数,即内核模块的加载函数。
module_exit,在内核模块被卸载时的卸载函数,卸载内核模块时调用。

在内核代码中,模块相关函数示例如下:

c 复制代码
static int __init function_init(void)
{}

static void __exit function_cleanup(void)
{

}
module_init(function_init);
module_exit(function_cleanup);

另外,对于内核模块而言,授权MODULE_LICENSE是必须的,用于指定内核模块的许可证,其他模块参数相对可选。常见的许可证包括:GPL、LGPL、BSD、MIT等。常见的内核模块参数还有:

  • MODULE_AUTHOR,指定内核模块的作者
  • MODULE_DESCRIPTION,内核模块的描述信息
  • MODULE_VERSION,内核模块的版本信息
  • MODULE_SUPPORTED_DEVICE,指定内核模块支持的设备。
  • MODULE_DEVICE_TABLE
  • MODULE_ALIAS

对于USB、PCI等设备驱动程序,通常会创建一个MODULE_DEVICE_TABLE,表明该驱动模块支持的设备。

符号导出EXPORT_SYMBOL

  • EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。
  • 在调用该函数的另外一个模块中使用extern对之声明。
  • 注意:先加载定义该函数的模块,然后再加载调用该函数的模块,请注意这个先后顺序,顺序不能错。

示例------FiRa IEEE 802.15.4相关内核模块

mcps_main

c 复制代码
int __init mcps802154_init(void)
{
	int r;

	r = mcps802154_nl_init();
	if (r)
		return r;
	r = mcps802154_default_region_init();
	WARN_RETURN(r);
	r = simple_ranging_region_init();
	WARN_ON(r);
	r = mcps802154_endless_scheduler_init();
	WARN_ON(r);
#ifdef CONFIG_MCPS802154_TESTMODE
	r = ping_pong_region_init();
	WARN_ON(r);
#endif
	return r;
}

void __exit mcps802154_exit(void)
{
#ifdef CONFIG_MCPS802154_TESTMODE
	ping_pong_region_exit();
#endif
	mcps802154_endless_scheduler_exit();
	simple_ranging_region_exit();
	mcps802154_default_region_exit();
	mcps802154_nl_exit();
}

module_init(mcps802154_init);
module_exit(mcps802154_exit);

FiRa域

c 复制代码
module_init(fira_region_init);
module_exit(fira_region_exit);

MODULE_DESCRIPTION("FiRa Region for IEEE 802.15.4 MCPS");
MODULE_AUTHOR("Nicolas Schodet <nicolas.schodet@qorvo.com>");
MODULE_VERSION("1.0");
MODULE_LICENSE("GPL v2");

FiRa调度器符号导出

c 复制代码
//MCPS, 调度器管理,实现调度器的注册与注销
EXPORT_SYMBOL(mcps802154_scheduler_register);
EXPORT_SYMBOL(mcps802154_scheduler_unregister);
相关推荐
没文化的阿浩9 分钟前
【Linux系统】进程状态详解
android·linux·c++·c
是店小二呀20 分钟前
AdGuard Home 部署实战:Linux/Windows 安装、DNS 配置与固定公网管理
linux·运维·windows
做萤石二次开发的哈哈20 分钟前
海康移动交通四款设备技能接入实战:布控球+取证终端+测速仪+出入口终端,Web/App/小程序移动交通应用快速生成
前端·物联网·萤石开放平台·蓝海aiot一站式工作台·aiot开发·移动交通
草莓熊Lotso22 分钟前
【Redis 初阶】C++ 客户端实战:从 RESP 协议到 redis-plus-plus 工程化用法
linux·开发语言·网络·数据库·c++·redis·缓存
yulingfeng5925 分钟前
虚拟机开机时自动挂载目录
linux·运维·服务器
张宇Joaquin32 分钟前
S920X00机器CentOS 7.6下大批量容器执行docker exec卡顿
linux·docker·centos
小此方41 分钟前
Linux网络(九):从 URL 到 HTTP 报文:彻底搞懂 HTTP 请求与响应,并手写一个简单的 HTTP 服务器
linux·服务器·网络
前端世界1 小时前
Linux服务器实战:日志越来越大怎么办?用Logrotate+DNS解决日志管理与内网访问问题
linux·服务器·chrome
小此方1 小时前
Linux网络(十):HTTP请求是如何被服务器解析的?从请求报文、路径处理到响应状态码与异常处理
linux·服务器·网络
少司府1 小时前
Linux系统篇(一)指令篇·一:初识Linux及其基本指令
linux·运维·服务器·网络·阿里云·linux系统