编译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 SUBDIRSKBUILD_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.oobj-m := mymodule.o
elsePWD := $(shell pwd)KVER ?= $(shell uname -r) KDIR:=/lib/modules/$(KVER)/buildall: $(MAKE) -C $(KDIR ) M=(PWD) modulesclean: 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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/107290.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue配置全局变量config.js

Vue配置全局变量config.js 若config.js在public目录下 在index.html中引入 这样配置是为了防止路由前缀&#xff0c;如果直接“/config.js”&#xff0c;若路由没有前缀还好&#xff0c;要是有就需要配置为“<% BASE_URL %>config.js”

【01】基础知识:React简介与案例

一、React 简介 React 概述 React 是一个将数据渲染为 HTML 视图 的开源 JavaScript 库 React 由 FaceBook 开发&#xff0c;且开源 为什么要学习 React 1、原生 JavaScript 操作 DOM 繁琐、效率低&#xff08;使用 DOM-API 操作 UI&#xff09; 2、使用 JavaScript 直接…

Xilinx IP 10G Ethernet PCS/PMA IP Core

Vivado 10G Ethernet PCS/PMA介绍 1介绍 完整的10G以太网接口如下图,分为10G PHY和10G MAC两部分。 这篇文章重点讲 10G Ethernet PCS/PMA。 2 IP的基本介绍 10G以太网物理编码子层/物理介质连接(PCS/PMA)核心在Xilinx 10G以太网介质访问控制器(MAC)核心和具有10Gb/s…

Linux网络编程系列之UDP组播

Linux网络编程系列 &#xff08;够吃&#xff0c;管饱&#xff09; 1、Linux网络编程系列之网络编程基础 2、Linux网络编程系列之TCP协议编程 3、Linux网络编程系列之UDP协议编程 4、Linux网络编程系列之UDP广播 5、Linux网络编程系列之UDP组播 6、Linux网络编程系列之服务器编…

尚硅谷Flink(一)

目录 ☄️前置工作 fenfa脚本 &#x1f30b;概述 ☄️Flink是什么 ☄️特点&#xff08;多nb&#xff09; ☄️应用场景&#xff08;不用看&#xff09; ☄️分层API &#x1f30b;配环境 ☄️wordcount ☄️WcDemoUnboundStreaming &#x1f30b;集群部署 ☄️集…

xml的语法

<!-- 1、每一个xml,有且只有一个根标签&#xff0c;所有xml标签必须写在根标签中 2、标签必须要有合闭 3、xml格式是否正确&#xff0c;可以通过浏览器打开xml。来校验xml格式是否正确 4、xml是区别大小写的 5、xml书写标签名时&#xff0c;不要出现空格等特…

微信小程序的框架

目录 一、视图层 1. WXML 数据绑定 列表渲染 条件渲染 模板 2. WXSS 尺寸单位 样式导入 内联样式 选择器 3. WXS事件 二、逻辑层 1. 页面生命周期 2.跳转 1. 一级跳一级 2. 一级跳二级 3. 二级跳二级 4. 二级跳一级 总结 带给我们的收获 一、视图层 1. …

idea 启动项目报错 Command line is too long

1.idea 启动报错 Command line is too long&#xff0c;启动报错信息&#xff1a;Error running ‘Application‘: Command line is too long. 2.如何解决&#xff1f; 1&#xff09;idea打开一个项目。 2.打开项目下的*.idea* 文件夹下的 workspace.xml 文件。 3.在<co…

springboot 导出word模板

一、安装依赖 <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.12.1</version></dependency>二、定义工具类 package com.example.springbootmp.utils;import com.deepoove.poi.XWP…

如何搬运视频赚钱?

可以写一个爬虫&#xff0c;爬取热门视频并下载&#xff0c;然后自动发布到对应网站。 具体实现步骤。 使用的技术栈是Nodejs&#xff0c;安装 Puppeteer npm install puppeteer创建一个 Puppeteer 脚本来访问抖音网站并爬取视频内容。 const puppeteer require(puppeteer…

