讲师中心 微信公众号
AI工具推荐 视频效率加速

Linux如何编写块设备驱动_LinuxBlockDriver开发教程

雨瑶小哥_1403

雨瑶小哥_1403

发布时间:2025-11-25 20:58:03

|

847人浏览过

|

来源于php中文网

原创

首先实现块设备驱动需理解gendisk与request_queue的作用,1. gendisk描述设备信息并注册到系统;2. request_queue管理I/O请求并通过make_request处理bio;3. 每个bio包含多个段,驱动需遍历并完成数据拷贝;4. 模块卸载时按顺序释放资源;5. 编译后通过insmod加载并用mkfs、mount测试。

linux如何编写块设备驱动_linuxblockdriver开发教程

编写Linux块设备驱动需要理解内核中块I/O子系统的基本架构和数据流。块设备与字符设备不同,它以固定大小的数据块为单位进行读写,并支持随机访问。典型的块设备包括硬盘、SSD、U盘等。本文将带你一步步实现一个简单的内存模拟块设备驱动(RAM Disk),帮助你掌握Linux块设备驱动开发的核心要点。

1. 理解块设备驱动的基本结构

Linux块设备驱动主要依赖于struct gendisk和struct request_queue两个核心结构体:

  • gendisk:描述一个逻辑块设备,包含设备名、主次设备号、分区信息等。
  • request_queue:管理来自文件系统的I/O请求,驱动需为其注册请求处理函数。

块设备不直接处理read/write系统调用,而是通过请求队列接收bio(block I/O)结构,由驱动完成数据搬运。

2. 创建请求队列与gendisk实例

在模块初始化函数中,需分配并初始化请求队列和gendisk:

static struct request_queue *queue;
static struct gendisk *disk;
<p>static int __init my_blk_init(void)
{
// 分配请求队列
queue = blk_alloc_queue(GFP_KERNEL);
if (!queue)
return -ENOMEM;</p><pre class='brush:php;toolbar:false;'>// 设置请求处理函数
blk_queue_make_request(queue, my_make_request);

// 分配gendisk结构(1个分区)
disk = alloc_disk(1);
if (!disk) {
    blk_cleanup_queue(queue);
    return -ENOMEM;
}

disk->major = MY_BLK_MAJOR;         // 主设备号
disk->first_minor = 0;
disk->fops = &my_blk_fops;          // 文件操作(通常为空或仅占位)
disk->queue = queue;
strcpy(disk->disk_name, "myblk");

// 设置容量(以512字节扇区为单位)
set_capacity(disk, MY_BLK_SIZE / 512);

// 注册设备
add_disk(disk);

return 0;

}

Spotify-Linux
Spotify-Linux

通过 MPRIS DBus 控制 Spotify Linux 桌面客户端,实现播放、搜索、启动、音量和曲目信息,无需浏览器自动化。

下载

3. 实现make_request函数处理I/O

传统方式使用make_request函数逐个处理bio。每个bio代表一次I/O操作,可能包含多个段(segment):

static int my_make_request(struct request_queue *q, struct bio *bio)
{
    struct bio_vec bvec;
    sector_t sector = bio->bi_iter.bi_sector;
    void *mem = myblk_data + (sector * 512); // 内存偏移
    bool is_write = op_is_write(bio_op(&bio));
<pre class='brush:php;toolbar:false;'>if (sector * 512 + bio->bi_iter.bi_size > MY_BLK_SIZE) {
    bio_endio(bio, -EIO);
    return 0;
}

bio_for_each_segment(bvec, bio, iter) {
    char *bdata = kmap_atomic(bvec.bv_page) + bvec.bv_offset;
    if (is_write)
        memcpy(mem, bdata, bvec.bv_len);
    else
        memcpy(bdata, mem, bvec.bv_len);
    kunmap_atomic(bdata - bvec.bv_offset);
    mem += bvec.bv_len;
}

bio_endio(bio, 0);
return 0;

}

注意:现代内核推荐使用blk_mq_make_request配合多队列机制,但简单驱动仍可用传统方式。

4. 清理资源与模块卸载

模块卸载时必须释放申请的资源,顺序不能错:

static void __exit my_blk_exit(void)
{
    del_gendisk(disk);
    put_disk(disk);
    blk_cleanup_queue(queue);
}

确保在del_gendisk后不再有新的I/O进入,避免空指针访问。

5. 编译与测试

编写Makefile:

obj-m += myblk.o
<p>KDIR := /lib/modules/$(shell uname -r)/build</p><p>all:
$(MAKE) -C $(KDIR) M=$(PWD) modules</p><p>clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean</p>

编译后加载模块:

sudo insmod myblk.ko
dmesg | tail        # 查看设备号
lsblk               # 应看到 myblk 设备
sudo mkfs.ext4 /dev/myblk
sudo mount /dev/myblk /mnt
echo "hello" > /mnt/test.txt

基本上就这些。从零写块设备驱动的关键是理解bio的处理流程和内存映射方式。虽然真实硬件驱动还需处理DMA、中断等,但内存模拟设备是学习的良好起点。调试时多用dmesg观察内核输出,逐步验证读写正确性。

相关文章

驱动精灵
驱动精灵

驱动精灵基于驱动之家十余年的专业数据积累,驱动支持度高,已经为数亿用户解决了各种电脑驱动问题、系统故障,是目前有效的驱动软件,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

5034

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

5191

2025.07.04

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

379

2026.04.23

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

179

2025.11.16

磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

4310

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

3633

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

2893

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

7110

2023.07.05

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn