Linux内核可自己增加吗6,linux内核自己添加模块(内核版本:3.0.101)

做内核驱动第一步都是学习如何添加模块,这是基础,有了这个基础,剩下就是写代码了。

由于2.4到2.6内核版本的更新,无论是系统调用还是模块添加机制都有了巨大的变化,本人也因此饱经挫折,最后在3.0.101版本的内核下成功。作为开源运动的支持者,自认为有必要把自己的经历分享出来,以供后来学习者分享与交流。

再次声明,本博客只分享我遇到了的问题,没有交流的不代表不难或者不会遇到问题,只是我没遇到,如果有阅读本博客的朋友遇到了问题,非常欢迎大家一起讨论,技术就是这么成长的!

关于添加模块,步骤上还是那三步。

1.编写模块函数

编写内核模块时必须要有的两个函数 :

1> 加载 函数:

static int func1_init(void)

2> 卸载函数 无返回值

static void func2_exit(void)

这里值得注意的是三点,一是卸载函数必须是void,即无返回型,否则会报错。其二是推荐把加载函数改写成static int __init func1_init(void),卸载函数同理。这里使用__init是利用2.6内核以后的宏机制,具体机制。。。还在学习中。第三点就是人尽皆知的,加载函数的名字必须写成*_init的样子,卸载函数必须是*_exit的样子。

2.其次就是Makefile了。

这方面的文章比较多,网上也讲得非常详细,我就大概讲一下模板和每步的意义。

obj-m := hello.o

kernel_path=/usr/src/linux-headers-$(shell uname -r)

all:

make -C $(kernel_path) M=$(PWD) modules

clean:

make -C $(kernel_path) M=$(PWD) clean

obj -m:= hello.o // 产生 hello 模块的目标

kernel_path // 定义内核源文件目录

all :

make -C $(kernel_path) M=$(PWD) modules

// 生成内核模块参数为内核源代码目录以及模块所在目录

clean:

make -C $(kernel_path) M=$(PWD) clean

// 清除生成的模块文件以及中间文件

这里就要尤为注意了,在2.6版本以后,引入了如下机制。2.6中模块的编译需要配置过的内核源码;编译、连接后生成的内核模块后缀为.ko;编译过程首先会到内核源码目录下,读取顶层的Makefile文件,然后再返回模块源码所在目录。

接下来要讲得就是最折磨人的改变了。

2.4内核下, 执行`cat /proc/ksyms`可看到内核符号在名字后还跟随着一串校验字符串,此校验字符串与内核版本有关。在内核源码头文件linux/modules 目录下存在许多*.ver文件,这些文件起着为内核符号添加校验后缀的作用,如ksyms.ver 文件里有一行 #define printk _set_ver(printk)。linux/modversions.h 文件会包含全部的 ver文件 。所以当模块包含linux/modversions.h文件后,编译时,模块里使用的内核符号实质是带有校验后缀的内核符号。在加载模块时,如果模块中所使用内核符号的校验字符串与当前运行内核所导出的相应的内核符号的校验字符串不一致,即当前内核空间并不存在模块所使用的内核符号,就会出现"Invalid module format "的错误。

为内核符号添加校验字符串来验证模块的版本与内核的版本是否匹配是繁杂和浪费内核空间的;而且随着SMP(对称多处理器)、PREEMPT(可抢占内核)等机制在2.6内核的引入和完善,模块运行时对内核的依赖不仅取决于内核版本,还取决于内核的配置,此时内核符号的校验码是否一致不能成为判断模块可否被加载的充分条件。2.6 内核下,在linux/vermagic.h中定义有VERMAGIC_STRING,VERMAGIC_STRING不仅包含内核版本号,还包含有内核使用的gcc版本,SMP与PREEMPT等配置信息。模块在编译时,我们可以看到屏幕上会显示"MODPOST"。在此阶段, VERMAGIC_STRING会添加到模块的modinfo段。 在内核源码目录下scripts/mod/modpost.c文件中可以看到模块后续处理部分的代码。模块编译生成后,通过`modinfo mymodule.ko`命令可以查看此模块的vermagic等信息。2.6 内核下的模块装载器里保存有内核的版本信息,在装载模块时,装载器会比较所保存的内核vermagic与此模块的modinfo段里保存的vermagic信息是否一致,两者一致时,模块才能被装载。譬如Fedora core 4 与core 2 使用的都是2.6 版本内核, 在Fedore Core 2下去加载Fedora Core4下编译生成的hello.ko,会出现"invalid module format" 错误。

因此,细心的朋友注意到我给出的Makefile模板中编译目标是内核源码树。这里必须是这样,否则会出错。而且必须对应,即,如果你当前内核版本是3.0.101,就必须是以3.0.101的内核源码树为目标进行编译得到*.ko,否则会报错。反之亦然。两者必须一一对应,这一点希望朋友们务必注意,否则会痛不欲生。

以上就是我学习这部分最痛苦最值得分享的部分了,希望可以帮到大家。

由于2.6下各位朋友肯定希望自己的模块能兼容2.4下的模式,所以,我这里再提供一套Makefile,有IBM官方给出,值得学习。

