`
cm14k
  • 浏览: 31416 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

编写第一个内核模块

阅读更多

    内核模块是Linux内核向外部提供的一个接口,其全称是 动态可加载内核模块(Loadabkle Kernel Module,LKM)。 Linux 内核之所以提供模块机制,是因为它本身是一个单内核( monolithic kernel )。单内核的最大优点是效率高,因为所有的内 容都集成在一起,但其缺点是可扩展性和可维护性相对较差,模块机制就是为了弥补这一缺陷。

 

一、什么是模块


模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或内核中其他上层功能。


二、 编写一个简单的模块

模块和内核都在内核空间运行, 模块编程在一定意义上说就是内核编程。因为内核版本的每次变化,其中的某些函数名也会相应地发生变化,因此模块编程与内核版本密切相关。

 

第一个内核模块:

内核版本:2.6.31-4
在RedFlag 6.0测试通过

 

/*
 * hellomod.c
 * 第一个内核模块
 * author:cm
 * date:2010-3-28
 */

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

static int __init lkp_init(void)
{
    printk("<1>Hello,Kernel! from the kernel space...\n");
    return 0;
}

static void __exit lkp_cleanup(void)
{
    printk("<1>Goodbye,Kernel! leaving the space...\n");
}

module_init(lkp_init);
module_exit(lkp_cleanup);
MODULE_LICENSE("GPL");

说明:

8~10行 一些必要的头文件

所有模块都要使用头文件module.h,此文件必须包含进来。
头文件kernel.h包含了常用的内核函数。

头文件init.h包含了宏_init和_exit,它们允许释放内核占用的内存。

 

12~16行

这是模块的初始化函数,它必需包含诸如要编译的代码、初始化数据结构等内容

printk()函数 该函数是由内核定义的,功能与C库中的printf()类似,它把要打印的信息输出到终端或系统日志。字符串中的<1>是输出的级别,表示立即在终端输出。

 

18~21行

这是模块的退出和清理函数。此处可以做所有终止该驱动程序时相关的清理工作。

 

23~24行

函数module_init()和module_exit()是模块编程中最基本也是必须的两个函数。module_init()向内核注册模块所提供的新功能,而module_exit()注销由模块提供的功能。

module_init() 是驱动程序初始化的入口点。对于内置模块,内核在引导时调用该入口点;对于可加载模块则在该模块插入内核时才调用,在卸载模块时调用module_exit()函数。

 

25行

GNU公共许可证 (必须)


编译

 

编译工具:gcc make

Makefile文件:

#Makefile2.6
obj-m += hellomod.o #产生hellomod模块的目标文件
CURRENT_PATH := $(shell pwd) #模块所在的当前路径
LINUX_KERNEL := $(shell uname -r) #内核版本
#内核源码的绝对路径 (RedFlag 6.0)
LINUX_KERNEL_PATH := /usr/src/kernels/2.6.31-4-i686
all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules #编译模块
clean:
	rm -rf *.mod.c *.o *.ko *.markers *.symvers *.order #清理 

执行make命令,会自动生成模块相关文件(如 .o  .ko文件)

 

插入模块到内核

[root@localhost module]# insmod hellomod.ko

 

成功插入后,可以通过dmesg命令查看这个模块所执行的显示内容

[root@localhost module]# dmesg

 

...

Hello,Kernel! from the kernel space...

 

卸载模块

[root@localhost module]# rmmod hellomod

 

再次执行dmesg 显示

Hello,Kernel! from the kernel space...
Goodbye,Kernel! leaving the space...

 

注:查看(dmesg)其实是看日志,只要是看日志的方法应该都是可以的比如:tail /var/log/messages

 

 

 

 

分享到:
评论

相关推荐

    Linux驱动开发之编写第一个内核模块--Hello World源码

    Linux驱动开发之编写第一个内核模块--Hello World源码, 亲测OK,对应文章链接: https://dingdong.blog.csdn.net/article/details/106329048

    linux内核模块.pdf

    最后第4章是驱动设计指导规范, 它是一个提纲性质的, 提醒我们在编写内核模块时的主要注意事项. 我们在做具体项目的时候, 可以查询此章节获得一个快速指引, 如果你对快速指引的细节遗忘了, 则需要重新理解第3章的内容...

    Linux内核模块的编写

    **2.1 HelloWorld(第1部分):创建基本的内核模块** 在这个阶段,我们的目标是创建一个最基本的内核模块,它能够在加载时打印一条消息。我们将使用`printk()`函数来输出这条信息。 ```c #include #include ...

    第12章 内核模块1

    6. **实验实践**:通过编写一个简单的内核模块,如显示进程控制块(PCB)信息,可以加深对内核模块工作原理的理解。这通常涉及使用内核API来访问和处理内核数据结构,例如,使用`current`宏获取当前进程的PCB,然后...

    Ubuntu下内核编程之第一个模块

    ### Ubuntu下内核编程之第一个模块 #### 一、引言 在Linux系统中,内核模块是一种重要的软件组件,它允许用户动态地添加或移除功能而不必重启整个系统。这种灵活性对于系统管理和应用程序开发都非常有用。本文将...

    Linux 2.6内核模块编程范例

    这是每个编程学习者接触的第一个程序,但在内核模块中,它的作用是展示如何与内核交互。Exhello.c中通常会包含以下关键部分: 1. `#include &lt;linux/init.h&gt;` 和 `#include &lt;linux/module.h&gt;`:这两个头文件包含了...

    编写属于你的第一个模块源码

    在这个主题中,我们将深入探讨如何编写属于你的第一个模块,特别是在Linux内核环境中。 首先,我们需要了解模块在Linux内核中的作用。Linux内核模块是一种可加载的代码片段,它们可以在运行时插入到内核中,增加新...

    linux内核驱动模块模板之hello

    这通常是初学者入门内核编程的第一个练习,因为它涉及到基本的模块入口和出口函数。模块入口函数是`init_module()`,它在模块被加载到内核时执行;退出函数是`cleanup_module()`,在模块被卸载时调用。这两个函数是...

    Windows内核模块加载控制系统设计

    这意味着操作系统内核和第三方内核模块都运行在同一特权级下,共享同一个虚拟地址空间。因此,第三方内核模块可以完全访问系统空间内的内存,从而构成极大的安全隐患。 尽管Windows系统提供了一些机制(如驱动签名...

    Linux内核分析与应用课件第1章(二)Linux 内核结构及内核模块.pdf

    Linux内核模块编程入门可以分为几个步骤:首先,需要编写模块的源代码,包括头文件、Makefile文件和模块的实现代码。其次,需要使用gcc编译器和ld链接器编译和链接模块。最后,需要使用insmod命令加载模块到内核中...

    linux内核模块编程(标记版)

    1. **初始化函数**:这是模块加载时调用的第一个函数,通常用于注册设备或执行其他初始化操作。 2. **退出函数**:当模块被卸载时,此函数会被调用,用于清理模块创建的所有资源。 ### 内核模块证书和文档说明 ...

    国嵌全部必修实验手册(第12部分_内核模块参数).pdf

    本实验手册的第12部分主要聚焦于Linux内核模块参数的使用和管理,通过实践操作帮助学生深入理解如何在Linux环境下编写、编译、加载以及调试内核模块,并特别关注了内核模块参数的配置方法。这对于学习Linux内核编程...

    Ubuntu下内核编程之第一个模块helloworld(附源码)

    本篇文章将深入探讨如何在Ubuntu环境下编写你的第一个内核模块——一个简单的“Hello, World!”模块。 首先,我们要了解什么是内核模块。内核模块是可加载到运行中的Linux内核中的代码片段,它们允许我们向内核添加...

    OSlab1 同步互斥和Linux内核模块1

    第二部分:编写一个自己的内核模块 2.1 实验内容与预备知识 内核模块是Linux内核的一部分,可以在需要时动态加载和卸载。预备知识包括Linux内核编程接口,如sysfs、procfs,以及如何使用module_init和module_exit宏...

    内核模块-3160104875-杨樾人21

    描述中提到了实验基于"Operating System Concepts"教材的第四章和第六章,这通常涉及操作系统的基本概念和进程管理,同时参考了"边干边学Linux内核指导2.2",这部分可能涉及了内核模块的编写和Linux内核的输入输出...

    The Linux Kernel Module Programming Guide

    这一节介绍了编写第一个内核模块的基本步骤,包括必要的头文件、函数声明和模块初始化。 #### 2.1.1 介绍printk() `printk()`是内核模块中常用的调试函数,用于向系统日志输出信息。它类似于标准C库中的`printf()`...

    linux内核编程.pdf

    - **背景**: 在学习编程时,“Hello, World”程序通常作为入门的第一个程序。对于Linux内核编程而言,也是如此。 - **基本结构**: 一个典型的内核模块至少包含两个函数: - `init_module()`: 当模块被加载到内核时...

Global site tag (gtag.js) - Google Analytics