一个最简单的Linux驱动程序的编译运行

简介:

一个最简单的Linux驱动程序的编译运行

一、背景知识

可装载内核模块:为了使系统功能能够更灵活的扩充,Linux支持内核的动态扩展,即在系统运行时给内核增加新的功能(即模块module)。

模块:模块(module)是一段可以被动态链接的目标代码(.ko),它可由insmod命令动态的装载并链接到正在运行的内核。链接后,它就成了内核的一部分,直到用rmmod命令解除链接并卸载。

Linux驱动程序就是一种特殊的可装载内核模块。

说明:本代码在linux2.6以上测试运行通过。linux3.*也可。本人用ubuntu12.04,linux内核版本linux3.5。

二、编译内核模块

如何由源码(.c文件)生成动态链接的目标代码(即.ko文件)?

首先写一个最简单的驱动程序源码:hello.c

[html] view plain copy


  
  
  1. #include <linux/init.h> //声明头文件 
  2.  
  3. #include <linux/module.h> 
  4.  
  5. //模块加载函数 
  6.  
  7. static int hello_init(void) 
  8.  
  9.  
  10. printk(KERN_INFO " Hello World enter\n"); //系统调用打印函数,类似于用户调用的printf 
  11.  
  12. return 0; 
  13.  
  14.  
  15. //模块卸载函数 
  16.  
  17. static void hello_exit(void) 
  18.  
  19.  
  20. printk(KERN_INFO " Hello World exit\n "); 
  21.  
  22.  
  23. module_init(hello_init); //向系统注册模块加载函数 
  24.  
  25. module_exit(hello_exit); //向系统注册模块卸载函数 
  26.  
  27. MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); //模块作者等信息声明,可选 
  28.  
  29. MODULE_LICENSE("Dual BSD/GPL"); //模块许可证声明 
  30.  
  31. MODULE_DESCRIPTION("A simple Hello World Module"); //模块描述声明,可选 
  32.  
  33. MODULE_ALIAS("a simplest module"); //模块别名的声明,可选 

将这段程序编译为hello.ko的步骤:

1、编写makefile文件

[html] view plain copy


  
  
  1. KVERS = $(shell uname -r) #变量KVERS为当前linux版本值 
  2.  
  3. obj-m += hello.o 
  4.  
  5. default
  6.  
  7. make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules 

-C后面是linux内核源码树目录,M=后面是源码目录

2、在终端下输入 cd /**/**,找到hello.c源码所在的目录

3、在终端输入 make命令。

4、如图所示即可生成hello.ko文件。

其他文件是生成的一些中间文件。

三、装载

加载:在终端输入insmod命令,模块加载完成。

注意:如果终端没有打印printk语句,在linux系统日志文件/var/log/syslog中查看。

卸载:在终端输入remmod命令。

打印信息同在日志文件中。

四、一些理论知识

模块加载函数:用宏“module_init”指定,它返回整型值。若初始化成功则返回0,若失败则返回一个负值作为错误码。

模块卸载函数必须用宏“module_exit”指定,无返回值。

printk用法:

1、printk(KERN_INFO "Hello, world!/n");

2、printk("<6>Hello, world!/n");

第一个参数指定输出级别:分为以下八种:

1、KERN_EMERG 用于紧急消息, 常常是那些崩溃前的消息.

2、KERN_ALERT 需要立刻动作的情形.

3、KERN_CRIT 严重情况, 常常与严重的硬件或者软件失效有关.

4、KERN_ERR 用来报告错误情况; 设备驱动常常使用 KERN_ERR 来报告硬件故障.

5、KERN_WARNING 有问题的情况的警告, 这些情况自己不会引起系统的严重问题.

6、KERN_NOTICE 正常情况, 但是仍然值得注意. 在这个级别一些安全相关的情况会报告.

7、KERN_INFO 信息型消息. 在这个级别, 很多驱动在启动时打印它们发现的硬件的信息.

8、KERN_DEBUG 用作调试消息.


原文发布时间为:2017-10-24 

本文作者:佚名

本文来自云栖社区合作伙伴“51CTO”,了解相关信息可以关注。

相关文章
|
3月前
|
安全 Linux Shell
Linux上执行内存中的脚本和程序
【9月更文挑战第3天】在 Linux 系统中,可以通过多种方式执行内存中的脚本和程序:一是使用 `eval` 命令直接执行内存中的脚本内容;二是利用管道将脚本内容传递给 `bash` 解释器执行;三是将编译好的程序复制到 `/dev/shm` 并执行。这些方法虽便捷,但也需谨慎操作以避免安全风险。
189 6
|
2月前
|
机器学习/深度学习 人工智能 Ubuntu
|
2月前
|
存储 数据可视化 Java
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
如何在Linux系统下部署和运行Java项目jar包,包括传输文件到Linux、使用nohup命令运行jar包、查看端口状态、杀死进程和查看项目运行状态,以及如何解决“没有主清单属性”的错误。
504 1
震惊!如何在linux下部署项目,部署/运行jar包 超详细保姆级教程!
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
94 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
2月前
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
|
2月前
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
42 1
|
25天前
|
Linux
Linux - 如何编译源码安装软件
源码编译安装通常包括三个步骤:1) `./configure` 检测平台特征和依赖项,生成 Makefile;2) `make` 编译源码,生成可执行文件;3) `make install` 将可执行文件安装到指定目录并配置环境变量。
38 0
|
2月前
|
Linux 编译器 C语言
Linux c/c++之多文档编译
这篇文章介绍了在Linux操作系统下使用gcc编译器进行C/C++多文件编译的方法和步骤。
42 0
Linux c/c++之多文档编译
|
3月前
|
消息中间件 分布式计算 Java
Linux环境下 java程序提交spark任务到Yarn报错
Linux环境下 java程序提交spark任务到Yarn报错
45 5
|
3月前
|
Linux Shell
6-9|linux查询现在运行的进程
6-9|linux查询现在运行的进程
下一篇
无影云桌面