# Makefile2.6

ifneq ($(KERNELRELEASE),)

#kbuild syntax. dependency relationshsip of files and target modules are listed here.

mymodule-objs := file1.o file2.o

obj-m := mymodule.o

else

PWD := $(shell pwd)

KVER ?= $(shell uname -r)

KDIR := /lib/modules/$(KVER)/build

all:

$(MAKE) -C $(KDIR) M=$(PWD)

clean:

rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions

endif

解析 Linux 内核可装载模块的版本检查机制

转自:http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/ 为保持 Linux 内核的稳定与可持续发展,内核在发展过程中引进了可 ...

linux内核添加模块

参考: http://blog.csdn.net/gaoguoxin2/article/details/50220665 动态添加模块不需要编译内核. LINUX的模块主要由6部分组成: 1.模块的加 ...

向linux内核中添加外部中断驱动模块

本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内 ...

linux 实现centos7在线升级最新版本内核

Kernel  (内核)是操作系统的核心,掌握所有硬件设备的控制权,也就是说,你所希望计算机帮你完成的各项工作,都需要通过内核的帮助才能完成,当然,如果我们想完成的某个功能是内核没有的,则内核不会操控 ...

Linux驱动之内核加载模块过程分析

Linux内核支持动态的加载模块运行:比如insmod first_drv.ko,这样就可以将模块加载到内核所在空间供应用程序调用.现在简单描述下insmod first_drv.ko的过程 1.in ...

Linux内核开发之将驱动程序添加到内核

驱动程序添加到内核 一.概述: 在Linux内核中增加程序需要完成以下三项工作: 1.将编写的源代码复制到Linux内核源代码的相应目录 2.在目录的Kconfig文件中增加新源代码对应项目的编译配置 ...

Linux内核的五大模块

Linux内核的五大模块 (转自)https://blog.csdn.net/huangjingbin/article/details/19396235 Linux内核的五大模块 1.进程调度模块 2 ...

在Linux内核中添加系统调用,并编译内核

1 环境准备 运行系统:vmware下安装的ubuntu10.10 32bit桌面版. 编译内核版本: linux-2.6.32.63 内核目录: /home/wanchouchou/linuxKer ...

Linux内核@系统组成与内核配置编译

Linux系统由什么组成? 由用户空间(应用程序+GNU C标准库)和内核空间(系统调用接口+内核+内核架构代码)组成. Linux内核到底是什么?以及组成. ARM的七种操作级别? 内核网络协议栈( ...

随机推荐

后台调取前台js中的函数

Page.ClientScript.RegisterStartupScript(this.GetType(), "setPicType", "setPicType(2); ...

浅谈SEO翻倍提升网站流量

本文是在简单了解并且熟悉SEO技术的基础上加上自己的总结归纳,对于SEO还是一个长期的工程不是一天就能一下优化排名第一.下面就是我对SEO的一些见解: 一.关键字选择 内容相关 搜索次数多,竞争小 主 ...

sql条件中比较性能优化

第一个比第二个性能高. 查询语句意义: 如果codelist中tablecode配置为0时, t.Table_Code = 'SV_RETURN_BILL'不生效. 如果codelist中tablec ...

POJ 2253 Frogger(最小生成树)

青蛙跳跃,题意大概是:青蛙从起点到终点进行一次或多次的跳跃,多次跳跃中肯定有最大的跳跃距离.求在所有的跳跃中,最小的最大跳跃距离SF-_-(不理解?看题目吧). 可以用最小生成树完成.以起点为根,生成 ...

散文说python半篇——景观三元论与盖茨比的对话

今天, 天气晴朗,风和日丽: 我事实上在说谎-- 爱说谎事实上是我的天性 上个礼拜四我就用景观三元论说了非常多谎话.然后一头大象自己上吊了. 了不起的大象啊,盖茨比也要从坟墓里爬出来了吧, 陈年旧事, ...

java 方法学习

手写随机代码 public class suiji{private static final int N = 200;private static final int LEFT = 40;privat ...

Python批量修改文件名与后缀

引言: 有时因为文件版本的更新,后缀名会发生变化,例如Word13的docx到Word16的doc,又例如我们想修改音频文件的后缀.一个一个修改后缀名往往很麻烦,于是我们便可以写一个Python的脚本 ...

Ubuntu安装Java8和Java9

前言 系统:Ubuntu 16.04 软件: Java8, Java9 Tips: Java 9 的代码由于提供了新特性,所以有些代码并不支持向后兼容.也就是说,用 Java 9 写的代码,有可能在 ...

go web framework gin middleware 设计原理

场景:一个middleware可以具体为一个函数,而由前面的gin 路由分析可得,每一个路径都对有一个HandlersChain 与其对应. 那么实际上增加一个middleware的过程,就是将每一个 ...

构建工具 —— Groovy 与 Gradle

1. Gradle Gradle 是一个基于 Groovy 的构建工具,使用 Groovy 来编写构建脚本,类似 maven,支持依赖管理和多项目创建. 相比 maven,更轻量: windows c ...

你可能感兴趣的:(Linux内核可自己增加吗6)