【学习记录】从0开始的Linux学习之旅——驱动模块编译与加载

一、概述

    Linux操作系统通常是基于Linux内核,并结合GNU项目中的工具和应用程序而成。Linux操作系统支持多用户、多任务和多线程,具有强大的网络功能和良好的兼容性。本文主要讲述如何编译及加载linux驱动模块。

二、概念及原理

    应用程序通过系统调用与内核进行交互,而驱动程序则提供了硬件设备的访问接口,内核本身则提供了系统调用、驱动框架等基础设施。
    驱动开发:Linux 驱动开发是指为 Linux 内核开发各种设备驱动程序,用于控制和管理硬件设备。驱动程序运行在内核空间,直接与硬件进行交互。Linux 内核提供了丰富的接口和框架,开发者可以编写各种类型的设备驱动,包括网络设备、存储设备、输入设备等。驱动程序通过内核提供的接口与用户空间的应用程序进行通信。
    应用开发:Linux 应用开发是指在 Linux 系统上开发各种类型的应用程序,包括命令行工具、图形界面应用、服务器端应用等。Linux 提供了丰富的开发环境和工具链,开发者可以使用各种编程语言和开发工具进行应用开发。应用程序运行在用户空间,通过系统调用与操作系统内核进行交互,执行各种任务和功能。
    内核开发:Linux 内核开发是指对 Linux 内核本身进行开发和维护。Linux 内核是操作系统的核心,负责管理系统资源、调度任务、提供系统调用等功能。内核开发包括对内核功能的添加和修改,修复内核漏洞,优化性能等工作。内核开发人员通常会编写和维护内核的各种子系统和模块,包括调度器、文件系统、网络协议栈等。
    模块加载与卸载:在 Linux 中,模块是指可以动态加载到内核中并扩展其功能的代码段。模块的加载意味着将模块的代码和数据加载到内核空间并使其在内核中运行,从而扩展内核的功能。模块的卸载则是将其从内核中移除,释放其占用的资源。模块的加载与卸载允许内核在运行时动态地添加或移除功能,这为系统提供了灵活性和可扩展性。

三、编译前准备

    在 Ubuntu 系统中进行 Linux 内核驱动模块的编译,需要做一些准备工作:

  1. 安装必要的软件包
    确保你的系统已经安装了必要的软件包,包括编译工具链、内核源码和头文件等。你可以使用以下命令来安装这些软件包:

    sudo apt update
    sudo apt install build-essential linux-headers-$(uname -r)
    
  2. 确认内核源码路径
    确保你知道系统中内核源码的路径,通常位于 /lib/modules/$(uname -r)/build。这个路径在编译驱动模块时可能会用到。

四、代码实现及编译

  • 驱动模块代码

    新建一个名为helloworld.c的文件,添加如下代码。

#include <linux/init.h>
#include <linux/module.h>/* 定义模块的初始化函数 */
static int Helloworld_Init(void)
{printk("I'm Chewie, Helloworld init ok!\n");return 0;
}/* 定义模块的退出函数 */
static void Helloworld_Exit(void)
{printk("Bye bye!\n");
}/* 注册模块的初始化和退出函数,这个是给内核识别的 */
module_init(Helloworld_Init);
module_exit(Helloworld_Exit);/* 声明该模块符合GPL协议 */
MODULE_LICENSE("GPL");
  • Makefile编写

    新建一个名为Makefile的文件(不需要后缀,必须是Makefile首字母大写,makefile识别不了,一开始不知道踩了个坑),这个 Makefile 文件主要是用于告诉 make 命令如何编译驱动程序模块,并提供了编译和清理的规则。在文件中添加如下内容。

obj-m := helloworld.oKDIR := /lib/modules/$(shell uname -r)/buildall:make -C $(KDIR) M=$(PWD) modulesclean:make -C $(KDIR) M=$(PWD) clean

    其中各部分的具体含义如下:

  1. obj-m := helloworld.o:

    • obj-m 是一个特殊的变量,用于指定要编译成模块的目标文件。
    • helloworld.o 是模块的目标文件名,这里是你要编译生成的驱动模块文件名。
  2. KDIR := /lib/modules/$(shell uname -r)/build:

    • KDIR 是一个变量,用于指定内核源码的路径。
    • /lib/modules/$(shell uname -r)/build 是一个动态获取当前系统内核版本并拼接出内核源码路径的命令。
  3. all::

    • all 是一个 Makefile 中的默认目标,表示默认情况下执行的规则。
  4. make -C $(KDIR) M=$(PWD) modules:

    • make -C $(KDIR) 是在内核源码路径下执行 make 命令,M=$(PWD) 表示当前目录是模块源码的路径。
    • modules 是指定了要编译生成模块对象文件的规则。
  5. clean::

    • clean 是一个用于清理的目标,用于清理编译产生的文件。
  6. make -C $(KDIR) M=$(PWD) clean:

    • make -C $(KDIR) 是在内核源码路径下执行 make 命令,M=$(PWD) 表示当前目录是模块源码的路径。
    • clean 是指定了要执行清理操作的规则。

    然后在当前helloworld.c目录下,打开终端,输入以下命令进行编译。

