linux内核模块编写,从零开始linux内核模块开发

d2cf5d7b6e7aae8aaf4763d184eb90c0.png

嗨,大家好!

在这篇文章中,我将向您介绍Linux内核模块开发领域。我本人是该领域的新手,但是随着我逐步学习它们,我决定在此博客中记录所有内容。

要启动,您需要某种虚拟机。当然,您可以在自己的系统上测试内核模块,但是这样做非常危险,您无法真正有效地调试它们,必须使用printk和调试消息来发现代码中的问题。

第一种选择是使用VirtualBox并在其中安装一个Linux发行版。这样,您的系统就不会崩溃,而且对于任何数据丢失,您都将是安全的。但是调试仍然不是很简单。

第二种选择是使用QEMU和buildroot,您可以轻松地对Linux内核代码或您自己的代码进行调试。这是推荐的方法。

我在这里找到了一个非常不错的linux + buildroot设置。顾名思义,再加上linux内核编程中的一些非常好的技巧。here

使用C++irosantilli buildroot

只需按照Github上的指南进行操作即可。这只是我在设置buildroot时遇到的一些故障。

克隆整个存储库。这样您会更好。

git clone --recurse-submodules -j16 "https://github.com/cirosantilli/linux-kernel-module-cheat"

注意依赖关系。奇怪的是configure脚本没有检查所有的脚本。如果遇到任何错误消息,请注意错误消息,并找到适合您发行版安装的软件包。 (很可能您也需要该软件包的开发版本)

如果您使用的是提及的buildroot,则无需执行此步骤。这是使您开始内核模块开发的最小设置。

安装用于编译内核模块的依赖项(如果在Ubuntu上,请运行以下命令):

APT-get install build-essential linux-headers-$(uname -r)

您的第一个模块

创建目录并将这段代码放入文件中(例如ko_example.c):

ude

include

include

MODULE_LICENSE("GPL");

MODULE_AUTHOR("Shahriar EV");

MODULE_DESCRIPTION("sample linux kernel module.");

MODULE_VERSION("1.00");

static int __init mylkm_init(void) {

printk(KERN_INFO "HI!n");

return 0;

}

static void __exit mylkm_exit(void) {

printk(KERN_INFO "BYE!n");

}

module_init(mylkm_init);

module_exit(mylkm_exit);

顶部的包含物非常明显。它们是linux内核编程所必需的,并为我们提供了此处使用的所有功能。

下一块是模块规格。自我解释...

mylkm_init是加载模块时调用的函数.

mylkm_exit是在模块卸载时调用的函数.

printk用于从内核中打印内容,然后可以通过dmesg读取。

KERN_INFO 是之后的日志消息的严重性级别

到目前为止,这已经足够了代码,但是我们需要一个Makefile来编译内核模块。

将此文件保存在与源代码相同的目录中的文件名Makefile中:

obj-m += lkm_example.o

all:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

72 / 5000

翻译结果

现在运行make,它将成功构建。 要加载它(以root身份)运行:

insmod ko_example.ko

如果一切正常,您可以在dmesg缓冲区中看到“ Hello World”:

dmesg

The module should now be visible on lsmod output.

在卸载内核模块时,再次调用printk:

rmmod ko_example.ko

知道L'M开发与用户态应用程序不同是非常重要的。 我喜欢直接从derekmolloy.ie引用:

内核模块不是应用程序!

不按顺序执行— 内核模块使用其初始化函数进行注册,以处理请求,该初始化函数先运行然后终止。 它可以处理的请求类型在模块代码中定义。 这与图形用户界面(GUI)应用程序中常用的事件驱动编程模型非常相似。

没有自动清理 — 卸载模块时,必须手动释放分配给模块的所有资源,否则在系统重新引导之前,这些资源可能不可用。

没有printf()函数 — 内核代码无法访问为Linux用户空间编写的代码库。内核模块在内核空间中运行并运行,内核空间具有自己的内存地址空间。内核空间和用户空间之间的接口已明确定义和控制。但是我们确实有一个printk()函数可以输出信息,可以从用户空间中查看信息。

可以打断 — 内核模块在概念上的一个困难方面是它们可以同时被多个不同的程序/进程使用。我们必须仔细构造我们的模块,以使它们在被中断时具有一致且有效的行为。我们必须考虑多个进程同时访问模块的影响。

具有更高级别的执行特权 — 通常,分配给内核模块的CPU周期要多于分配给用户空间程序的CPU周期。这听起来像是一个优势,但是,您必须非常小心,以免模块对系统的整体性能产生不利影响。

没有浮点支持 — 内核代码使用陷阱为用户空间应用程序从整数模式转换为浮点模式。但是,在内核空间中执行这些陷阱非常困难。另一种方法是手动保存和恢复浮点运算-最好避免执行此任务,并将其留给用户空间代码。

我认为第一次尝试就足够了! 进一步的话题可能实际上是在为内核模块做一些实际的任务。 例如向用户区显示一些数据或提供一些设备供其他程序使用。

参考文献

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值