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

news2024/11/28 6:31:45

一、概述

    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.o

KDIR := /lib/modules/$(shell uname -r)/build

all:
	make -C $(KDIR) M=$(PWD) modules

clean:
	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.coloradmin.cn/o/1256918.html

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

相关文章

【C/C++】如何不使用 sizeof 求数据类型占用的字节数

实现代码&#xff1a; #include <stdio.h>#define GET_TYPE_SIZE(TYPE) ((char *)(&TYPE 1) - (char *) & TYPE)int main(void) {char a a;short b 0;int c 0;long d 0;long long e 0;float f 0.0;double g 0.0;long double h 0.0;char* i NULL;print…

STK Components 二次开发-创建地面站

1.地面站只需要知道地面站的经纬高。 // Define the location of the facility using cartographic coordinates.var location new Cartographic(Trig.DegreesToRadians(-75.596766667), Trig.DegreesToRadians(40.0388333333), 0.0); 2.创建地面站 创建方式和卫星一样生成对…

MUI框架从新手入门【webapp开发教程】

文章目录 MUI -最接近原生APP体验的高性能前端框架APP开发3.25 开发记录miu框架介绍头部/搜索框&#xff1a;身体>轮播图轮播图设置数据自动跳转&#xff1a;九宫格图片九宫格图文列表底部选项卡按钮选择器手机模拟器 心得与总结&#xff1a;MUI框架在移动应用开发中的应用M…

Linux shell编程学习笔记30:打造彩色的选项菜单

1 需求分析 在 Linux shell编程学习笔记21&#xff1a;用select in循环语句打造菜单https://blog.csdn.net/Purpleendurer/article/details/134212033?spm1001.2014.3001.5501 中&#xff0c;我们利用select in循环语句打造的菜单中&#xff0c;菜单项都是用系统设置的颜色配…

大屏可视化编辑器

前言&#xff1a; 乐吾乐Le5le大屏可视化设计器&#xff0c;零代码实现物联网、工业智能制造等领域的可视化大屏、触摸屏端UI以及工控可视化的解决方案。同时也是一个Web组态工具&#xff0c;支持2D、3D等多种形式&#xff0c;用于构建具有实时数据展示、监控预警、丰富交互的组…

一、Spring_IOCDI(1)

&#x1f33b;&#x1f33b; 目录 一、前提介绍1.1 为什么要学?1.2 学什么?1.3 怎么学? 二、Spring相关概念2.1 初始Spring2.1.1 Spring家族2.1.2 了解 Spring 发展史 2.2 Spring系统架构2.2.1 系统架构图2.2.2 课程学习路线 2.3 Spring核心概念2.3.1 目前项目中的问题2.3.2…

【古诗生成AI实战】之一——实战项目总览

[1] 总览 【古诗生成AI实战】系列共五篇文章&#xff1a; 【古诗生成AI实战】之一——实战项目总览   【古诗生成AI实战】之二——项目架构设计   【古诗生成AI实战】之三——任务加载器与预处理器   【古诗生成AI实战】之四——模型包装器与模型的训练   【古诗生成AI…

nodejs+vue+python+PHP+微信小程序-婚纱摄影预约系统的设计与实现-安卓-计算机毕业设计

本婚纱摄影预约系统主要包括个人中心、套系风格管理、用户管理、摄影师管理、婚纱套系管理、婚纱套系订单管理、客片欣赏管理、客户样片管理、摄影咨询管理、客户选片管理、系统管理等多个模块。它帮助婚纱摄影预约实现了信息化、网络化&#xff0c;通过测试&#xff0c;实现了…

阿里云,找回初心!

大数据产业创新服务媒体 ——聚焦数据 改变商业 近期&#xff0c;阿里巴巴发布了2023年Q3财报。其中&#xff0c;阿里云收入同比增长2%至276.48亿元&#xff0c;经调整EBITA利润从上个季度的3.87亿元&#xff0c;提升至14.09亿元&#xff0c;环比增幅达264%。 应该说&#xff…

自建CA实战之 《0x02 Nginx 配置 https双向认证》