make -C /lib/modules/$(uname -r)/build M=$(pwd) modules

五、模块加载及卸载

    编译完模块后,需要把模块加载到内核才可正常使用。这里可以使用insmod指令加载驱动模块。注意需要加上sudo使用root权限。

sudo insmod helloworld.ko

    那如何知道模块是否加载成功呢?这里需要使用lsmod | grep helloworld检查模块加载情况。如果有如下显示则说明加载成功。
在这里插入图片描述

    卸载模块时,则需要使用rmmod进行卸载。同样需要加上sudo使用root权限。

sudo rmmod helloworld

    到这里可能有人要问了,模块初始化和退出函数里不是加了printk打印了一些信息吗,为什么终端里没有显示任何内容?是因为printk打印的信息是在内核空间中,而终端是属于用户空间的,所以不会显示内核的信息。如果想要显示这个打印内容,可以使用dmesg打印内核日志(同样的要加上sudo使用root权限),这样就能看到上面模块加载和卸载的信息及打印的相关信息。
在这里插入图片描述
    如果想要实时查看内核日志,可以通过以下命令实时打印内核日志。这里建议单独开一个终端实时查看。

sudo tail -f /var/log/kern.log

在这里插入图片描述

六、相关链接

【学习记录】从0开始的Linux学习之旅——编译linux内核

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/172688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件介绍02- flameshot截图软件(linux系统可用)

1 软件介绍 在Windows和mac平台一直都使用着snipaste截图&#xff0c;非常好用&#xff0c;又能够钉图。遗憾是并没有开发linux版本&#xff0c;真不知道为什么。 好在终于找到一款截图软件&#xff0c;flameshot截图软件&#xff0c;可以平替snipaste。 下载网址&#xff1a;…

华为eNSP使用教程(Enterprise Network Simulation Platform,企业网络仿真平台)

文章目录 华为eNSP使用教程详解引言eNSP界面快速入门启动与初始设置主界面组成创建和管理项目 构建网络拓扑添加和连接设备配置设备参数示例&#xff1a;配置设备接口IP 保存配置 仿真网络功能启动与测试示例&#xff1a;测试网络连通性 使用调试工具 疑难技术点解析路由协议配…

C语言WFC绘制矩形

代码实现&#xff1a; void CCGDrawingView::Rectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, COLORREF color,CDC* pDC) {CPen redPen(PS_SOLID, 1, color);CBrush redBursh(color);CPen* pOldPen pDC->SelectObject(&redPen);CBrush* p…

Django(十一、auth认证模块)

文章目录 一、auth介绍auth认证相关模块及操作扩展auth_user表 一、auth介绍 Django自带一个admin路由&#xff0c;但是需要我们提供管理员账户和密码&#xff0c;如果想要使用admin后台管理&#xff0c;需要先创建表&#xff0c;然后创建管理员账户。 直接执行数据类迁移命令…

hivesql 将json格式字符串转为数组

hivesql 将json格式字符串转为数组 完整过程SQL在文末 json 格式字符串 本案例 json 字符串参考格式&#xff0c;请勿使用本数据 {"data": [{"province": 11,"id_card": "110182198903224674","name": "闾丘饱乾"…

【JAVA学习笔记】71 - JDBC入门

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter25/src/com/yinhai/dao_ 一、JDBC概述 1.基本介绍 1. JDBC为访问不同的数据库提供了统一的接口&#xff0c;为使用者屏蔽了细节问题。 2. Java程序员使用JDBC,可以连接任何提供了JDBC驱动…

YARN工作流程详解

图1 图2 图1 -作业提交阶段&#xff1a; 1、client 提交job,向 ResourceManager【RM】 申请job_id; 2、RM 返回 job_id 及资源提交路径 给 client 3、client 把job所需的资源提交 到 3中指定的路径中 4、client 上传完成资源后&#xff0c;向RM 发送执行作业请求&#xff0c;RM…

