我们已经准备好了,你呢?

2024我们与您携手共赢,为您的企业形象保驾护航!

Linux驱动程序的编译安装有两种类型:动态加载和静态加载

动态加载

1.编译,在指向的内核树下进行编译,生成.o文件或者.ko文件

二、将生成的.o或.ko文件复制到相应目录下,一般是/lib//

3.使用命令加载,使用rmmod命令卸载

静态加载

静态加载主要就是对内核进行编译,也就是把写好的驱动放到内核对应的目录下,然后对内核进行编译,最后运行编译好的内核。

静态加载是把驱动程序直接编译到内核中,这样系统启动后就可以直接调用。静态加载的缺点是调试起来比较麻烦,每次改变都要重新编译下载内核,效率很低。

动态加载利用了LINUX的特点,可以在系统启动后用命令添加驱动(.o文件),不需要的时候用rmmod命令卸载。动态加载一般在台式机上使用。

在嵌入式产品中可以先通过动态加载的方式进行调试,调试完成后再编译进内核,下面以我们的nHD板子为例介绍如何加载驱动。

假设我们需要添加一个名为mydrv的字符设备驱动,主设备号为254,次设备号为0(只有一个从设备),静态加载的步骤如下:

1、编写自己的驱动源文件mydrv.c,放在\--2500\linux-2.4.x\\char下。一个典型的字符驱动程序一般包括以下内容:

int(空)

int ret;

ret = (, “mydrv”, &);

如果 (ret == 0) (“ !\n”);

else ("失败!\n");

0;

void mydrv (void)

(mydrv,“mydrv”);

(" !\n");

(初始化);

(我的驱动器);

函数的任务是注册设备,函数的任务是取消注册。 和 函数将在后面讨论。

2、在\--2500\\\2500\中添加如下语句(以刚才提到的设备为例,具体要根据自己的设备名和设备号来添加):

mknod $() /dev/mydrv c 254 0

该语句的作用是在内核中创建一个与你的驱动程序对应的设备节点。

3. 在 \--2500\linux-2.4.x\\char\

添加以下语句:

obj-$() +=mydrv.o

该语句的作用是根据编译选项$()来决定是否添加设备驱动。

4. 在 \--2500\linux-2.4.x\\char\.in

添加于:

如果 [“$”=”y”]; 那么

',我的驱动器'

该语句的作用是在运行make的时候生成对应你的设备的编译选项。

5. 运行 make,您应该会看到适合您自己设备的选项,只需选择它即可。

6.编译内核,下载并运行自己的测试程序。

如果你觉得以上步骤麻烦,可以跳过4和5,直接

obj-$() +=mydrv.o

改成

obj-y +=mydrv.o

这样就不会有你的设备对应的选项了,编译的时候会直接把你的驱动编译到内核里。

还有一个问题需要说明一下。在...//char下有个mem.c文件,最后面有一个int(void)函数。可以看到,所有的字符设备初始化函数(诸如此类)都要加在这里,但是我们的驱动程序的初始化函数却没有加在这里。这个问题涉及到系统启动时的函数,详细讲解起来比较麻烦。有兴趣的可以看看《情景分析》第二卷P726~P729。这里就简单介绍一下。如果对一个函数(通常是一些初始化函数)的处理如下(仍以我们的函数为例):

()

然后在编译内核的时候会产生一个函数指针,在系统启动运行该函数的时候会依次执行这些初始化函数,初始化完成后就会释放这些函数所占用的内存。

回到mem.c文件,最后有一行:

()

这句话的目的很明显,该函数是系统启动时自动执行的。所以我们不需要在mem.c/中添加自己的初始化函数,而是在我们自己的设备文件(mydrv.c)中添加如下一行:

()。

在前面提到的我们自己的设备文件mydrv.c中,最后有这么一句话:

(初始化);

你可以看一下 ...linux.-2.4.x\\linux\init.h 中的定义。如果定义了该宏,则将其用作模块初始化函数。如果没有定义,则

(fn) 定义为 (fn)。它在静态编译时没有定义,因此我们驱动程序中的定义是:

()。

这样我们的初始化函数就会在启动时执行。

你的设备初始化函数是放在 mem.c/ 里还是放在设备文件中,完全看你的喜好,没什么区别。如果你的初始化函数只注册了一个设备(没有申请内存等),那么在两个地方都添加也没关系(相当于初始化了两次),也不会报错(你可以看看内核的设备注册函数实现,

…linux-2.4.x\fs\.c\)。但是为了标准化,不建议这么做。

最后一个问题:当驱动程序静态加载的时候,我们的函数永远不会被执行,所以删除它是完全没问题的,但是为了程序结构清晰以及与动态加载程序的兼容性,建议保留它。

以下是动态加载驱动程序的方法。

1. 运行 make,进入内核配置,选择 和 (NEW) 选项。进入应用程序配置,选择 rmmod、lsmod 选项。

2.在...\\2500\中添加相应的设备节点,方法和静态加载完全相同。

3.编写自己的驱动文件,在文件开头添加一句话:

最后一个文件

(初始化)

(我的驱动器)

这四项必须保留。

4.按照以下格式编写自己的文件:

= /home/hexf//nHD///--2500/linux-2.4.x

= - -I$()/ -Wall -- -Wno- -O2 -fno-- -fno- -fno- -pipe -fno- - - -mapcs-32 --load-bytes -msoft-float

CC = arm-elf-gcc

全部:mydrv.o

干净的:

rm -f *.o

5. 编译自己的驱动文件。注意,动态加载时只编译不链接,所以得到的是.o文件。

6.将编译好的驱动程序的.o文件和自己的测试程序(假设是调用的,注意这是可执行文件)一起放到编译服务器的//自己的目录下。测试程序就是一个普通的应用程序,这里就不描述编写和编译的步骤了。

7.启动nHD板子,使用nfs的方式将自己的目录挂载到编译服务器上(假设挂载到/mnt)。Nfs的使用大家都很熟悉了,这里就不解释了。

8、

cd /mnt

/bin/mydrv.o

现在你的设备已经动态加载到系统中了,你可以使用 lsmod 命令查看当前挂载的模块。

9. 运行测试程序

10. 调试完成后,使用 rmmod mydrv 卸载您的设备。

另外几点:

1.关于建立设备节点的问题,由于每个人的系统都不一样,所以可以不用按照我说的方法,简单来说就是在自己系统的dev目录下建立自己驱动的设备节点就可以了。

2.没有考虑动态分配主设备号的问题,因此设备注册稍微松散一些。

3. 加载模块时,需要将自己的.c文件编译成.o文件。结尾的编译选项字符串有时可能有点烦人。如果你搞不懂,最简单的方法是重新编译内核并将其重定向到文件(别忘了先make clean):make > out。

然后在out文件里找到一个字符驱动的编译过程,找出它的编译选项,复制到自己的里面,我就是这么做的。

下面是一个最简单的字符设备驱动程序的例子。实际的驱动程序千差万别,但实际上它们只是“填充”了自己的 open、close、read、write 和 ioctl 函数。

endif 254 // () // () // 错误代码 // //

int ( inode *inode, 文件 *filp)

(“打开!\n”);

0;

(文件翻转、字符增益、计数、

* f_位置)

char buf[10] = {0x1,0x2,0x3,0x4,0x5};

(BUF,BUF,5);

5;

int ( inode *inode, 文件 *filp)

{;

(“关闭!\n”);

0;

= {

读: ,

// 写: ,

打开: ,

:,

// 读写控制:,

};

int(空)

int ret;

ret = (, “”, &);

如果 (ret == 0) (“ !\n”);

else ("失败!\n");

0;

无效(无效)

(,””);

(" !\n");

(“再见!\n”);

();

();

二维码
扫一扫在手机端查看

本文链接:https://by928.com/2082.html     转载请注明出处和本文链接!请遵守 《网站协议》
我们凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设、网站改版、域名注册、主机空间、手机网站建设、网站备案等方面的需求,请立即点击咨询我们或拨打咨询热线: 13761152229,我们会详细为你一一解答你心中的疑难。

项目经理在线

我们已经准备好了,你呢?

2020我们与您携手共赢,为您的企业形象保驾护航!

在线客服
联系方式

热线电话

13761152229

上班时间

周一到周五

公司电话

二维码
微信
线