自建CA实战之 《0x02 Nginx 配置 https双向认证》 上一章节我们已经实现了Nginx上配置https单向认证&#xff0c;主要场景为客户端验证服务端的身份&#xff0c;但是服务端不验证客户端的身份。 本章节我们将实现Nginx上配置https双向认证&#xff0c;主要场景为客户端验证服…

MySQL简单介绍

简单了解MySQL MySQL语句分类 SQL语句分类 DDL&#xff1a;数据定义语句 create表&#xff0c;库.….] DML&#xff1a;数据操作语句 [增加insert&#xff0c;修改 update&#xff0c;删除delete] DQL&#xff1a;数据查询语句 [select] DCL&#xff1a;数据控制语句 …

Linuxfork,写时拷贝

1.prinf隐藏的缓冲区 1.思考:为什么会有缓冲区的存在? 2.演示及思考? 1).演示缓存区没有存在感 那为什么我们感觉不到缓冲区的存在呢?我们要打印东西直接就打印了呢? 我们用代码演示一下: 比如打开一个main.c,输入内容如下: #include <stdio.h> int main() { …

【论文解读】Real-ESRGAN:使用纯合成数据训练真实世界的超分辨率图像

图一是4种超分方法的对比效果 。 0 摘要 尽管在盲超分辨率方面已经进行了许多尝试&#xff0c;以恢复具有未知和复杂退化的低分辨率图像&#xff0c;但它们仍然远远不能解决一般的真实世界退化图像。在这项工作中&#xff0c;我们将强大的 ESRGAN 扩展到一个实际的恢复应用程序…

计算机图形学-变换基础

坐标系转换历程模型坐标系 -> 世界坐标系 -> 摄像机坐标系 -> 视口&#xff08;屏幕&#xff09;坐标系 变换 仿射变换和线性变换线性&#xff1a;旋转 缩放 镜像 切变放射&#xff1a; 平移 平移 2D变换矩阵 3D变换矩阵 旋转 2D旋转矩阵 //2D 旋转private (float,…

案例026:基于微信的原创音乐小程序的设计与实现

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;SSM JDK版本&#xff1a;JDK1.8 数据库&#xff1a;mysql 5.7 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.5.4 小程序框架&#xff1a;uniapp 小程序开发软件&#xff1a;HBuilder X 小程序…

7000字详解 动态代理(JDK动态代理 CGLIB动态代理)与静态代理

代理模式 1. 代理模式 概念2. 静态代理3. 动态代理3.1.JDK动态代理3.2.CGLIB动态代理3.3. JDK动态代理和CGLIB动态代理区别 4.静态代理和动态代理区别5.篇末 1. 代理模式 概念 代理模式是一种设计模式。 使用代理对象来替代真实对象&#xff0c;用代理对象去访问目标对象。这样…

ROS2智能小车基本原理图

我觉得这样意思已经表的很清楚了 这个图很重要&#xff0c;有了这个图&#xff0c;就可以积累每个部分的代码了&#xff0c;如果没有这个图&#xff0c;那么每次都只能是测试&#xff0c;以前的代码都会需要重新写一次。不过第一次训练也许更重要&#xff0c;这也是不可避免的…

使用STM32与MFRC522 IC进行RFID卡的读取与识别(含代码)

利用STM32与MFRC522 IC进行RFID卡的读取和识别&#xff0c;可以实现对RFID卡的读取和获取卡片标识信息。MFRC522 IC是一种高集成度的13.56MHz RFID芯片&#xff0c;常用于门禁系统、物流跟踪和智能支付等领域。下面将介绍如何使用STM32与MFRC522 IC进行RFID卡的读取和识别&…

Mycat实现读写分离

Mycat实现读写分离 Mycat支持MySQL主从复制状态绑定的读写分离机制。这里实现的也是基于MySQL主从复制的读写分离。 MySQL主从复制配置 首先要配置MySQL的主从复制&#xff0c;这里配置的是一主一次从。可以参考下面的文章。 https://blog.csdn.net/wsb_2526/article/detail…

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

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