【学习记录】从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;…

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…

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 使…

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

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

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…

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

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

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

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

WordPress无需插件禁用WP生成1536×1536和2048×2048尺寸图片

我们在使用WordPress上传图片媒体文件的时候&#xff0c;是不是看到媒体库中有15361536和20482048的图片文件&#xff0c;当然这么大的文件会占用我们的服务器空间&#xff0c;如何禁止掉呢&#xff1f; function remove_default_image_sizes( $sizes) {unset( $sizes[1536x15…

spring-webmvc练习-日程管理-访问后端展示列表数据

1、util/request.js import axios from "axios";let request axios.create({baseURL: "http://localhost:8080",timeout: 50000 });export default request 2、api/schedule.js import request from "../util/request.js";export let getSchedu…

[架构之路-253]:目标系统 - 设计方法 - 软件工程 - 软件设计 - 结构化设计的主要评估指标:高内聚(模块内部)、低耦合(模块之间)的含义

目录 前言&#xff1a; 一、软件工程中的软件设计种类&#xff1a;根据宏观到微观分 &#xff08;1&#xff09;软件架构设计&#xff08;层次划分、模块划分、职责分工&#xff09;&#xff1a; &#xff08;2&#xff09;软件高层设计、概要设计&#xff08;功能模块的接…

【c++随笔14】虚函数表

【c随笔14】虚函数表 一、虚函数表&#xff08;Virtual Function Table&#xff09;1、定义2、查看虚函数表2.1、 问题&#xff1a;三种类型&#xff0c;包含一个int类型的class、一个int类型的变量、int类型的指针&#xff1a;这三个大小分别是多少呢&#xff1f;2.2、怎么发现…

IT问题解答类型网站源码

问答网是一款为IT工程师提供的问答平台&#xff0c;旨在帮助用户在线获取专业知识和相关问题的答案。在问答网&#xff0c;用户可以轻松找到其他人的问答问题&#xff0c;并在这里寻求解答。如果您有任何想要解决的问题&#xff0c;都可以在此发布问题并得到其他同行的解答。 …

CSS之弹性盒子Flexible Box

我想大家在做布局的时候&#xff0c;没接触flex布局之前&#xff0c;大家都是用浮动来布局的&#xff0c;但现在我们接触了flex布局之后&#xff0c;我只能说&#xff1a;“真香”。让我为大家介绍一下弹性盒子模型吧&#xff01; Flexible Box 弹性盒子 在我们使用弹性盒子时&…

【算法】链表-20231127

这里写目录标题 一、面试题 02.02. 返回倒数第 k 个节点二、82. 删除排序链表中的重复元素 II三、141. 环形链表 一、面试题 02.02. 返回倒数第 k 个节点 提示 简单 130 相关企业 实现一种算法&#xff0c;找出单向链表中倒数第 k 个节点。返回该节点的值。 注意&#xff1a;本…

Linux(8):BASH

硬件、核心与 Shell 操作系统其实是一组软件&#xff0c;由于这组软件在控制整个硬件与管理系统的活动监测&#xff0c;如果这组软件能被用户随意的操作&#xff0c;若使用者应用不当&#xff0c;将会使得整个系统崩溃。因为操作系统管理的就是整个硬件功能。 应用程序在最外层…