如何编译一个linux下的驱动模块

如何编译一个linux下的驱动模块,第1张

linux下编译运行驱动

嵌入式linux下设备驱动的运行和linux x86 pc下运行设备驱动是类似的,由于手头没有嵌入式linux设备,先在vmware上的linux上学习驱动开发。

按照如下方法就可以成功编译出hello world模块驱动。

1、首先确定本机linux版本

怎么查看Linux的内核kernel版本?

'uname'是Linux/unix系统中用来查看系统信息的命令,适用于所有Linux发行版。配合使用'uname'参数可以查看当前服务器内核运行的各个状态。

#uname -a

Linux whh 3.5.0-19-generic #30-Ubuntu SMPTue Nov 13 17:49:53 UTC 2012 i686 i686 i686 GNU/Linux

只打印内核版本,以及主要和次要版本:

#uname -r

3.5.0-19-generic

要打印系统的体系架构类型,即的机器是32位还是64位,使用:

#uname -p

i686

/proc/version 文件也包含系统内核信息:

# cat /proc/version

Linux version 3.5.0-19-generic(buildd@aatxe) (gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) ) #30-UbuntuSMP Tue Nov 13 17:49:53 UTC 2012

发现自己的机器linux版本是:3.5.0-19-generic

2、下载机器内核对应linux源码

到下面网站可以下载各个版本linux源码https://www.kernel.org/

如我的机器3.5.0版本源码下载地址为:https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.5.tar.bz2

下载完后,找一个路径解压,如我解压到/linux-3.5/

然后很重要的一步是:执行命令uname -r,可以看到Ubuntu的版本信息是3.5.0-19-generic

。进入linux源码目录,编辑Makefile,将EXTRAVERSION = 修改为EXTRAVERSION= -19-generic。

这些都是要配置源码的版本号与系统版本号,如果源码版本号和系统版本号不一致,在加载模块的时候会出现如下错误:insmod: error inserting 'hello.ko': -1 Invalid module format。

原因很明确:编译时用的hello.ko的kenerl 不是我的pc的kenerl版本。

执行命令cp /boot/config-3.5.0-19-generic ./config,覆盖原有配置文件。

进入linux源码目录,执行make menuconfig配置内核,执行make编译内核。

3、写一个最简单的linux驱动代码hello.c

/*======================================================================

Asimple kernel module: "hello world"

======================================================================*/

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE("zeroboundaryBSD/GPL")

static int hello_init(void)

{

printk(KERN_INFO"Hello World enter\n")

return0

}

static void hello_exit(void)

{

printk(KERN_INFO"Hello World exit\n ")

}

module_init(hello_init)

module_exit(hello_exit)

MODULE_AUTHOR("zeroboundary")

MODULE_DESCRIPTION("A simple HelloWorld Module")

MODULE_ALIAS("a simplestmodule")

4、写一个Makefile对源码进行编译

KERN_DIR = /linux-3.5

all:

make-C $(KERN_DIR) M=`pwd` modules

clean:

make-C $(KERN_DIR) M=`pwd` clean

obj-m += hello.o

5、模块加载卸载测试

insmod hello.ko

rmmod hello.ko

然后dmesg|tail就可以看见结果了

最后,再次编译驱动程序hello.c得到hello.ko。执行insmod ./hello.ko,即可正确insert模块。

使用insmod hello.ko 将该Module加入内核中。在这里需要注意的是要用 su 命令切换到root用户,否则会显示如下的错误:insmod: error inserting 'hello.ko': -1 Operation not permitted

内核模块版本信息的命令为modinfo hello.ko

通过lsmod命令可以查看驱动是否成功加载到内核中

通过insmod命令加载刚编译成功的time.ko模块后,似乎系统没有反应,也没看到打印信息。而事实上,内核模块的打印信息一般不会打印在终端上。驱动的打印都在内核日志中,我们可以使用dmesg命令查看内核日志信息。dmesg|tail

可能还会遇到这种问题insmod: error inserting 'hello.ko': -1 Invalid module format

用dmesg|tail查看内核日志详细错误

disagrees about version of symbolmodule_layout,详细看这里。

http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/index.html

在X86上我的办法是:

make -C/usr/src/linux-headers-3.5.0-19-generic SUBDIRS=$PWD modules

Linux su,全拼:switch user,命令用于变更为其他使用者的身份,除root外,需要键入使用者的密码。

使用权限:所有使用者

语法:

su [参数] [-] [用户帐号]

参数说明:

-f或者--fast不必读启动档,仅用于csh或tcsh

-m -p或者-preserve-environment执行su时不改变环境变数

-c command或者--command=command变更为账号为USER的使用者并执行指令后再变回原来使用者

-s shell或者--shell=shell指定要执行的shell,预设值为/etc/passwd内的该使用者shell

-help 显示说明文件

--version 显示版本资讯

-

-l或者--login这个参数加了之后,就好像是重新login为该使用者一样,大部分环境变数都是以该使用者为主,并且工作目录也会改变,如果没有指定USER,内定是root

USER 欲变更的使用者账号

ARG 传入新的shell参数

su命令功能说明:切换用户身份。

语法:su [-flmp][--help][--version][-][-c <指令>][-s

][用户帐号]

补充说明:su可让用户暂时变更登入的身份。变更时须输入所要变更的用户帐号与密码。

参数:

 -c<指令>或--command=<指令> 执行完指定的指令后,即恢复原来的身份。

 -f或--fast  适用于csh与tsch,使shell不用去读取启动文件。

 -.-l或--login  改变身份时,也同时变更工作目录,以及HOME,SHELL,USER,LOGNAME。此外,也会变更PATH变量。

 -m,-p或--preserve-environment  变更身份时,不要变更环境变量。

 -s

或--shell=

 指定要执行的shell。

 --help  显示帮助。

 --version  显示版本信息。

 [用户帐号]  指定要变更的用户。若不指定此参数,则预设变更为root。

示例: 

su -c ls root#变更帐号为 root 并在执行 ls 指令后退出变回原使用者。

su root -f#变更帐号为 root 并传入 -f 参数给新执行的 shell。

su - test#变更帐号为 test 并改变工作目录至 test 的家目录(home dir)。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7236374.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-03
下一篇 2023-04-03

发表评论

登录后才能评论

评论列表(0条)

保存