Linux 简单字符设备驱动

1、hello_drv.c

(1) 初始化和卸载函数的格式是固定的,函数名自定义

(2) printk是内核的打印函数,用法与printf一致

(3) MODULE_LICENSE:模块代码支持开源协议(必须包含此项)

      MODULE_AUTHOR:模块作者

      MODULE_DESCRIPTION:模块简单描述

      MODULE_VERSION:模块代码版本

      MODULE_ALIAS:模块的别名

      MODULE_DEVICE_TABLE:模块支持什么设备


// 模块化程序必须包含的两个头文件
#include <linux/module.h>
#include <linux/init.h>

// __init 标记为初始化代码,仅在初始化时使用
static int __init hello_init(void)
{
	printk("-----%s-----
", __FUNCTION__);

	return 0;
}

// __exit 标记为卸载函数,仅在卸载时使用
static void __exit hello_exit(void)
{
	printk("-----%s-----
", __FUNCTION__);
}

// 模块入口函数,insmod会调用hello_init
module_init(hello_init);
// 模块出口函数,rmmod会调用hello_exit
module_exit(hello_exit);

// 模块遵循开源协议
MODULE_LICENSE("GPL");
// 模块的开发者
MODULE_AUTHOR("Aaron Lee");


2、Makefile

在模块源码目录下使用make指令会自动调用当前目录下的Makefile文件来编译生成hello_drv.ko


# KERNEL_DIR为内核源码路径变量,根据实际情况选择编译过的源码路径
KERNEL_DIR = /home/lialong/iTop4412_Kernel_3.0
# CUR_DIR为需要编译的文件路径,$表示取变量值
CUR_DIR = $(shell pwd)

# 驱动代码文件名
DRV_NAME = hello_drv
# 应用代码文件名
#USR_NAME = hello_app

# -C 指定内核Makefile文件的路径
# M 指定要编译代码的路径
# modules 将程序编译成.ko文件
# arm-none-linux-gnueabi-gcc使用交叉编译工具编译应用层代码
all:
	make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
#	arm-none-linux-gnueabi-gcc $(USR_NAME).c -o $(USR_NAME)

# make clean 
# 调用内核中make clean方法在本目录下使用
# 删除编译产生的后缀为.o的文件
clean:
	make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
	rm -rf *.o

# 需要编译的的文件
obj-m += $(DRV_NAME).o



3、加载模块 insmod hello_drv.ko

打印 -----hello_init-----


4、卸载模块 rmmod hello_drv (卸载不加.ko后缀)

打印 -----hello_exit-----


原文地址:https://www.cnblogs.com/lialong1st/p/7756677.html