编译linux内核模块时的make -C M= modules的参数说明

这篇具有很好参考价值的文章主要介绍了编译linux内核模块时的make -C M= modules的参数说明。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        在linux下编译可加载内核模块形成.ko文件的makefile中的核心语句是:

$(MAKE) -C $(KERNEL_DIR) M=(PWD) modules

这句是Makefile的规则:这里的

  • $(MAKE)就相当于make;
  • -C 选项的作用是指将当前工作目录转移到你所指定的位置,一般都是内核源代码目录或者内核headers目录,如/usr/include/linux-5.1.1-headers/类似的位置;-C $(KERNEL_DIR) 代表切换工作目录,因为内核源码顶层的Makefile文件定义了伪目标 modules,所以要先将工作目录切换到内核源码顶层 Makefile 所在位置;
  • “M=”选项的作用是,当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules 命令中加入“M=dir”,程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成KO文件。

注释:这个是编译linux核外模块必备的makefile中的核心语句,相当于先跳转到-C 指定的内核目录,然后执行这个目录下的makefile M=XXX modules(这个有点不好理解,一般都是在某个目录下执行makefile就行了,这里是执行makefile M=XXX modules),相当于在当前系统内核根目录下执行make M= XXX modules 进行XXX目录下的模块的编译,编译成xx.ko.这样你的modules就可以在任何其他位置,而不用必须在内核文件下面了。
例如:

obj-m := hello.o
KVERSION:= $(shell uname -r)

