linux设备驱动makefile入门解析

2023-11-18

以下内容仅作参考,能力有限,如有错误还请纠正。
对于一个普通的linux设备驱动模块,以下是一个经典的makefile代码,使用下面这个makefile可以
完成大部分驱动的编译,使用时只需要修改一下要编译生成的驱动名称即可。只需修改obj-m的值。


ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
#generate the path
CURRENT_PATH:=$(shell pwd)
#the absolute path
LINUX_KERNEL_PATH:=/lib/modules/$(shell uname -r)/build
#complie object
default:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
clean:
make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
endif


说明:
当我们在模块的源代码目录下运行make时,make是怎么执行的呢?
假设模块的源代码目录是/home/study/prog/mod/hello/下。
先说明以下makefile中一些变量意义:
(1)KERNELRELEASE在linux内核源代码中的顶层makefile中有定义
(2)shell pwd会取得当前工作路径
(3)shell uname -r会取得当前内核的版本号
(4)LINUX_KERNEL_PATH变量便是当前内核的源代码目录。
关于linux源码的目录有两个,分别为"/lib/modules/$(shell uname -r)/build"和"/usr/src/linux-header-$(shell uname -r)/",
但如果编译过内核就会知道,usr目录下那个源代码一般是我们自己下载后解压的,而lib目录下的则是在编译时自动copy过去的,
两者的文件结构完全一样,因此有时也将内核源码目录设置成/usr/src/linux-header-$(shell uname -r)/。关于内核源码目录
可以根据自己的存放位置进行修改。
(5)make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
这就是编译模块了:首先改变目录到-C选项指定的位置(即内核源代码目录),其中保存有内核的顶层makefile;
M=选项让该makefile在构造modules目标之前返回到模块源代码目录;然后,modueles目标指向obj-m变量中设定的模块;
在上面的例子中,我们将该变量设置成了hello.o。



按照顺序分析以下make的执行步骤:
在模块的源代码目录下执行make,此时,宏“KERNELRELEASE”没有定义,因此进入else。
由于make 后面没有目标,所以make会在Makefile中的第一个不是以.开头的目标作为默认的目标执行。
于是default成为make的目标。
make会执行 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules ,假设当前内核版本是2.6.13-study,
所以$(shell uname -r)的结果是 2.6.13-study ,这里实际运行的是
make -C /lib/modules/2.6.13-study/build M=/home/study/prog/mod/hello/ modules


-C 表示到存放内核的目录执行其makefile,在执行过程中会定义KERNELRELEASE,
然后M=$(CURDIR)表示返回到当前目录,再次执行makefile,modules表示编译成模块的意思。
而此时KERNELRELEASE已定义,则会执行obj-m += hello.o,表示会将hello_world.o目标编译成.ko模块。
若有多个源文件,则采用如下方法:
obj-m := hello.o
hello-objs := file1.o file2.o file3.o
关于make modules的更详细的过程可以在内核源码目录下的scripts/Makefile.modpost文件的注释 中找到。


如果把hello模块移动到内核源代码中。例如放到/usr/src/linux/driver/中, KERNELRELEASE就有定义了。
在/usr/src/linux/Makefile中有KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)。

这时候,hello模块也不再是单独用make编译,而是在内核中用make modules进行编译,此时驱动模块便和内核编译在一起。


关于内核模块编译可以参考另外一篇文章:linux内核模块编译基础知识


