Linux驱动开发(1.基础创建)
序言:从高层逻辑到底层硬件的回归
在当今的软件开发中,我们习惯于用高级语言构建抽象层——通过框架、库和云服务快速实现功能。这种“软逻辑”的便利性让开发效率倍增,却也逐渐模糊了我们对计算机本质的认知:一切代码终将落地为硬件行为。
Bjarne Stroustrup(C++之父)曾言:“The Web is a flea on the tail of the dog called IT.”(万维网不过是信息技术狗尾巴上的一只跳蚤)。这句话深刻揭示了技术表象与底层根基的关系。
回想DOS时代,从盘符加载到命令执行,每一步都直击硬件本质;而如今的一键开机背后,是无数硬件信号、固件协议和驱动程序的精密协作。理解底层,不是为了复古,而是为了在高层抽象失效时,仍能掌控全局。
设备驱动程序——连接软硬件的桥梁
1.1 什么是设备驱动?
设备驱动是操作系统的“硬件翻译官”,它完成两件事:
-
机制(Mechanism):将硬件操作(如寄存器读写、中断处理)封装为统一接口。
-
策略(Policy):由上层决定如何使用这些接口(如权限管理、数据调度)。
示例:
-
键盘驱动(机制)提供按键扫描码,窗口管理器(策略)决定如何响应快捷键(如Ctrl+C)。
-
GPU驱动(机制)实现图形渲染,桌面环境(策略)管理窗口布局。
1.2 为什么需要学习驱动开发?
-
突破技术黑箱:理解从代码到硬件的完整链路(如
printf
如何点亮屏幕像素)。 -
解决实际问题:定制硬件支持(如为嵌入式设备编写专用驱动)。
-
职业竞争力:内核开发、IoT、自动驾驶等领域对底层能力要求极高。
1.3 设备驱动的分类
类型 | 特点 | 典型设备 | 用户接口示例 |
---|---|---|---|
字符设备 | 按字节流访问,支持read() /write() | 键盘、串口 | /dev/ttyS0 |
块设备 | 按数据块访问,用于存储设备 | 硬盘、SSD | /dev/sda |
网络接口 | 处理数据包,无文件节点 | 网卡、虚拟隧道 | eth0 、wlan0 |
1.4 从零编写一个驱动模块
代码示例:最简单的内核模块
#include <linux/module.h>
#include <linux/init.h>// 模块加载时执行
static int __init my_driver_init(void) {printk(KERN_INFO "Driver loaded: Hello, Kernel!\n"); // 内核日志输出return 0;
}// 模块卸载时执行
static void __exit my_driver_exit(void) {printk(KERN_INFO "Driver unloaded: Goodbye, Kernel!\n");
}// 注册模块入口/出口
module_init(my_driver_init);
module_exit(my_driver_exit);// 模块元信息
MODULE_LICENSE("GPL"); // 开源协议
MODULE_AUTHOR("Your Name"); // 作者
MODULE_DESCRIPTION("A Minimal Driver"); // 描述
操作步骤:
-
使用vim创建一个my_driver.c文件
-
编写
Makefile
:obj-m += my_driver.o all:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean:make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
-
编译并加载模块:
make # 编译 sudo insmod my_driver.ko # 加载模块 dmesg | tail -n 2 # 查看内核日志输出 sudo rmmod my_driver # 卸载模块
当加载模块后通过dmesg可以看见我们驱动运行时打印的信息 。
现在自己也在学习Linux驱动开发中也欢迎各位同学和大佬跟我交流~
相关文章:
Linux驱动开发(1.基础创建)
序言:从高层逻辑到底层硬件的回归 在当今的软件开发中,我们习惯于用高级语言构建抽象层——通过框架、库和云服务快速实现功能。这种“软逻辑”的便利性让开发效率倍增,却也逐渐模糊了我们对计算机本质的认知:一切代码终将落地为…...
mmseg
系列文章目录 文章目录 系列文章目录bug bug File "/public/home/rsinfo/project/mmsegmentation/mmseg/__init__.py", line 61, in <module>assert (mmcv_min_version < mmcv_version < mmcv_max_version), \ AssertionError: MMCV2.2.0 is used but i…...

LangChain核心概念
下面整理的LangChain部分核心概念: 聊天模型【Chat models】:通过聊天 API 暴露的大语言模型(LLMs),将消息序列作为输入,并输出一条消息。消息【Messages】:聊天模型中的通信单元,…...
阿里巴巴全新推理模型QwQ-32B:性能比肩DeepSeek-R1,开源引领未来
摘要 阿里巴巴集团于深夜正式发布全新推理模型QwQ-32B,其性能与DeepSeek-R1完整版相当。该模型已通过Apache 2.0开源协议在Hugging Face和ModelScope平台发布。用户可通过Qwen Chat平台直接体验QwQ-32B的强大功能。这一举措不仅展示了阿里巴巴在人工智能领域的技术实…...

使用Arduino和ESP8266进行基于物联网的垃圾箱监控
使用 Arduino 和 ESP8266 的基于 IOT 的垃圾箱监控系统 在这个 DIY 中,我们将制作一个基于 IOT 的垃圾箱/垃圾监控系统,该系统将通过网络服务器告诉我们垃圾桶是空的还是满的,并且您可以通过互联网从世界任何地方了解“垃圾桶”或“垃圾箱”的状态。它将非常有用,可以安装…...

