也学了10天左右的linux驱动开发了,一般学习新知识的时候,我都喜欢首先理清思路,然后才去关注更加细节的东西,这次也不例外。
正如我前面写的几篇博客,主要内容包括linux内核
和linux发行版
的概念与区别;linux系统
和linux内核源码
的目录分析;设备驱动
的作用,裸机设备驱动
和linux系统中的设备驱动
有什么区别等等,都是在以一个小白的视角来记录一些必须提前了解的知识。当我们后面遇到一些概念或者一些操作的时候,能够帮助我们更快的理解这些概念和操作具体是什么意思,我相信这是非常有帮助的。
在前面我已经写了两篇关于如何从零开始写一个简单的字符设备驱动的文章,但是即使在已经了解了字符设备驱动开发的大致流程的情况下,我依然有很多的疑问,那就是我到底应该如何把编写好的驱动真正的使用起来?
通过这几天迷迷糊糊的资料查询,终于是有了初步的了解。今天我就来简单的说一下,当然不会涉及到很多的细节,旨在理清思路,还是那句话思路很重要。
以下都是我自己的一些理解,加上搜索到的一些资料,有错误是在所难免。如果有错误,还请大家指出来(哈哈)!!
二、两种使用方式正如我们的题目所述,新编写的驱动程序主要有两种处理方式,也即我们可以通过两种方式来使用我们新编写的驱动。一种方式是将驱动程序编译成.ko
文件,另一种方式就是将驱动程序直接编译进内核
。它们刚好对应着动态编译和静态编译这两种编译模式。
-
静态编译:就是将驱动源码,放到
kernel内核
的源码中的对应文件夹下面,并且需要添加或者修改Kconfig
和Makefile
文件,再通过图形界面来配置相应的选项,配置好选项后保存退出,然后编译,最后编译出来的是一个整合后用于烧录到板端
的文件,如zImage
。具体可以参考这篇文章:linux驱动程序——将驱动程序编译进内核 -
动态编译:就是将驱动源码编译成
.ko
文件,最后通过insmod
命令去板端
加载这个.ko
文件。具体可以参考我之前的两篇博客:如何开始编写你的第一个字符设备驱动?和 如何编写应用程序去验证我们的字符设备驱动程序?
你可能已经发现,就是我们提到了板端
这个词,没错,这里我们就是假设你有一个能够运行linux系统
的板子,比如运行raspbian
的Raspberry Pi
或者运行armbian
的orange Pi
,当然还有很多其他类型的板子。我们是使用PC
来开发驱动程序,并且执行编译操作,然后将生成的一些文件拷贝到板端
进行运行验证。
从以上的描述中,你可能已经大致了解对写好的驱动程序进行动态编译和静态编译是什么意思了,其实这里面还有一些问题需要注意。
1、内核源码
- 其实我刚开始的时候对于内核源码的选择纠结了很久,因为内核源码一般有三个来源,分别是linux官方的内核,芯片厂商修改后的内核以及开发板厂商(或者说适配系统到该板子的一方)修改后的内核。
- 其实很好理解,后面两者都是为了适应自己的芯片或者开发板专门对内核做了修改,加入了一些新的功能,我们上面所说的驱动开发就属于这种情况。所以,最合适的当然是板子中运行的系统对应的内核,对应的就是第三种来源。例如对树莓派的内核进行修改和编译的时候就会从树莓派的官网去下载内核源码。
- 但是其他的相同版本号的内核可以使用吗?我的理解是可以,因为本身目前所使用系统的内核就是一步一步在最基础的内核上修改得到的。但是,显而易见的是使用这种内核进行驱动开发是相对较困难的,所以一般都是使用和板子上运行的系统正在使用的内核对应的内核。
2、交叉编译器
- 因为我们是在
PC
上进行的驱动开发,所以最后编译的时候,如果直接使用gcc
,那么编译出的模块是只能运行在x86
平台上的,因此我们需要使用交叉编译器
将其编译成能够在ARM
平台上运行的模块。以上所说的还是比较容易理解的。