5.Python-使用XMLHttpRequest对象来发送Ajax请求

题记 使用XMLHttpRequest对象来发送Ajax请求&#xff0c;以下是一个简单的实例和操作过程。 安装flask模块 pip install flask 安装mysql.connector模块 pip install mysql-connector-python 编写app.py文件 app.py文件如下&#xff1a; from flask import Flask, reque…

spring boot 下载resources下的静态文件为流格式

废话不多说&#xff0c;直接上代码 一、下载逻辑 public void downAppApk(HttpServletResponse response){ClassPathResource classPathResource new ClassPathResource("app/xxxxxx.apk");if (!classPathResource.exists()) {throw new BusinessException("安…

好用的跨平台同步笔记工具,手机和电脑可同步的笔记工具

在这个快节奏的工作环境中&#xff0c;每个人都在寻找一种方便又高效的方式来记录工作笔记。记录工作笔记可以帮助大家统计工作进展&#xff0c;了解工作进程&#xff0c;而如果工作中常在一个地方办公&#xff0c;直接选择电脑或者手机中笔记工具来记录即可&#xff0c;但是对…

[部署网站]01安装宝塔面板搭建WordPress

宝塔面板安装WordPress&#xff08;超详细&#xff09;_Wordpress主题网 参考教程 宝塔面板 - 简单好用的Linux/Windows服务器运维管理面板 官网 1.首先你需要一个服务器或者主机 &#xff08;Windows系统或者Linux系统都可以&#xff09; 推荐Linux系统更稳定&#xff0c;…

centos7安装docker-compose

1、下载docker-compose 网盘下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1pltG3aWiN9zMqYt7ZVyLng 提取码&#xff1a;7awd --来自百度网盘超级会员V5的分享2、上传docker-compose文件到/usr/local/bin目录 [root192 bin]# ll 总用量 53892 -rwxrwxrwx 1 …

service worker实现静态资源缓存

service worker如何实现静态资源缓存和强制更新&#xff0c;请看如下示例&#xff1a; 1、注册service worker function serviceWorker() {if (isLocalStorageAvailable() && serviceWorker in navigator) {navigator.serviceWorker.register(/static/almasaeed2010/…

Axure RP医疗在线挂号问诊原型图医院APP原形模板

医疗在线挂号问诊Axure RP原型图医院APP原形模板&#xff0c;是一款原创的医疗类APP&#xff0c;设计尺寸采用iPhone13&#xff08;375*812px&#xff09;&#xff0c;原型图上加入了仿真手机壳&#xff0c;使得预览效果更加逼真。 本套原型图主要功能有医疗常识科普、医院挂号…

海思平台SS528V100编译 linux kernel tun.c eth_get_headlen 编译 出错的问题

osdrv目录下 make kernel 会去opensource目录下解压linux内核压缩包 同时打上很多补丁 如上图 查看Makefile 如下 有打补丁的命令 然后 然后我们的应用程序用到一个特性 需要打开tun/tab这两个属性 打开之后编译内核出错 查到最后发现 没打补丁之前的文件 没问题 …

Qt拖拽文件到窗口、快捷方式打开

大部分客户端都支持拖拽文件的功能&#xff0c;本篇博客介绍Qt如何实现文件拖拽到窗口、快捷方式打开&#xff0c;以我的开源视频播放器项目为例&#xff0c;介绍拖拽视频到播放器窗口打开。   需要注意的是&#xff0c;Qt拖拽文件的功能&#xff0c;不支持以管理员权限启动的…

maven 新建模块 导入后 按Ctrl 点不进新建模块pom定义

新建的ruoyi-common-mybatisplus 模块,导入一直不正常 画出的模块一直导入不进来 这是提示信息 这是正常的提示信息 加上 <version>3.6.3</version> 后,才一切正常