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打印输出。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值