linux驱动入门之hello wrold

Posted Welljia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux驱动入门之hello wrold相关的知识,希望对你有一定的参考价值。

第一个驱动程序:Hello World

在linux上,所有的设备都可以看成是文件。我们对设备的所有操作基本上都可以简化成open、close、read、write、io control这几个操作。

源代码
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");

static int hello_inti(void)

    printk(KERN_ALERT "Hello, world\\n");
    return 0;


static void hello_exit(void)

    printk(KERN_ALERT "Goodbye, cruel world\\n");  


module_init(hello_init);
module_exit(hello_exit);

所有模块都包含的两个头文件:

#include <linux/init.h>
#include <linux/module.h>

module.h包含有可装载模块需要的大量符号和函数的定义,init.h主要用来指定初始化和清除函数。

初始化函数应该被声明为static,因为这种函数在特定文件之外没有其他意义。其实际定义通常如下:

static int __init initialization_function(void)

    /* Initialization code here */

module_init(initialization_function);

__init 标志是一个给内核的暗示, 给定的函数只是在初始化使用,模块加载者在模块加载后会丢掉这个初始__化函数, 使它的内存可做其他用途。一个类似的标签 (__initdata) 给只在初始化时用的数据.

使用 moudle_init 是强制的. 这个宏定义增加了特别的段到模块目标代码中,表明在哪里找到模块的初始化函数. 没有这个定义, 你的初始化函数不会被调用.

有初始化函数就有退出的清理函数,其定义如下:

static void __exit cleanup_function(void)

/* Cleanup code here */

module_exit(cleanup_function);

清理函数没有返回值, 因此它被声明为 void. __exit 修饰符标识这个代码是只用于模块卸载( 通过使编译器把它放在特殊的 ELF 段). 如果你的模块直接建立在内核里, 或者如果你的内核配置成不允许模块卸载, 标识为 __exit 的函数被简单地丢弃. 如果你的模块没有定义一个清理函数, 内核不会允许它被卸载.

创建Makefile

obj-m := hello.o

上面的赋值语句说明了有一个模块需要从目标文件hello.o中构造,而从该目标文件中构造的模块名称为hello.ko,因为是从内核构造系统中调用的,所以可利用其内建语句,但如果从命令行调用,Makefile文件则如下所示:

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

完整的Makefile则如下所示:

# KERNELRELEASE时内核源代码顶层所定义的一个变量
# ifneq ($(KERNELRELEASE),)表示判断该变量是否为空,即有没有定义,没有便执行else中的内容
ifneq ($(KERNELRELEASE),)

# obj-m后面跟的就是最终的模块名,hello.o, make会在该目录下自动找到hello_driver.c文件进行编译
obj-m := hello.o

# uname -r命令输出当前系统所使用的版本号
# build只是一个符号链接,一般它指定的正是你的源码所在的目录
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build

# 显示当前目录
PWD := $(shell pwd)

#当执行到modules时,-C $(KERNELDIR) 指明跳转到内核源码目录下读取那里的Makefile
#M=$(PWD) 表明之后返回到当前目录继续读入、执行当前的Makefile。
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif

执行make编译后,便可进行加载和卸载了(只有超级用户可以加载和卸载模块)

[加载] 
[Linux@] #insmod ./hello.ko 
[卸载] 
[Linux@] #rmmod hello
[查看内核输出] 
///var/log/messages 是系统日志文件
[Linux@] #tail /var/log/messages 

在加载和卸载的过程中,就会有信息输出,通过dmesg打印输出。

以上是关于linux驱动入门之hello wrold的主要内容,如果未能解决你的问题,请参考以下文章

Linux 驱动之 Hello World

[driver]简单地hello驱动加载

linux脚本入门之终端显示输出

设备驱动之HelloWorld-1

AM335x内核模块驱动之LED

java之字符串linux中jdk配置