http://blog.csdn.net/shanzhizi/article/details/8626474


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux设备驱动makefile入门解析 的相关文章

  • ioctl函数详解

    大部分驱动除了需要具备读写设备的能力之外 还需要具备对硬件控制的能力 一 在用户空间 使用ioctl系统调用来控制设备 原型如下 cpp view plain copy int ioctl int fd unsigned long cmd
  • KVM内核代码结构

    KVM内核代码结构 因为KVM的源代码已经包含在了Linux的内核树中 因此我们只需直接从www kernel org下载代码即可 内核源码包打开较大 解开后目录结构大概是这个样子 涉及KVM的主要有两个目录 virt和arch x86 k
  • linux内核分析:进程通讯方式

    信号 一旦有信号产生 我们就有下面这几种 用户进程对信号的处理方式 1 执行默认操作 Linux 对每种信号都规定了默认操作 例如 上面列表中的 Term 就是终止进程的意思 Core 的意思是 Core Dump 也即终止进程后 通过 C
  • Android:在争议中逃离Linux内核的GPL约束

    原文地址 http tech sina com cn s s 2012 05 28 09447177318 shtml 为这个题材起名 我思考了许久 GPL 是著名的开放源代码许可协议 Linux 内核开源项目正是在 GPL 的庇佑之下 十
  • eMMC简介

    eMMC是embedded MultiMediaCard的简称 MultiMediaCard 即MMC 是一种闪存卡 Flash Memory Card 标准 它定义了MMC的架构以及访问Flash Memory的接口和协议 而eMMC则是
  • 编译Linux内核时出现“ncurses-devel”错误

    通常在安装完Linux系统后 在编译kernel使用make menuconfig时 可能会出现如下错误 Unable to find the ncurses libraries or the required header files m
  • Linux read的核心函数generic_file_buffered_read

    内核 5 9 0 流程图 generic file buffered read一种调用路径 cat某个文件触发 0 ondemand readahead mapping 0xffff888005c61340 ra 0xffff8880059
  • LINUX软中断-ksoftirqd

    前言 在上一篇 LINUX软中断 softirq的描述中 提到过ksoftirqd 这篇文章就介绍ksoftirqd ksoftirqd 是什么 ksoftirqd 是个内核线程 在创建的时候是绑定cpu的 每一个core对应生成一个kso
  • Linux驱动(一)之最简单的驱动程序

    1 前言 为什么要有驱动 为了防止像我等小菜程序员写应用程序的时候权限过高直接去操作底层设备 给设备造成不可挽回的损失 所以要过度一下 让大牛们将底层封装好 应用开发工程师只需要通过特定的接口来完成特定的功能就可以了 2 应用 通常情况下
  • UBOOT命令总结(转)

    UBOOT命令总结 转 很好的UBOOT命令总结 我在起步时就是看的这篇东西 熟悉了以后就用 看自带帮助就行 Printenv 打印环境变量 Uboot gt printenvbaudrate 115200ipaddr 192 168 1
  • Linux设备驱动-procfs

    在Linux中 procfs是进程文件系统 file system 的缩写 包含一个伪文件系统 启动时动态生成的文件系统 可用于内核层和用户层交互信息 这个文件系统通常被挂载到 proc 目录 由于 proc 不是一个真正的文件系统 它也就
  • linux内核的 等待队列 使用方法,wait_queue_head_t,进程休眠

    当你在用户空间需要读写一大片数据的时候 这个就用上了 以下来自 http www yuanma org data 2006 1207 article 1916 htm 假设我们在 kernel 里产生一个 buffer user 可以经由
  • 七种Linux设备驱动模型之——Device

    前言 Linux将所有的设备统一抽象为struct device结构 同时将所有的驱动统一抽象为struct device driver结构 这样设计之后就方便驱动开发工程师编写驱动 只需要将具体的设备包含struct device结构 具
  • MPC8314 (e300核) uboot 调试

    历经2个多月 完成了MPC8314最小系统 uboot 及Linux内核和根文件系统的调试 这是我第一次从头开始做小系统和内核的移植工作 虽然调试的比较辛苦 但是收获还是很多的 下面就介绍一下调试的过程和一些原理性的东西 1 MPC8314
  • 字符设备驱动相关函数

    Linux内核中 a 使用cdev结构体来描述字符设备 b 通过其成员dev t来定义设备号 分为主 次设备号 以确定字符设备的唯一性 c 通过其成员file operations来定义字符设备驱动提供给VFS的接口函数 如常见的open
  • Linux slab 分配器剖析

    http www ibm com developerworks cn linux l linux slab allocator 了解 Linux 内存管理的方式 良好的操作系统性能部分依赖于操作系统有效管理资源的能力 在过去 堆内存管理器是
  • 慢慢欣赏linux pud_offset解析

    typedef struct pudval t pud pud t gt typedef u64 pudval t dir表示L0页表索引的指针 指向PUD页表的基地址 define pud offset dir addr pud t va
  • 最全的交叉编译Makefile讲解

    最近正在搞交叉编译 参考很多博客 学习了一下Makefile的编写 记录一下Makefile内代码是什么意思 代码如下 简单的hello ko的makefile ifneq KERNELRELEASE obj m hello o else
  • Linux内核源码学习(1)

    一 内核简介 1 在安装好的Linux系统中 内核的源代码位于 usr src linux 2的10次方就是1K 1024 16位CPU的地址空间是64K X86结构的80386是32位CPU 段描述结构伪代码 typedef struct
  • linux内核驱动开发笔试题

    linux内核驱动开发笔试题 一 一些常规中举的C考题 第一题 写出下述程序结果 int m 3 1 4 7 2 5 8 3 6 9 int i j k 2 for i 0 i lt 3 i printf d m k i 问题所在 本题考点

