需要了解的Linux模块编程框架

作者: 公司产品  发布:2020-02-04

  是单内核系统,可通用计算平台的外围设备是频繁变化的,不可能将所有的(包括将来即将出现的)设备的驱动程序都一次性编译进内核,为了解决这个问题,Linux提出了可加载内核模块(Loadable Kernel Module,LKM)的概念,允许一个设备驱动通过模块加载的方式,在内核运行起来之后融入内核,加载进内核的模块和本身就编译进内核的模块一模一样。

  一个程序在编译的地址的相对关系就已经确定了,运行的时候只是进行简单的偏移,为了使模块加载进内核后能够被放置在正确的地址,并正确的调用系统的运行的导出符号表,编译模块的时候必须要使用系统的编译地址,并调用系统编译出得静态的导出符号表。即模块必须使用系统的配置环境fig,一旦这两个文件任意一个发生了变化,都很可能导致模块的编译地址与系统的编译地址不匹配,造成运行时的错误甚至宕机。

  从提供系统运行效率的角度,一个模块不是也不应该是完全独立的,即一个模块往往会调用其他模块提供的功能来实现自己的功能,这样做能更好实现系统的分工并提高效率。Linux为了实现模块间的相互调用,设计了导出符号表,每个模块都可以将自己的一个私有的标号导出到系统层级,以使该标号对其他模块可见,系统在编译一个模块的时候会自动导出这个模块的导出符号表到modules.syms文件(如果没有导出任何符号,可以为空),mac地址模块并在加载一个模块的时候会自动将该模块的导出符号表与系统自身的导出符号表合并。一个系统的源码的导出符号表一般在源码顶层目录的modules.syms文件中,查看正在运行的系统导出符号表使用cat /proc/kallsyms。注意,正如前面解释的,我们的模块之所以能够正常运行,一个重要原因就是编译我们模块使用的符号地址就是编译内核时使用的符号地址,所以运行起来虽然地址会有偏移,但是模块中相关的符号的地址也会和内核地址一起偏移,也就还能找得到。基于这种思想,我们也可以直接查看系统当前运行的地址,将地址赋值给一个函数指针并使用,也是没有问题的,当然,这只是阐述原理,并不建议这么写模块。

  导出符号表可以大大的提高系统的运行效率,这也是只有开源系统才能提供的一个强大的功能,但是,导出符号表的引入会导致一个小小的麻烦--模块的依赖,当我们使用lsmod的时候,就可以查看系统当前的模块,其最后两列分别是该模块被引用的次数以及引用该模块的内核模块,当一个模块被其他模块引用时,我们是不能进行卸载的,同样,如果模块A依赖于模块B,那么如果模块B不加载的时候模块A也加载不了。在编写多模块的时候尤其要注意这个问题,可以写一个脚本管理多个依赖模块。Linux内核使用两个宏来导出一个模块的符号

  借助内核的Makefile,编译出的XXX.ko(Kernel Object)就是可加载到该内核的外部模块,为了利用内核的Makefile,我们可以将编译外部模块的Makefile写成如下的格式:

  这个简单的Makfile是利用ubuntu主机的源码Makefile来编译模块,学习模块编程的开始阶段在主机进行编译调试更方便一点,下面我解释一下这个Makefile,首先,我们的思路还是通过内核的Makefile来准备我们的模块,而内核的Makefile一旦执行,就会给KERNELRELEASE这个变量赋值,所以第一次进入我们这个Makfile的时候,这个变量还是空,所以执行else的部分——给相关的变量赋值,make默认编译第一个目标all,make -C $(KERNELRELEASE)就是进入到KERNELRELEASE指定的目录并执行里面的Makefile,显然,这就是我们内核源码的顶层Makefile,接下来的选项M=$(PWD) modules都是传入这个顶层Makefile的参数,表示我要编译一个模块,这个模块位于M指定的目录,所以内核会进行相关的配置并最终进入到这个模块所在的目录,此时,我们的这个Makefile会再被进入一次,这一次是从内核Makefile中跳入这里的,,KERNELRELEASE已经被定义过,内核Makefile想要的就是obj-m后面指定的要编译的目标文件,所以内核Makfile就会找到我们写的模块源文件进行编译。如此我们就得到了能在ubuntu下执行的xxx.ko文件,如果需要在开发板上运行,只需要将内核路径改成开发板运行系统的源码路径即可,同时记得要导出相关的环境变量( ARCH, CROSS_COMPILE )

  Linux为每个模块都预留了相应的地址,注册模块即让该模块对内核可见,这也是模块工作的先决条件。注册之后,我们就可以通过查看内核输出信息dmesg命令来查看模块的运行情况。经常使用内核函数printk()来输出系统信息进行打印调试。使用insmod XXX.ko加载一个模块,使用rmmod XXX.ko卸载一个模块,使用lsmod查看当前系统中的模块及其引用情况

  注意这里的授权是必须的,如果一个模块没有授权,那么很多需要该授权的函数甚至都不能使用,同理,不合适的授权也会导致模块运行或加载的错误,所以初学者一定不要忽视这个授权,相关授权的选项在linux/module.h中,这里我把相关的说明贴出来供大家参考

  另一个细节是Linux内核源码的默认头文件路径是顶层目录的include目录,所以包含头文件的时候include可以省略,

  课程从0开始,讲到云计算结束,按阶段授课,从入门到跑路,适合初学者,也适合定制,需要哪个模块学哪个模块2,包含初级运维工

  IEC 1131-3的编程语言是IEC工作组对世界规模的PLC厂家的编程语言合理地吸收、学习的基础上...

  Rocke是专门从事门罗币(Monero)挖掘业务的顶级黑客组织。去年年底,自新黑客组织Pacha崛...

  随着电子产品的飞速发展,MCU的集成度越来越高,体积越来越少,封装形式越来越多。编程是产品上市前至关...

  3月5日,高盛集团向全体3.6万名员工发布内部信,表示放宽员工着装要求。从此,这一老牌华尔街公司员工...

  张钹院士指出,清华大学建立人工智能研究院的重要目标就是在人工智能的基础理论和基本方法上进行源头性和颠...

  继电器梯形图(LD-Ladder Diagram)语言是PLC首要选用的编程语言,也是PLC最普遍选...

  本文主要测试MySQL执行update语句时,针对与原数据(即未修改)相同的update语句会在My...

  我们可以把“进化计算”看做是一类人工智能和机器学习的分支。最早提出于20世纪50年代,进化计算旨在让...

  根据分析指令时产生的“操作命令”形成相应的操作控制信号序列,通过运算器,存储器及输入/输出设备的执行...

  最近,网上流传一组《人工智能实验教材》的图片,照片火起来的原因是教材是为幼儿园的小朋友们设计的!

  Vundle在github上面有上将近20K的star,已经作为最流行的Vim插件管理器,强烈推荐所...

  目前国内流行用昆仑通泰或者威纶通触摸屏做项目,一方面价格便宜,另一方面编程简单。mac地址模块但西门子屏也经常会被...

  其实在Linux操作系统中,磁盘管理机制和windows上的差不多,绝大多数都是使用MBR(Mast...

  嵌入式linux中文站给大家介绍三种Linux中的常用多线程同步方式:互斥量,条件变量,信号量。

  为了协助外科手术或在人体内运送药物,未来的机器人将需要放弃有毒性的钕,转而使用铁等危险性较低的金属。...

  初代kirigani的实验也证明了不同的鳞片形状会对机器人的爬行效率产生影响。研究人员对圆形、三角形...

  一个服务器是以虚拟机的形式提供的,通过df -h看服务器磁盘空间只有30多个G,但通过fdisk -...

  PLC(可编程控制器)是软硬结合的一门技术,因为我们编写的程序需要外部接线才能实现,而只有接线没有程...

  World Zones的作用是在机器人位于用户专门定义的区域内时,停止该机器人或设置一个输出信号。

  天雷滚滚。天雷滚滚。天雷滚滚。作为一个Linux程序员,你能碰到的最伤心的事情,莫过于:编译了一整天...

  docker是linux容器的一种封装,提供简单易用的容器使用接口。它是最流行的Linux容器解决方...

  今天Reddit机器学习板块最火的话题,莫过于一个“亡于AI”的帖子,作者分享了发生在自己公司的一个...

  有时候在你安装后摇升级 RAM 的时候需要增加一点交换分区的空间,比如你要将你的系统的 RAM 从 ...

  目前,Linux作为嵌入式系统的主力军,广泛应用于消费类电子、工业控制、军工电子、电信/网络/通讯、...

  该团队首先制作了一个由16个镍钛诺电极组成的电极束,每个电极的直径只有23微米。(最小的人类神经元的...

  如果你想要进入运维管理领域这一行,首先你应该了解linux运维工程师是干什么的。他主要是对Linux...

  预测源代码,听着就是一件非常炫酷的事情。最近,谷歌大脑的研究人员就对此高难度任务发起了挑战,mac地址模块在构建源...

  玩儿电脑最怕的就是卡慢,那么电脑卡慢应该怎么解决呢?对于windows系统来说,你可能有各种免费的杀...

  当转为使用 Linux 时,你可能会注意到你所使用的版本会带有一个默认的备份工具。然而,可能该工具并...

  在这个路径运动过程中,工具的方向会从起始点到结束点连续变化,这种方式通过腕部轴的变化把执行运动拆分成...

  也许没有那么多铁杆的游戏玩家使用 Linux,但肯定有很多 Linux 用户喜欢玩游戏。如果你是其中...

  正如我之前说过,安全好比是在公路上开车――比你开得慢的人都是白痴,比你开得快的人都是疯子。本文介绍的...

  当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机...

  上古卷轴 5 已经不是款新游戏了,但它的 mod 社区依旧活跃。如果你的 Linux 系统有足够资源...

  众所周知,如果没有 cd 命令,我们无法 Linux 中切换目录。这个没错,但我们有一个名为 sho...

  作为中央核心处理单元的CPU,除了生产工艺的不断革新进步外,在处理数据和响应速度方面也需要有权衡。稍...

  IO响应过程中最主要问题是中断的balance,由于默认linux中并没有对NVMe的中断进行有效的...

  这是一个美妙而且疯狂的时代,瞬息万变,一切皆有可能。 曾经一度,微软把Linux看作危险的异类

  Linux系统让我们懂得了共享、开放、自由可以让人类生活的更加美好,开源精神是一种让每个从事Linu...

  OpenCV是一个跨平台的计算机视觉库,可以运行在Windows、Linux、MacOS等操作系统上...

  本月C语言和C++都强势增长,C语言大有超越Java的趋势,C++则回到第三位置。

  如果说如何快速学习、了解 Linux 的话,我的答案是学命令、背命令!为何呢?对于一名新手来说,去学...

  自从多线程编程的概念出现在 Linux 中以来,Linux 多线应用的发展总是与两个问题脱不开干系:...

  最近,据报道,日本文部科学省3月26日公布了全国小学从2020年度起使用的教科书的审定结果,共164...

  Windows 7将要到达其生命线的终点,市场数据表明,Win7操作系统(OS)的用户数量开始减少。...

  由于 Linux 所具备的开源、稳定、高效、易裁剪、硬件支持广泛等优点,使得它在嵌入式系统领域最近十...

  按 照电气工程师协会的一个定义:嵌入式系统是用来控制或监视机器、装置或工厂等的大规模系统的设备。具体...

  基于 TensorMask 表示的模型,有一个采用滑窗的掩码预测分支和一个类似于检测框回归的分类分支...

  树莓派运行的是Linux系统,因此需要对Linux的命令和操作进行熟悉,我个人的体会Linux的命令...

  处理机(CPU)是整个计算机系统的核心资源,在多进程的操作系统中,进程数往往多于处理机数,这将导致各...

  众所周知,现在的分时操作系统能够在一个CPU上运行多个程序,让这些程序表面上看起来是在同时运行的。l...

  TI AM437x高性能处理器基于ARM Cortex-A9内核。 这些处理器通过3D图形加速得到增强,可实现丰富的图形用户界面,还配备了协处理器,用于进行确定性实时处理(包括EtherCAT,PROFIBUS,EnDat等工业通信协议)。该器件支持高级操作系统(HLOS)。基于Linux的® 可从TI免费获取。其它HLOS可从TI的设计网络和生态系统合作伙伴处获取。 这些器件支持对采用较低性能ARM内核的系统升级,并提供更新外设,包括QSPI-NOR和LPDDR2等存储器选项。 这些处理器包含功能方框图中显示的子系统,并且后跟相应的“说明”中添加了更多信息说明。 处理器子系统基于ARM Cortex-A9内核,PowerVR SGX图形加速器子系统提供3D图形加速功能以支持显示和高级用户界面。 可编程实时单元子系统和工业通信子系统(PRU-ICSS与ARM内核分离,允许单独操作和计时,以实现更高的效率和灵活性.PRU-ICSS支持更多外设接口和EtherCAT,PROFINET,EtherNet /IP,PROFIBUS,以太网Powerlink,Sercos,EnDat等...

本文由佛山市光源模块有限公司发布于公司产品,转载请注明出处:需要了解的Linux模块编程框架

关键词: mac地址模块