《杀死一只知更鸟》

今天在读一篇英文文献的时候&#xff0c;摘要里有这样一句话&#xff1a;The developed algorithm is successfully applied to mock and real word problems。看到mock这个单词&#xff0c;想起最近一周在看的一本书《杀死一只知更鸟》&#xff0c;书的英文名叫《To Kill A Mo…

手写操作js数组的常见方法

文章目录 1.push2.pop3.unshift4.shift5.slice6.splice7.forEach8.map9.filter10.some11.every12.concat13.join14.indexOf15.lastIndexOf16.reserve17.sort18.find19.reduce 1.push // push() 方法可向数组的末尾添加一个或多个元素&#xff0c;并返回新的长度。 // 末尾添加…

BGP选路实验

要求 1 使用PreVal策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2 使用AS_Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3 配置MED策略&#xff0c;确保R4通过R3到达192.168.12.0/24 4 使用Local Preference策略&#xff0c;确保R1通过R2到达192.168.1.0/24 5 使…

服务器tar压缩解压文件

文章目录 一、前言二、命令2.1、解压2.2、压缩 三、最后 一、前言 前端上传dist代码到服务器上后&#xff0c;是在linux上操作&#xff0c;所以和window有所不同。一般是打好dist&#xff0c;然后压缩成gz传输到服务器&#xff0c;此时在服务器上可能涉及到解压和压缩的操作&a…

力扣日记11.25-【二叉树篇】对称二叉树

力扣日记&#xff1a;【二叉树篇】对称二叉树 日期&#xff1a;2023.11.25 参考&#xff1a;代码随想录、力扣 101. 对称二叉树 题目描述 难度&#xff1a;简单 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,…

操作系统题目分类总结 | 进程管理 内存管理 文件系统 设备管理

系列文章如下 学习过程中一定要有系统观念&#xff08;知识框架&#xff0c;每一章开头都会有一个思维导图&#xff09;&#xff0c;知道目前自己在学习的是哪一板块的内容&#xff0c;和前面有什么样的联系 操作系统的很多知识点前后都是联系非常紧密的&#xff0c;去一点一…

PCL 计算一条直线与一条线段的距离

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里的线段我们仍然使用一种参数化的表示,即 Q [ 0 ] + s [ 0 ] ∗ ( Q [ 1 ] − Q [ 0

Blender 连续 5 天遭受大规模 DDoS 攻击

Blender 发布公告指出&#xff0c;在2023年11月18日至23日期间&#xff0c;blender.org 网站遭受了持续的分布式拒绝服务&#xff08;DDoS&#xff09;攻击&#xff0c;攻击者通过不断发送请求导致服务器超载&#xff0c;使网站运营严重中断。此次攻击涉及数百个 IP 地址的僵尸…

ATK-ESP8266 WIFI模块串口通信通用实现方案

ATK-ESP8266 WIFI模块是一种常用的无线模块&#xff0c;它可以通过串口与外部设备进行通信&#xff0c;实现数据的收发和控制。本文将介绍一种通用的实现方案&#xff0c;帮助您在项目中使用ATK-ESP8266 WIFI模块进行串口通信。 【方案概述】 这个通用实现方案涵盖了ATK-ESP82…

springboot(ssm付费自习室管理系统 自习室预约平台Java(codeLW)

springboot(ssm付费自习室管理系统 自习室预约平台Java(code&LW) 开发语言&#xff1a;Java 框架&#xff1a;ssm/springboot vue JDK版本&#xff1a;JDK1.8&#xff08;或11&#xff09; 服务器&#xff1a;tomcat 数据库&#xff1a;mysql 5.7&#xff08;或8.0&am…

算法-技巧-中等-颜色分类

记录一下算法题的学习12 颜色分类 题目&#xff1a;给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝…

Android 相机库CameraView源码解析 (二) : 拍照

1. 前言 这段时间&#xff0c;在使用 natario1/CameraView 来实现带滤镜的预览、拍照、录像功能。 由于CameraView封装的比较到位&#xff0c;在项目前期&#xff0c;的确为我们节省了不少时间。 但随着项目持续深入&#xff0c;对于CameraView的使用进入深水区&#xff0c;逐…

了解JSX

在React中使用JSX <!DOCTYPE html> <html> <head> <meta charset"UTF-8" /> <title>JSX</title> </head> <body> JSX <!-- JSX 概念&#xff1a;JSX是JavaScript和XML的缩写&#xff0c;表示在js代码中编写…