随机推荐

  • 服务器虚拟化导出快照,ESXi5 PACS服务器虚拟化系统快照数据恢复

    杭州某国有企业 一台ESXi5 1 虚拟化系统中运行一重要的PACS服务的虚拟机 因为之前做了快照 管理员在误还原快照后 数据回到3个月前 数据很重要 管理员在尝试多种方式后 也无法补救数据 后通过集成商介绍 联系到了北京安数云和科技 北京
  • sklearn K近邻KNeighborsClassifier参数详解

    原文网址 https scikit learn org stable modules generated sklearn neighbors KNeighborsClassifier html class sklearn neighbors
  • 项目中的STL经验

    STL是c 非常重要的一部分 它是很多大神的杰作 高效 稳定 可扩展性好 虽然STL确实存在难以调试 内存碎片的问题 现在机器的内存越来越大 内存碎片的问题基本不太可能成为系统瓶颈 但只要你使用恰当 它能显著提高生产力 并使代码更短 更易维
  • 五大常用经典算法

    五大常用算法之一 分治算法 一 基本概念 在计算机科学中 分治法是一种很重要的算法 字面上的解释是 分而治之 就是把一个复杂的问题分成两个或更多的相同或相似的子问题 再把子问题分成更小的子问题 直到最后子问题可以简单的直接求解 原问题的解即
  • 【UE4】搭建局域网内VR直播 UE4.27

    前言 英伟达显卡 UE4 27的内网搭建360 相机直播 并在内网任意设备使用VR观看 理论上性能足够效果越好 此处使用的VR设备为Vive 梳理了整体构建流程 希望能帮到你 多图警告 图片教程比较直观 1 准备工作 下载UE和OBS所需安
  • 代码走查和代码审查_代码审查随时间而变化

    代码走查和代码审查 我们已经进行了大约4年的代码审查 代码审查入门 从一开始 开发人员就会互相帮助 在有人询问时查看代码 或者有时主管或高级开发人员会介入并检查代码 如果我们发现测试存在问题 或者是否有人刚刚加入团队并且我们期望他们需要一些
  • android 透明状态栏方法及其适配键盘上推(二)

    在上一篇文章中介绍了一种设置透明状态栏及其适配键盘上推得方法 但是上一篇介绍的方法中有个缺点 就是不能消除掉statusbar的阴影 很多手机如 三星 Nexus都带有阴影 即使我用了
  • GD32F303调试小记(五)之ADC+DMA+硬件过采样

    前言 单片机的大多数的功能都是基于数字信号去控制的 然而许多的场合下 我们也需要有模拟信号的参与 因为许多变量的控制是需要连续的而非阶跃式的 常见的若想得到电压值 温度值 电流值等等都需要用到A D转换 如果外围器件不是特定IC而是自己搭的
  • Mask R-CNN详解

    一 Mask R CNN网络介绍 Mask R CNN是何凯明2017年提出的一个实例分割 Instance segmentation 算法 可以用来做 目标检测 目标实例分割 目标关键点检测 是ICCV2017的best paper Ma
  • 小科普

    买固态硬盘 我们会比较关注颗粒寿命 机械硬盘虽然几乎不用考虑长寿与否 除了考虑SMR PMR记录方式外 最怕的其实就是坏 盘一挂数据未必能找回来 所以其故障率指标就显得尤为重要 各种寿命指标 那这个指标一般就是MTBF了 全称平均无故障间隔
  • 文件传输协议FTP与TCP/IP协议之间有什么关系

    TCP IP协议是目前网络所采用的一种框架协议 包括五层 应用层 传输层 网络层 链路层 物理层 FTP协议是TCP IP协议的一部分 严格意义上来说是应用层协议 FTP是一种应用程序 基于TCP IP协议 它定义了本地登录户机与远程服务器
  • Verilog HDL运算符

    一 逻辑运算符 逻辑与 逻辑或 逻辑非 二 关系运算符 逻辑相等 逻辑不等 全等 不全等 和 可以比较含有x和z的操作数 在模块的功能仿真中有着广泛的应用 三 位运算符 非 与 或 异或 同或 四 拼接运算符 s1 s2 sn 五 一元约简
  • Python数据可视化:豆瓣电影TOP250

    欢迎关注天善智能 我们是专注于商业智能BI 人工智能AI 大数据分析与挖掘领域的垂直社区 学习 问答 求职一站式搞定 对商业智能BI 大数据分析挖掘 机器学习 python R等数据领域感兴趣的同学加微信 tstoutiao 邀请你进入数据
  • eclipse 使用maven构建 springboot +swagger

    swagger用于定义API文档 好处 1 前后端分离开发 2 API文档非常明确 3 测试的时候不需要再使用URL输入浏览器的方式来访问Controller 4 传统的输入URL的测试方式对于post请求的传参比较麻烦 当然 可以使用po
  • vue 记住密码下次自动登录

    div div
  • <HarmonyOS第一课>运行Hello World课后作业

    前言 HarmonyOS应用开发者基础认证课程课后习题 仅供参考 也欢迎各位小伙伴讨论指正 习题 判断题 1 DevEco Studio是开发HarmonyOS应用的一站式集成开发环境 正确 True 2 main pages json存放
  • [Qt]基础数据类型和信号槽

    文章目录 1 Qt基本结构 1 1 Qt本有项目 1 1 1 项目文件 pro 1 1 2 main cpp 1 1 3 mainwindow ui 1 1 4 mainwindow h 1 1 5 mainwindow cpp 1 2 Q
  • 使用libvirt管理KVM虚拟机

    使用libvirt管理KVM虚拟机 一 安装虚拟化管理工具 1 yum install virt manager libvirt libvirt python python virtinst 1 kmod kvm kvm kernel mo
  • 微信小程序wx.canvasToTempFilePath压缩上传图片,ios压缩成功但是数据sm2加密后无法发起请求,安卓一切正常

    问题以及解决 吐槽遇到的问题 在写微信小程序的时候 采用wx canvasToTempFilePath压缩图片且上传的时候 安卓一切正常 我在开发工具上也一切正常 偏偏ios上就不正常 不正常不是指压缩失败 而是明明也压缩成功了 竟然发不起
  • linux设备驱动makefile入门解析

    以下内容仅作参考 能力有限 如有错误还请纠正 对于一个普通的linux设备驱动模块 以下是一个经典的makefile代码 使用下面这个makefile可以 完成大部分驱动的编译 使用时只需要修改一下要编译生成的驱动名称即可 只需修改obj