all:
	$(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
	$(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) clean

---------------------------------------------------我是分割线------------------------------------------------------------

新的(一般指>2.6.18的内核版本)内核模块编程中的make命令里有个M选项,如下:

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

M=$(PWD) 意思是返回到当前目录继续读入、执行当前的Makefile。
请参考:从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响-CSDN博客

       这个M是kbuild的东西呢,还是make本来自己就有的东西呢?
        按理说,它是make的一个参数,应该是make的东西,但是make的doc里又找不到,如果是kbuild里的东西,它应该怎样来实现呢?经查证这个M是内核根目录下的Makefile中使用的变量。M是makefile脚本中的一个变量(variable):

Use make M=dir to specify directory of external module to build.

Old syntax make … SUBDIRS=$PWD is still supported.

Setting the environment variable KBUILD_EXTMOD take precedence

ifdef SUBDIRS
    KBUILD_EXTMOD ?= $(SUBDIRS)
endif
ifdef M //如果没有定义或赋值M,此处M未定义(undefined)

    ifeq ("$(origin M)", “command line”) //如果定义了,此句用来判断M是否从命令行来
        KBUILD_EXTMOD := $(M)
    endif
endif

以下是来自:从 2.4 到 2.6:Linux 内核可装载模块机制的改变对设备驱动的影响

清单3:2.6 内核模块的Makefile模板

#Makefile 2.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) modules
    clean: rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
endif

        KERNELRELEASE是在内核源码的顶层Makefile中定义的一个变量,在第一次读取执行此Makefile时,KERNELRELEASE没有被定义, 所以make将读取执行else之后的内容。

如果make的目标是clean,直接执行clean操作,然后结束。

当make的目标为all时,-C $(KDIR ) 指明跳转到内核源码目录下读取那里的Makefile (解决M这个变量的定义问题,和KERNELRELEASE变量赋值问题); M=(PWD) 表明然后返回到当前目录继续读入、执行当前的Makefile。当从内核源码目录返回时,KERNELRELEASE已被被定义,kbuild也被启动去解析kbuild语法的语句,make将继续读取else之前的内容。else之前的内容为kbuild语法的语句, 指明模块源码中各文件的依赖关系,以及要生成的目标模块名。mymodule-objs := file1.o file2.o表示mymoudule.o 由file1.o与file2.o 连接生成。obj-m := mymodule.o表示编译连接后将生成mymodule.o模块。

补充一点,"$(MAKE) -C ( KDIR ) M=(PWD)“与”$(MAKE) -C (KDIR ) SUBDIRS=(PWD)"的作用是等效的,后者是较老的使用方法。推荐使用M而不是SUBDIRS,前者更明确。

通过以上比较可以看到,从Makefile编写来看,在2.6内核下,内核模块编译不必定义复杂的CFLAGS,而且模块中各文件依赖关系的表示简洁清晰。

针对要编译的模块的过程,我猜测应该是:(1)读取模块的makefile,因为没有定义KERNELRELEASE变量,所以先走else分支,获得KDIR等信息;(2)然后执行make all,发现需要走make -C $(KDIR) M=$(PWD) modules;(3)跳转到$(KDIR)目录,读取该目录下的makefile,得到KERNELRELEASE变量和M的定义和值,以及其他所需要的内容;(4)跳转到模块代码目录,再读取makefile,发现if已经成立,走if;(5)走make modules编译模块代码生成ko文件。至于为什么这样,参考linux KBuild MakeFile介绍 之二-CSDN博客文章来源地址https://www.toymoban.com/news/detail-757261.html

到了这里,关于编译linux内核模块时的make -C M= modules的参数说明的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • Linux 编译内核模块出现--Unknown symbol mcount

    Linux suse: 在编译SUSE Linux Enterprise Server 12 SP时,使用低版本的docker镜像编译内核模块时,加载内核模块时出现: 加载内核模块时: (1) 指示系统可能受到 Spectre V2 漏洞的影响,并且正在加载的模块没有使用 retpoline 编译器进行编译。 Spectre V2(CVE-2017-5715)是 Spectre 漏洞家族

    2024年02月11日
    浏览(45)
  • 【嵌入式Linux】编译应用和ko内核模块Makefile使用记录

    【嵌入式Linux】编译应用和ko内核模块Makefile使用记录

    在Makefile中,变量的赋值可以使用以下几种方式: = :最基本的赋值符号,表示简单的延迟展开(lazy expansion)方式。变量的值将会在使用变量的时候进行展开。 := :立即展开(immediate expansion)的赋值方式。变量的值在赋值的时候立即展开,并且在后续的使用中不再改变。

    2024年02月08日
    浏览(16)
  • 从module_init看内核模块

    module_init是linux内核提供的一个宏, 可以用来在编写内核模块时注册一个初始化函数, 当模块被加载的时候, 内核负责执行这个初始化函数. 在编写设备驱动程序时, 使用这个宏看起来理所应当, 没什么特别的, 但毕竟我还是一个有点追求的程序员嘛:P, 这篇文章是我学习module_init相

    2024年02月14日
    浏览(7)
  • 内核模块(编译方法)

    内核模块(编译方法)

    目录 一、向内核添加新功能 1.1 静态加载法: 1.2 动态加载法: a、新功能源码与Linux内核源码在同一目录结构下时 b、新功能源码与Linux内核源码不在同一目录结构下时 c、主机ubuntu下使用ko文件 d、开发板Linux下使用ko文件 二、内核模块基础代码解析 Linux内核的插件机制——内

    2024年02月09日
    浏览(7)
  • 软件课设(Ⅲ)——padavan-ng编译以及内核模块修改

    软件课设(Ⅲ)——padavan-ng编译以及内核模块修改

    我记得今年的很多笔试面试都遇到了linux相关的操作,答题状况都挺……昂。算是补课吧,正好大四的毕业实习、软3还有研0的项目都需要linux的环境进行推进,记录一下,聊作纪念。 实验要求 编译系统,下载并提交,验收的时候,我会找MIPS板子,让大家下载验证。 编译一个

    2024年02月02日
    浏览(14)
  • Linux2.6内核配置说明

    maturity level options 代码成熟度选项 Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完成的代码与驱动.除非你是测试人员或者开发者,否则请勿选择 setup 常规设置 Local version - append to kernel release 在内核版本后面加上自定义的版本字符串(小于64字符),可以用\\\"uname

    2024年02月14日
    浏览(36)
  • 【linux内核】Debian内核编译

    【linux内核】Debian内核编译

    列出 Debian 内各种版本的核心软件包 apt安装软件包 编译内核源码 安装内核 更新grub 参考: 8.10. 编译内核 (debian.org) Debian编译内核教程 - 时光旅行的懒猫 - 博客园 (cnblogs.com) 内核编译方法-tony_ayuan-ChinaUnix博客

    2024年02月17日
    浏览(34)
  • Maven自定义脚手架(多module模块)+自定义参数

    Maven自定义脚手架(多module模块)+自定义参数

    视频教程:Maven保姆级教程 Maven入门教程(一):安装Maven环境 Maven入门教程(二):idea/Eclipse使用Maven Maven入门教程(三):Maven语法 Maven入门教程(四):Nexus私服 Maven入门教程(五):自定义脚手架 视频教程: Maven保姆级教程 脚手架是一个项目模板,包含常用的工程结构、代码。 脚手

    2024年02月12日
    浏览(12)
  • 使用cmake编译opencv过程中的可选参数说明

    使用cmake编译opencv过程中的可选参数说明

    opencv版本:4.5.5 通过源码编译opencv时,cmake可以带有很多可选参数,这里对这些可选参数进行说明。 配置选项可以通过几种不同的方式设置: 命令行:cmake-Doption=value… 初始缓存文件:cmake-C my_options.txt… 通过Cmake-GUI进行设定 在本参考中,我们将使用常规命令行。 最常用和有

    2024年02月16日
    浏览(10)
  • Linux内核学习(包含Linux 2.6内核编译安装流程)

    Linux内核学习(包含Linux 2.6内核编译安装流程)

    Linux内核官方网站为:http://www.kernel.org 或者使用git将源码clone下来(我这里使用的版本为2.6): clone下来的源码目录结构如下:  其中比较重要的目录的官方描述如下: 对应的中文描述如下: 由于centos7.6初始gcc版本为4.8.5,而编译内核需要的最低版本为5.1.0,所以需要安装高

    2024年02月07日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包