首页 > 系统相关 >Linux驱动开发 驱动程序的具体编写及出口入口函数解析,printk打印内核信息

Linux驱动开发 驱动程序的具体编写及出口入口函数解析,printk打印内核信息

时间:2023-11-19 17:04:35浏览次数:32  
标签:__ 驱动程序 init exit Linux printk hello 函数

(文章目录)


前言

本文将带大家学习驱动程序的具体编写及出口入口函数解析。

一、出口函数入口函数解析

每一个驱动程序都是含有出口函数和入口函数的,装载驱动的时候先调用入口函数,卸载驱动的时候则调用出口函数。 入口出口函数的形式如下:

static __init int hello_dev_init(void)
{
	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);	
	return 0;
}

static __exit void hello_dev_exit(void)
{
	printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
}


module_init(hello_dev_init);
module_exit(hello_dev_exit);

module_init和module_exit的作业是将上面两个函数分别修饰为入口函数和出口函数,一般的函数我们不能随意指定他就是出口函数和入口函数,必须经过指定后才能认为他是入口函数和出口函数。

有同学可能会有疑惑为什么这两个函数前面要加__init和__exit呢? 其实__init和__exit就只是一个空的宏,入口函数和出口函数在整个过程中都只会调用一次,调用完后我们可以将其释放节省内存,使用这两个标识就可以达到这样的效果。 在这里插入图片描述

二、printk内核打印信息

在普通的程序中我们一般使用的是printf来输出打印信息,但是在Linux内核中要用printk来打印输出信息。 一般默认情况下内核的打印信息是没有打开的,我们需要将其打开。

cat /proc/sys/kernel/printk//查看设置值
echo 7       4       1      7 > /proc/sys/kernel/printk//打开内核打印信息

将内核的打印功能打开后我们就可以使用printk去打印输出信息了。

三、驱动程序的具体编写

1.确定主设备号 主设备号可以由我们自己指定,也可以由系统帮我们指定。

static int major = 0;

2.构造file_operations结构体

static struct file_operations hello_drv = {
	.owner	 = THIS_MODULE,
	.open    = hello_drv_open,
	.read    = hello_drv_read,
	.write   = hello_drv_write,
};

3.实现对应的open,read,write函数

static ssize_t hello_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	return 1;
}

static ssize_t hello_drv_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	return 1;
}

static int hello_drv_open (struct inode *node, struct file *file)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	return 0;
}

4.注册驱动程序 在Linux中我们会经常听到注册这个词,注册其实就是将结构体添加进链表。

major = register_chrdev(0, "hello", &hello_drv);

5.编写入口函数

static int __init hello_init(void)
{
	int err;
	
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	major = register_chrdev(0, "hello", &hello_drv);  /* /dev/hello */


	hello_class = class_create(THIS_MODULE, "hello_class");
	err = PTR_ERR(hello_class);
	if (IS_ERR(hello_class)) {
		printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
		unregister_chrdev(major, "hello");
		return -1;
	}
	
	device_create(hello_class, NULL, MKDEV(major, 0), NULL, "hello"); /* /dev/hello */
	
	return 0;
}

6.编写出口函数

static void __exit hello_exit(void)
{
	printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
	device_destroy(hello_class, MKDEV(major, 0));
	class_destroy(hello_class);
	unregister_chrdev(major, "hello");
}

7.完善信息

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

总结

本篇文章的内容不多大家看完后有什么疑问可以留言。

标签:__,驱动程序,init,exit,Linux,printk,hello,函数
From: https://blog.51cto.com/u_16153875/8473961

相关文章

  • linux中cmake的用法
    cmake的基本用法一、message()函数message:为用户显示一条消息message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]"messagetodisplay"...)#(无)=重要消息;#STATUS=非重要消息;#WARNING=CMake警告,会继续执行;#AUTHOR_WARNING=CMake警......
  • Linux第七次周总结
    第六章I/O重定向与管道6.1I/O重定向打开一个终端0,输入date命令,会显示当前时间。如果在date命令后加“>”,并指向date.txt文件,那么就会写入date.txt文件。在执行passwd命令改密码时,系统会产生一个进程。date命令在默认情况下将输出结果显示在终端,此时文件描述符为1。现在改变......
  • linux命令学习
    Linux命令的学习导航目录Linux命令的学习导航使用VMware备份操作系统快照克隆Linux系统的文件文件与文件夹Linux系统的文件目录结构Linux的基本指令指令与选项基础指令ls指令pwd指令cd命令mkdir指令touch指令cp指令mv指令rm指令vim命令输出重定向cat指令进阶指令df指令free指令h......
  • Linux下荣耀MagicBook的触控板被错误识别为鼠标的临时解决方案
    TL;DR安装软件包hid-tools,然后运行命令:sudohid-featureset-f300003$(sudohid-featurelist-devices|grepBLTP7853|awk-F:'{print$1}')问题现象荣耀MagicBook笔记本安装了汇顶的触控板,此触控板在Linux下被识别为鼠标,导致无法使用触控板手势等功能。该触控板......
  • 第十一周Linux教材第十二章学习笔记——块设备I/O和缓冲区管理
    块设备I/O和缓冲区管理本章讨论了块设备1/O和缓冲区管理;解释了块设备1/O的原理和T/O缓冲的优点;论述了Unix的缓冲区管理算法,并指出了其不足之处;还利用信号量设计了新的缓冲区管理算法,以提高1/O缓冲区的缓存效率和性能;表明了简单的PV算法易于实现,缓存效果好,不存在死锁和饥饿问题;还......
  • 在Linux环境安装redis步骤,且设置开机自动启动redis
    原创/朱季谦最近一直在学习redis相关知识,看了很多理论知识后,觉得还是要多动手操作,就如王阳明说的知行合一那样,因此,便决定在linux环境安装了redis,过程捣鼓了一番,也遇到了一些波折,但最后还是成功安装完成,顺便把步骤流程记录了下来,分享给有需要的小伙伴。1.首先,我在linux的/usr/local/......
  • linux环境安装可操作图库语言Gremlin的图框架HugeGraph
    原创/朱季谦 若你还没接触过图数据库,可能看到这个概念时,会比较蒙蔽。图是什么?图数据库又是什么?首先,在数据结构中,图是一种由顶点(vertex)集合及顶点间关系集合组成的一种非线性数据结构。而图数据库,则是以图这种具有点边结构来增、删、改、查之类操作的NoSQL数据库,它特别擅长处理大数......
  • Linux信号基本概念
    信号分为两大类:标准信号,用于内核向进程通知事件,信号范围为1~31实时信号信号产生后,会在稍后被传递给某进程,进程也会采取某措施来响应信号。在产生和到达期间,信号处于pending(等待)状态。有时需要确保一段代码不被传递来的信号所中断,这时可以把信号添加到进程的信号掩码中,阻塞......
  • linux - grep 查找匹配
    在文件中查找匹配的字符串或者模式1.在单个文件中查找给定的字符串grep"string"filename2.在多个文件中查找指定的字符串grep"this"demo_*3.-i选项忽略大小写敏感进行查找grep-i"string"filename4.使用正则表达式进行匹配查找grep"lines.*empty"demo_file5......
  • Linux与Sre入门建议
    https://www.w3schools.com/go/index.php......