![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
内核模块
文章平均质量分 84
苦梨甜
嵌入式全栈ing
展开
-
模块的加载过程四
sys_init_module第二部分由load_module返回的do_init_module实现。原创 2022-12-20 16:10:46 · 850 阅读 · 0 评论 -
模块的加载过程三
这种情况下simplify_symbols函数会调用resolve_symbol函数来处理该未定义符号,后者会调用find_symbol函数去查找该符号(详细的查找过程见本章前面的"find_symbol函数”部分),如果找到了,就把它在内存中的实际地址赋值给st_valueo如此,经过simplify_symbols函数的调用之后,内核模块符号表中的所有符号就都有了正确的st_value值,也即都有了正确的内存地址。这是个很严重的问题。如此,内核模块导出符号的地址在系统执行完重定位之后被更新为正确的值。原创 2022-12-19 21:33:52 · 896 阅读 · 0 评论 -
模块的加载过程二
总体上,each_symbol_section函数可以分成两个部分:第一部分是在内核导出的符号表中查找对应的符号,如果找到,就通过返回该符号的信息,否则,再进行第二部分的查找:第2部分是在系统中己加载的模块(系统中所有己成功加载的模块都以链表的形式保存在一个全局变量modules中)的导出符号表中查找对应的符号,如果找到就通过返回该符号的信息,否则函数返回false。函数在全局链表modules中遍历所有己加载的内核模块,对其中的每一模块都构造一个新的arr数组,然后在其中查找特定的符号。原创 2022-12-18 15:59:56 · 543 阅读 · 0 评论 -
模块的加载过程一
ps:kernel symbol内核符号表,就是在内核的内部函数或变量中,可供外部引用的函数和变量的符号表。. 其实说白了就是一个索引文件,它存在的目的就是让外部软件可以知道kernel文件内部实际分配的位置。先来个图:在用户空间,用insmod这样的命令来向内核空间安装一个内核模块,本节将详细讨论模块加载时的内核行为。原创 2022-12-17 21:27:17 · 1382 阅读 · 0 评论 -
内核模块的文件格式与EXPORT_SYMBOL的实现
图中忽略了驱动程序模块ELF文件中不会用到的Program header table从图中可以看到,静态的ELF文件视图3总体上可分为三大部分:头部的ELF header,中间的section和尾部的Section header table。以内核模块形式存在的驱动程序,比如demodev.ko,其在文件的数据组织形式上是ELF(Executable and Linkable Format)格式,更具体地,内核模块是一种普通的可重定位目标文件。ELF文件的主体,位于文件视图中间部分的一个连续区域中。原创 2022-12-17 15:50:17 · 614 阅读 · 0 评论 -
将模块编译入内核
按下空格键设置为*,也就是让对应模块编译到内核中,然后保存退出。输入 / 可以根据关键字查找模块所在位置。这是一个简单的模块hello.c。2. 修改Makefile。3. 修改Kconfig。6. 重新配置 执行。原创 2022-12-04 16:14:21 · 641 阅读 · 0 评论 -
resource 资源分配
先掌握用于管理资源的数据结构和函数:Linux提供通用的构架,用于在内存中构建数据结构。这些结构描述了系统中可用的资源,使得内核代码能够管理和分配资源。具中关键的数据结构resource源码如下:用于连接parent,child,sibling成员规则如下:在内存中表示数据结构时,我们必须要注意几个问题:为确保可靠地配詈资源(无论何种类型),内核必须提供一种机制来分配和释放资源。一旦资源已经分配,则不能由任何其他驱动程序使用。请求资源内核提供了_request_resource函数,用于请求一个资源原创 2022-12-03 15:29:55 · 489 阅读 · 0 评论 -
内核模块
modprobe在识别出目标模块所依赖的模块之后,在内核中也会使用insmod,在用户空间对模块的处理也是基于insmod。因为模块使用了持久编译到内核中的函数,在模块本身编译时无法确定这些函数的地址,所以的要在这里处里未定义的引用。内核中驻留的每一个模块,都分配了该结构的一个实例。模块使用ELF二进制恪式,模块中包含了几个额外的段,普通的程序或库中不会出现。处理未解决的引用,为与内核的剩余部分协作,模块必须使用内核提供的函数。当然,前提是该模块的代码不再使用,并且其他模块也不再使用该模块导出的函数。原创 2022-12-03 12:59:15 · 734 阅读 · 0 评论 -
应用层open->软中断指令->底层驱动xxx_open
驱动程序中实现file_operations中的open函数,在应用层中使用open来调用到内核中实现的file_operations中的open函数,那么如何实现的呢?原创 2022-12-02 21:40:09 · 428 阅读 · 0 评论 -
进程原理及其系统调用
操作系统作为硬件的使用层,提供使用硬件资源的能力,进程作为操作系统使用层,提供使用操作系统抽象出的资源层的能力。进程:是指计算机中己运行的程序。进程本身不是基本的运行单位,而是线程的容器。程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行实例。原创 2022-11-29 20:30:49 · 776 阅读 · 0 评论 -
字符设备的编写一
字符设备是Linux驱动中三大设备之一,字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少要实现open、close、read和write的系统调用。字符终端(/dev/console)和串口(/dev/ttyS0以及类似备)就是两个字符设备,它们能很好的说明“流”这种抽象概念。字符设备可以通过文件节点来访问,比如/dev/tty1和/dev/lp0等。原创 2022-10-31 13:17:52 · 392 阅读 · 0 评论 -
linux模块化编程
最近挺忙的,疫情加课程,另外还在不断学习Linux,都要忘了和大家分享了。不过它还是来了,在第二章学习完之后,我对Linux的一些概念有了了解,至于能不能口述,还得背背,而对于makefile吗,知道怎么用,会移植就好了,它其实算个脚本吧。在这一章,将学习模块化编程的步骤和规范。以上就是模块化编程的步骤。原创 2022-10-27 14:13:36 · 593 阅读 · 0 评论 -
内核是如何运行ko文件的--系统调用
系统调用是操作系统扌是供给编程人员的接囗,当编程人员写程序时,因为上层应用不能直接操作硬件,所以就要利用系统调用接囗来请求操作系统的照务,如访问硬件。系统调用是和CPU架进行绑定的。和内核版本也有关系。回到init_module和finit_module这俩个系统调用就是应用程序调用系统调用,内核就会执行运行ko文件的操作。原创 2023-03-31 18:41:20 · 1520 阅读 · 0 评论 -
内核是如何运行ko文件的--insmod命令
insmod命令将文件加载到Linux系统中运行。那Linux系统是如何加载的文件呢?加载ko文件使用的是insmod命令,insmod命令做了哪些事情呢?实际上,命令本质上是一个可执行程序,也是有源码的。我们来看下insmod命令的源码。打开busybox源码busybox/modutils/insmod.c文件,找到以下代码。所以可知使用的是finit_module。使用自己的命令来安装驱动。结果与insmod相同。insmod命令流程。原创 2023-03-31 18:37:09 · 2233 阅读 · 0 评论 -
驱动代码使用Makefile的宏
EXTRA_CFLAGS替换 KBUILD_CFLAGS_MODULE。KBUILD_CFLAGS_KERNEL编译进内核使用宏。KBUILD_CFLAGS_MODULE编译成模块使用宏。再Makefile中定义DEBUG宏(注意格式+)原创 2023-03-31 18:34:49 · 293 阅读 · 0 评论 -
编译进内核的驱动是如何工作的
打开内核源码下的顶层Makefile,驱动编译进内核KBUILD_AFLAGS_KERNEL决定驱动编译成模块KBUILD_AFLAGS_MODULE决定所以这里时驱动编译成模块即。原创 2023-03-29 17:41:36 · 297 阅读 · 0 评论 -
内核模块符号导出
驱动程序可以编译成内核模块,也就是KO文件。每个KO文件是相互独立的,也就是说模块之间无法互相访问。但是在某些使用场、要互相访问,如B模块要用A模块中的函数。(B模块依赖于A模块)这时候我们要怎么做呢?模块可以使用一下宏EXPORT_SYMBOL和EXPORT_SYMBOL_GPL导出符号到内核符号表中。所谓“符号"就是内核中的函数名,全局变量名等。符号表就是用来记录这些“符号"的文件。导出去的符号可以被其他模块使用。使用前只需要声明一下即可。原创 2023-03-29 17:37:19 · 343 阅读 · 0 评论 -
驱动模块传参
在系统编程中绝大多数情况需要main函数作为程序的入口函数来进行参数的传递。参数说明:argc英文全称为argument count,代表形参表示传入参数的个数。argv全称为argument value,代表参数传入的值。在装载内核模块时,用户可以向模块传递参数,形式为“insmode(或 modprobe)模块名参数名=参数值”,如果不传递,参数将使用模块内定义的缺省值。原创 2023-03-29 17:30:51 · 681 阅读 · 0 评论 -
Linux内核源码介绍
我的开发环境:内核版本4.1.15开发板正点原子阿尔法IMX6ULL开发板source insight写代码,搭建samba服务器与Ubuntu虚拟机共享代码所在目录,Ubuntu与开发板使用nfs共享代码目录。无操作系统时的驱动(裸机)有的时候并不一定需要操作系统,比如用亠些行简单的通断控制,从编程角度来说,直接控制寄存器就可以了,也就是直接和硬件打交道。有操作系统时的驱动(Linux系统)从编程角度看:有了操作系统以后,编写驱动就变的比较复杂,要基于Linux种驱动框架进行编程。但是当驱动都按原创 2023-03-28 22:27:44 · 2828 阅读 · 0 评论 -
驱动程序的helloworld
我的开发环境:内核版本4.1.15开发板正点原子阿尔法IMX6ULL开发板source insight写代码,搭建samba服务器与Ubuntu虚拟机共享代码所在目录,Ubuntu与开发板使用nfs共享代码目录。原创 2023-03-29 17:07:04 · 395 阅读 · 0 评论 -
驱动编译进Linux内核
每个选项都必须指定类型,类型包括bool,tristate,string,hex,int最常见的是bool,tristate,string这二个。选项的状态有[ ],< >,()三种表示状态,其中[ ]表示有俩种状态,只能设置成选中或者不选中,< >表示有三种状态,可以设置成选中,不选中,和编译成模块。config文件和.config文件都是Linux内核的配置文件,config文件位于Linux内核源码的arch/$(ARCH)/configs目录下,是Linux系统默认的配置文件。这俩个是成对出现的。原创 2023-03-29 17:16:21 · 744 阅读 · 0 评论