一个最简单的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”,了解相关信息可以关注。

时间: 2024-07-29 20:47:15

一个最简单的Linux驱动程序的编译运行的相关文章

c++ 连接数据库什么方式最好?要在windows和linux都能编译运行

问题描述 c++ 连接数据库什么方式最好?要在windows和linux都能编译运行 c++ 连接主流数据库什么方式最好呢,最好能介绍一下各种方式的优缺点,谢谢! SqlApi怎样呢?有没有开源的免费的? 解决方案 无非就是把差异的代码分开来.如果是C++,你可以写一个抽象类,访问数据库.你的程序操作这个抽象类. 然后不同的数据库,继承这个抽象类,把差异的代码写在里面. 而使用工厂设计模式,并且把这些代码条件编译. 这样你的程序代码只维护一份,就能适应不同的数据库了. 解决方案二: 用sqlit

在VMware上制作一个简单的Linux

大体思路 boot root initrd.gz grub vmlinuz-2.6.18-308.el5 bin sbin lib etc proc sys dev boot   有以上内容我们就可以运行一个非常简单的Linux,只需要往里面添加各种配置文件,就可以启动我们所需要的各种服务.在制作之前,我们先做一些准备工作. 1.在VMware上添加一块新的IDE磁盘 2.将这块盘分区,/dev/hdb1 /dev/hdb2,之后格式化为ext3的文件系统 3.挂载/dev/hdb1到/mnt/

flex-【求助】如何编译运行一个java demo

问题描述 [求助]如何编译运行一个java demo 运行结果如下 如果是一个helloworld的java文件,我编译运行成功过,应该不是环境问题,哪位大神能否帮忙看下?我附上代码链接http://download.csdn.net/detail/zhuifeng20008/9439664 我的问题是如何编译这个demo 解决方案 看了你的源码,主要有如下问题 1.编码问题,解决办法为新建三个一样名字的java文件,将原文件内容复制到新建的文件中 2.代码问题,修改public static

《Android深度探索(卷1):HAL与驱动开发》——6.5节使用Eclipse开发和测试Linux驱动程序

6.5 使用Eclipse开发和测试Linux驱动程序 Android深度探索(卷1):HAL与驱动开发 在前面几节开发的word_count驱动和测试程序大多都需要在Linux终端进行编译(Android应用程序除外)和运行,而且也无法跟踪到Linux内核函数.变量.宏的内部(除非自己到Linux内核源代码中就寻找这些源代码文件),这并不利于深入了解Linux内核技术.在本节将为读者展示如何在Eclipse中开发Linux驱动程序,并且可以像跟踪Java代码一样直接跟踪到Linux内核源代码.

简单字符设备驱动程序

linux驱动程序开发步骤 1)查看原理图.数据手册,了解设备的操作方法. 2)在内核中找到相近的驱动程序,以它为模板进行开发,有时候需要从零开始. 3)实现驱动程序的初始化:比如向内核注册驱动程序,这样应用程序传入文件名时,内核才能找到相应的驱动程序. 4)设计所要实现的操作,比如open,read,write,close. 5)实现中断服务(不是必需的) 6)编译该驱动程序到中,或者用insmod命令加载. 7)测试驱动程序.    驱动框架 应用程序API接口read,open,write

linux使用gcc编译c语言共享库步骤_C 语言

对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例如一个数据库服务器的接口,就像MySQL. 大部分大型的软件项目都会包含若干组件,其中一些你发现可以用在其他项目中,又或者你仅仅出于组织目的将不同组件分离出来.当你有一套可复用的并且逻辑清晰的函数时,将其构建为一个库会十分有用,这样你就不将这些源代码拷贝到你的源代码中,而且每次都要再次编译它们.除此之外,你还可以保证你的程序各模块隔离,这

依赖-linux ldd 自己编译的.so 提示PIC =&amp;amp;gt;no found

问题描述 linux ldd 自己编译的.so 提示PIC =>no found 问题是这样的,我编译一个.so动态链接库的时候,依赖一些.o目标文件,提示我编译.o的时候要用-fPIC选项去编译目标文件,这个地方我觉得很奇怪,之前没有这样用过.最终我写了一个简单的demo去调用我自己写的.so的时候,提示依赖的.o(目标文件)中的几个函数没有定义,让我很费解, 我怀疑是没有连接进我最终的.so中,于是我ldd查看一下我最终的.so依赖的文件哪些不错在,ldd之后得到结果 , 提示PIC=>n

linux 6下编译安装配置LAMP平台

LAMP(Linux- Apache-MySQL-PHP)网站架构是目前国际流行的Web框架,该框架包括:Linux操作系统,Apache网络服务器,MySQL数据库,Perl.PHP或者Python编程语言,所有组成产品均是开源软件,是国际上成熟的架构框架,很多流行的商业应用都是采取这个架构,和Java/J2EE架构相比,LAMP具有Web资源丰富.轻量.快速开发等特点,微软的.NET架构相比,LAMP具有通用.跨平台.高性能.低价格的优势,因此LAMP无论是性能.质量还是价格都是企业搭建网站

《Linux设备驱动开发详解 A》一一3.4 Linux内核的编译及加载

3.4 Linux内核的编译及加载 3.4.1 Linux内核的编译 Linux驱动开发者需要牢固地掌握Linux内核的编译方法以为嵌入式系统构建可运行的Linux操作系统映像.在编译内核时,需要配置内核,可以使用下面命令中的一个: make conf?ig(基于文本的最为传统的配置界面,不推荐使用) make menuconf?ig(基于文本菜单的配置界面) make xconf?ig(要求QT被安装) make gconf?ig(要求GTK+被安装) 在配置Linux内核所使用的make c