【Python爬虫】爬取公共交通路网数据
程序来自于Github,以下这篇博客作为完整的学习记录,也callback上一篇爬取公共交通站点的博文。 Bardbo/get_bus_lines_and_stations_data_from_gaode: 这个项目是基于高德开放平台和公交网获取公交线路及站点数据,并生成shp文件,…...

基于Matlab的人脸识别的二维PCA
一、基本原理 传统 PCA 在处理图像数据时,需将二维图像矩阵拉伸为一维向量,这使得数据维度剧增,引发高计算成本与存储压力。与之不同,2DPCA 直接基于二维图像矩阵展开运算。 它着眼于图像矩阵的列向量,构建协方差矩阵…...

SSM架构 +Nginx+FFmpeg实现rtsp流转hls流,在前端html上实现视频播放
序言: 本文介绍通过SSM架构 NginxFFmpeg实现rtsp流转hls流,在前端html上实现视频播放功能。此方法可用于网络摄像头RTSP视频流WEB端实时播放。(海康和大华都可以),我使用的是海康 步骤一:安装软件 FFmpeg…...

【实战ES】实战 Elasticsearch:快速上手与深度实践-3.2.3 案例:新闻搜索引擎的相关性优化
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 Elasticsearch新闻搜索引擎相关性优化实战3.2.3 案例:新闻搜索引擎的相关性优化项目背景1. 相关性问题诊断与分析1.1 初始查询DSL示例1.2 问题诊断矩阵1.3 性能基…...

SQL经典查询
查询不在表里的数据,一张学生表,一张学生的选课表,要求查出没有选课的学生? select students.student_name from students left join course_selection on students.student_idcourse_selection.student_id where course_selecti…...

体验开源openeuler openharmony stratovirt模拟器
文档 openeuler社区面向数字基础设施的开源操作系统 openharmony社区 OpenHarmony是由开放原子开源基金会(OpenAtom Foundation)孵化及运营的开源项目, 目标是面向全场景、全连接、全智能时代、基于开源的方式,搭建一个智能终端设备操作系统…...

【C++】:STL详解 —— 红黑树
目录 平衡二叉查找树 红黑树的概念 红黑树的五大性质 红黑树的效率 红黑树和AVL树的比较 插入与删除操作 内存与实现复杂度 经典性能数据对比 总结 对旋转的基本理解 旋转的作用 左旋(Left Rotation) 右旋(Right Rotation…...
蓝桥试题:蓝桥勇士(LIS)
一、题目描述 小明是蓝桥王国的勇士,他晋升为蓝桥骑士,于是他决定不断突破自我。 这天蓝桥首席骑士长给他安排了 N 个对手,他们的战力值分别为 a1,a2,...,an,且按顺序阻挡在小明的前方。对于这些对手小明可以选择挑战…...

Trae IDE新建C#工程
目录 1 结论 2 项目结构 3 项目代码 1 结论 新建C#工程来说,Trae的Chat比DeepSeek的Coder好用。 2 项目结构 MyWinFormsApp/ │ ├── Program.cs ├── Form1.cs ├── Form1.Designer.cs ├── MyResources/ │ └── MyResources.resx └── MyWin…...

Linux基础--进程管理
目录 静态查看进程 使用命令: ps 动态查看进程 使用命令: top 关闭进程: 使用命令: kill 查看进程占用端口 使用命令: ss 编辑 查看某端口是否被进程占用 使用命令: lsof 作业管理 进程后台运行: 使用命令: jobs 将后台进程调回前台 使用指令: fg 将前台进…...
Java面向对象(详细解释)
第一章 Static关键字 1.static的介绍以及基本使用 1.概述:static是一个静态关键字 2.使用: a.修饰一个成员变量: static 数据类型 变量名 b.修饰一个方法: 修饰符 static 返回值类型 方法名(形参){…...
qt ui相关的第三方库插件库
Qt UI相关的第三方库和插件库有很多,能帮助开发者提高开发效率,扩展UI功能,增强可用性和美观度。以下是一些常见的第三方库和插件: 1. QCustomPlot 功能:用于在Qt应用程序中创建交互式的二维绘图。特点:支…...
详解动态规划算法
动态规划 一、动态规划的核心思想二、动态规划的步骤1. 定义状态(State)2. 确定状态转移方程(State Transition Equation)3. 确定边界条件(Base Case)4. 填表(Table Filling)或递归计…...

LINUX网络基础 [五] - HTTP协议
目录 HTTP协议 预备知识 认识 URL 认识 urlencode 和 urldecode HTTP协议格式 HTTP请求协议格式 HTTP响应协议格式 HTTP的方法 HTTP的状态码 编辑HTTP常见Header HTTP实现代码 HttpServer.hpp HttpServer.cpp Socket.hpp log.hpp Makefile Web根目录 H…...

慕慕手记项目日志 项目从开发到部署多环境配置 2025-3-8
慕慕手记项目日志 项目从开发到部署多环境配置 2025-3-8 现在是已经到了课程的第十章了,开始进行配置项目环境了。现在要完成的任务是项目可以正常运行,而且可以自由切换配置,开发/测试。 下面是当前的目录结构图: 现在来解释一…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...