naos-riscv源码分析:block.h如何把字节请求交给块设备驱动

Linux Swap 子系统:架构、内存管理与虚拟化 Swap Linux Swap机制通过将不活跃内存页移至磁盘或压缩内存,扩展系统有效内存容量,缓解内存压力。传统架构中,逻辑Swap槽与物理存储绑定,导致资源浪费,尤其在使用Zswap等压缩技术时。为此,Vswap与Xswap提出虚拟化方案:前者以XArray实现灵活映射,支持多后端迁移;后者采用稀疏映射,简化管理但容量固定。二者在架构设计、资源记账与动态扩展上各有权衡,反映了内核开发中对性能、可维护性与灵活性的深层考量。 阅读详情

原来读这份头文件时,我主要在辨认每个字段。这次再向前走一步:上层想读磁盘上的 20 个字节,驱动为什么收到的却是扇区号和扇区数量? 从这个问题看,结构体里的成员就不再是孤立名词。

1. 先对齐版本,避免拿新代码硬套旧截图

保留原来的数组式管理截图。本次补充明确以历史提交 5971db63b3c56cddfbcac98a5475d41d968799b2 的 kernel/src/block/block.h 与 block.c 为参照;这个版本的核心结构与原图一致,但不宣称它就是当时截图的精确提交。

对应 block.h,对应 block.c。较新的工作树已改用链表,接口也有扩展,本文不是最新版 API 手册。

原来的头文件截图

数组式块设备数量上限

MAX_BLKDEV_NUM 为 64,是这个实现的表容量,不是系统设计中永远只能有 64 个设备,也不代表注册函数自动完成了所有越界保护。

2. 两层接口,同名 size 可能不是同一个单位

原来的 blkdev_t 结构

核心字段摘录如下,可复制对照:

typedef struct blkdev {
    char *name;
    void *ptr;
    uint64_t block_size;
    uint64_t size;
    uint64_t max_op_size;
    uint64_t (*read)(void *data, uint64_t lba,
                     void *buffer, uint64_t size);
    uint64_t (*write)(void *data, uint64_t lba,
                      const void *buffer, uint64_t size);
} blkdev_t;

这是一份内核头文件摘录,依赖内核类型定义,不能当成独立的用户态程序直接编译。

位置在所选实现中的含义
block_size一个逻辑块的字节数;注册时为零会使用 512
max_op_size用来约束一次底层请求的字节规模
上层 offset、len字节偏移、字节长度
回调 lba起始逻辑块编号
回调参数 size本次请求的逻辑块数量,不能混成字节数
回调返回值该实现按完成的逻辑块数量比较
blkdev_read 成功返回值返回复制给上层的字节数

结构体自身的 size 保存注册者传入的容量值,IOCTL_GETSIZE 原样返回;完整容量单位还要检查各驱动的注册调用,不能仅凭变量名断言所有驱动都一致。

最容易忽略的就是回调的 size:block.c 会调用 dev->read(..., chunk_sectors),并用返回值和 chunk_sectors 比较。这个调用点比“size 看起来应该是大小”的猜测可靠。

3. ptr 与函数指针:将数据和行为一起交给公共层

设备表与计数

注册函数接口

注册时,公共层记住名字、几何参数、驱动私有数据 ptr 和 read/write 回调。之后公共层不必知道具体硬件细节:它把 ptr 原样交回回调,驱动再把它解释成自己的上下文。

调用路径可以写成:

上层:blkdev_read(drive, 字节偏移, 用户缓冲区, 字节长度)
    -> 根据 drive 找到 blkdev_t
    -> 字节请求换算为逻辑块请求
    -> dev->read(dev->ptr, 起始LBA, 临时缓冲区, 块数)
    -> 从临时缓冲区复制需要的字节
    -> 向上层返回字节数

drive 是这一层管理的设备索引,ptr 是驱动上下文;两者不是同一件事。这个注册表也不等同于另一篇 device.h 的通用设备表。

4. 真正走一次:偏移 500,读取 20 字节

假设逻辑块大小 512 字节,请求从字节偏移 500 开始读 20 字节,且单次请求限制足以读两个块。

所选实现的换算:

start_sector = 500 / 512 = 0
end_sector   = (500 + 20 - 1) / 512 = 1
sector_count = 1 - 0 + 1 = 2
offset_in_block = 500 % 512 = 500

注意减一:长度 20 的最后一个字节在偏移 519,不是 520。

块0: [0 ................ 499 | 500 .... 511]
                                   取12字节
块1: [512 ... 519 | 520 ................ 1023]
          取8字节

对驱动:从 LBA 0 读 2 块
对上层:交付 20 字节

驱动不是只读 20 个字节,而是提供覆盖请求范围的块。块层再裁出上层需要的那一段。相反,偏移 512、长度 512 恰好对齐,只覆盖 LBA 1 一个块。

5. ioctl 与写操作:不能只看名字猜功能

查询块大小和容量的命令

统一读写接口

IOCTL_GETBLKSIZE 与 IOCTL_GETSIZE 在这个版本里只是查询已有字段,不会自动触发格式化等操作。

写操作还有一个读取没有的要求:只覆盖块中某一段时,不能破坏同块其余字节。所以历史 blkdev_write 有先读旧块、修改指定范围、再写回的分支。这就是读改写。它也意味着部分块写入可能需要有效的 read 回调,而不只是 write 回调。

6. 我怎样核对这段解释

本次实际读取了固定提交的源码,用独立的字节区间模型核对了跨块、对齐和单字节案例。模型不运行内核,也不证明磁盘驱动正确。

历史实现还值得继续审查:零长度下 offset + len - 1 的计算、偏移加法溢出、设备索引范围、临时缓冲区是否覆盖实际整块 I/O,以及 max_op_size 太小时如何保证循环前进。看懂换算不代表这些边界已经处理完善;本文不把旧实现包装成经过完整验证的生产代码。

读这份头文件,最后我想记住的不是每个字段的中文翻译,而是三个层次:上层说字节,驱动说块,公共层负责换算和衔接。下一篇 device.h 则继续看不同类型设备怎样接入同一套入口。

Unity+Hybridclr发布WebGL记录 问题不多,比预想中的顺利,如果遇到问题建议先看Hybridclr的常见问题里面有没有解决方案,没遇到Hybridclr的报错,所以记录的问题里面没有Hybridclr相关的。导出设置里的压缩格式选择了Brotli,而服务器或浏览器不支持,据说是可以拓展服务器配置使支持Brotli,但是由于我本人是IIS小白,所以换了种压缩格式,在publishing Settings修改Compression Fromat为Gzip。3.在浏览器运行之后视图一直闪烁。,修改配置,这个网上很常见。 阅读详情

相关推荐

nRF52382低功耗蓝牙应用开发之入门教程-软件烧录

准备工作在上一篇文章讲过了,这里就讲讲nRFgo studio的使用 硬件准备: J-link:2线 供电:3.3V 如下图打开nRFgo studio界面介绍, 2、如果J-link正常,如下图 3、如果蓝牙芯片正常 4、烧录过程,如果蓝牙芯片之前有烧录过程序,需先点擦除,再点烧录 5、烧录代码路劲,例如 F:\nRF\SDK\nRF5_SDK_15.2.0_...

LinQiPing233的博客 1945

naos-riscv源码分析:device.h如何把设备注册、查找与读写串起来

从原来的设备结构截图出发,对照历史实现梳理注册、设备号、私有数据与函数指针分发,并解释它与 block.h 的区别。

doting__的博客 240

fastjson1.2.83反序列化漏洞

【代码】fastjson1.2.83反序列化漏洞。

Coder的博客 1万+

naos的device.c源码:设备注册、子类型查找与驱动回调转发

保留13张原截图,用对应历史源码核对type与subtype、设备号、私有指针和错误返回,并明确宿主桩测试与内核运行的边界。

doting__的博客 377

python 常见算法(1-50题)

常见的算法题

weixin_58470558的博客 1755

理解 Linux 动态库加载:LD_LIBRARY_PATH

flyfish

二分掌柜的 318

STM32 IIC温湿度传感器(STH45)实验

精度 ΔRH = ±1.0 %RH, ΔT = ±0.1 °C• 平均电流:0.4 μA,空闲电流:80 nA• I2C FM、CRC 校验和、乘法。I2C 地址。• 专利保护选项 [1]、PTFE 膜和可拆卸保护盖• 工作范围:0 …100 %相对湿度,−40…125 摄氏度• 在冷凝环境中功能齐全• 动力加热器,真正的NIST可追溯性• JEDEC JESD47 认证 • 符合 ISO 17025 : 2017 的传感器专用校准证书,3 点温度校准。

baidu_34971492的博客 3065

Linux 磁盘满了怎么排查?df / du / find 三步定位大文件

Linux 磁盘满排查三步法:df -h 定位分区、du 逐层下钻、find 按大小和时间抓大文件,附 inode 耗尽、文件已删未释放、du 与 df 不一致等经典坑的解决方案。

weixin_38291577的博客 213

AIGC实战——多模态模型DALL.E 2

DALL.E 2 是 OpenAI 提出的一个大规模文本生成图像模型,可以根据文本提示生成各种风格的逼真图像。它通过将预训练模型 CLIP 与 GLIDE 中的扩散模型架构相结合完成任务。它还具有其他应用,例如通过文本提示编辑图像和提供给定图像的变体。虽然它也有一些局限性,例如不一致的文本渲染和属性绑定,但 DALL.E 2 是仍然一个非常强大的AI模型,推动了生成模型的发展。

盼小辉丶的博客 1万+

古月学院《如何在Gazebo中实现阿克曼转向车的仿真》课程资料在ROS Noetic版本中运行时的常见错误及解决方法

   最近想在Gazebo中开发一些仿真内容,于是购买了古月学院的《如何在Gazebo中实现阿克曼转向车的仿真》课程,但是由于ROS 版本的更新,拿到手的课程资料不能直接在ROS Noetic版本中运行,经过我这几天的探索,对遇到的错误及解决方法进行了整理,方便后面购买课程的小伙伴更快的成功运行程序    在文章正式开始之前,先放一下我之前为了寻找该资料报错的原因,而写的两篇与该课程相关的文章链接,感兴趣的可以自行阅读    以阿克曼转向车为例对URDF和XACRO文件进行解读(点击可跳转)    将x

慕羽★的博客 5973

Linux-iostat命令详解

Linux命令学习记录

m0xin的博客 81

Vibe Draw:AI实现2D草图转3D建模,开源免费的设计师宝藏软件!

AI实现2D草图转3D建模,开源免费,设计师进来看一下?

Code_流苏:在代码中寻诗意,在实践中觅真知 2146

Linux 服务器性能排查手册(2026):CPU、内存、磁盘IO、网络四大瓶颈定位

iptables 四表五链模型、firewalld zone 信任级别、云安全组与主机防火墙的关系与优先级,避坑改了防火墙把自己挡在服务器外面的翻车事故。

2502_91473995的博客 282

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

【Linux】APT 本地 deb 安装与 `-f` 参数总结笔记

apt install ./xx.deb 可自动解析并安装依赖,无需 -f;-f 仅用于修复已损坏的依赖状态,非首次安装时必需。apt install -f 可单独运行,修复 broken dependencies。两者职责不同:前者是安装与依赖解决,后者是故障修复。完全离线时需提前准备依赖包或本地源。

hknaruto的专栏 205

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Linux rm 误删文件恢复实操教程

Linux使用rm删除文件时,并不会直接抹除磁盘上的数据,只是移除文件索引,让系统不再识别这块空间。只要没有写入新数据,原有扇区内容就会保留。新文件写入才有可能覆盖这些区域,一旦覆盖就很难找回。恢复的本质就是扫描磁盘,找到这些还存在、但索引丢失的数据条目,再把它们导出保存到其他分区。越早停止写入,恢复成功的概率越高。

海天数据恢复-winhex数据恢复教程 200

Windows/Linux下强实时运动控制内核(二):基于Qt的Delta机械手的开发应用

强实时运动控制内核MotionRT750下Qt开发Delta机械手的完整开发流程。

weixin_57350300的博客 238

Linux sudo

如果输出 → 无 sudo 权限 如果输出 → 拥有全部 sudo 权限 辅助验证命令 ⚠️ 注意:在 wheel 组 ≠ 一定能 sudo,必须 开启 Ubuntu/Debian: ✅ 重要:修改组之后,用户要重新登录才生效! 或者执行 临时生效 看到这行(没有 #注释)才生效: 方式 2:visudo 直接单独给用户授权(精细化权限) 找到 ,下面添加一行: 自带语法校验,写错会告警,不要直接 vim 改 ,写错直接 sudo 炸掉! 想免密 su

fengliyang_的博客 176

Linux 磁盘 100% 但 du 查不出东西,五种情况逐个排

监控告警说根分区 100%,登录上去 du -sh /* 加起来只有 12GB,df 显示 40GB 已用。差了快 30GB,du 找不到任何东西。这种情况基本都是"文件被删了但进程还开着",但也可能是别的原因。这篇按可能性排一下顺序。

2408_89646393的博客 160

【Linux 网络编程】DNS 与 ICMP:从域名解析到 ping、traceroute,把“网络通不通”问清楚

DNS 让名字与网络资源建立联系,ICMP 让部分网络状态有机会被看见。真正排查问题时,我们需要的不是一条万能命令,而是把每次观测放回它对应的层次。看到一个 DNS 结果,先问“谁回答的、什么类型、缓存多久”;看到一次 ping 回复,先问“哪个地址、哪个方向、证明了哪一次往返”;看到一份 traceroute,先问“用了什么探测、哪些节点回应、星号还有哪些解释”。当这些问题能被分别回答,“网络通不通”就不再是一个模糊判断,而会变成一条可以逐步验证的分析路径。

星光编译者的技术博客,专注 C/C++、Linux、数据结构与算法。 490

Linux 网络基础详解:IP、子网、路由与 ip、ss 命令实战

建库建表、增删改查、连接查询(内连左连右连)、聚合函数、权限控制 GRANT/REVOKE,每条命令配可运行示例,零基础也能跟着敲会 SQL 基础。

2502_91473995的博客 607

Linux、Shell、MySQL 测试卷逐题细讲(下篇:MySQL)

本文为Linux、Shell、MySQL测试卷下半段MySQL部分逐题讲解,包含填空、选择与SQL分析三类题型。填空题覆盖COUNT、HAVING、DISTINCT、事务、约束、索引等核心语法;选择题辨析存储过程、索引类型、ACID、存储引擎、用户管理等考点。SQL大题围绕员工、部门、职位、地点四张关联表,考察多表连接、分组聚合、自连接、相关子查询、NULL处理等高频写法,标注LEFT JOIN统计计数、NULL判断、子查询别名等易错坑点,同时梳理试卷OCR识别带来的干扰问题,重点提示SQL实操中的常见失误

dongziwen1的博客 179

Linux 下 OpenCode 接入自定义大模型 API 教程:以 DeepSeek-V4.1-Flash-1017 为例

本文介绍在Linux下通过Python脚本配置OpenCode接入自定义大模型API(以DeepSeek-V4.1-Flash-1017为例),实现永久化、非侵入式配置。通过修改~/.config/opencode/opencode.json文件,添加OpenAI兼容服务商BLSC,注册模型并设置APIKey。支持命令行测试、默认模型设定及安全权限控制,操作简单且不影响原有配置。适用于各类支持OpenAI接口的自定义模型服务,提升开发灵活性与安全性。

qq_15060477的博客 118

【Linux 命令实战(02):文件与目录操作,掌握 pwd、ls、cd 三个核心命令】

命令作用cd /进入根目录cd ~进入当前用户家目录cd返回当前用户家目录cd …返回上一级目录cd …/…返回上两级目录cd -返回上一次所在目录进入指定目录命令核心用途常用参数pwd查看当前目录-L、-Pls查看文件和目录cd切换目录…、~、-Linux 文件系统的基本结构。绝对路径与相对路径的区别。Tab 自动补全。Shell 通配符。使用&&组合命令。这篇文章主要解决的是如何在 Linux 文件系统中快速定位目录。

一些微不足道的见解、希望能帮助各位 185

Linux Day29——HTTP与网络排障

*实测**:`traceroute -n -m 8 8.8.8.8` 的输出:第 1 跳 `172.17.144.1`(本机网关)、第 2 跳 `10.32.0.1`、第 3 跳 `10.50.255.253`、第 4 跳 `* * *`、第 5 跳 `221.226.71.193`、第 6 跳 `* * *`、第 7、8 跳有地址但夹着星号。`ping` 和 `traceroute` 都靠它。**实测**:`ss -lta` 看到三行 `domain`,加 `-n` 后变成 `53`。

2503_94114317的博客 147

Linux-IPC进程间通信

进程间通信(IPC)因进程空间独立但需数据共享而必要。主要方式包括:管道(无名/有名,基于队列)、信号(异步通知)、消息队列、共享内存(高效读写,需配合信号量同步)及Socket(网络通信)。无名管道用于亲缘进程,有名管道支持任意单机进程;共享内存提供高速共享,但需同步机制避免冲突。各类IPC各有特性,适用于不同场景。

2401_86256335的博客 159

【Linux指南】进程通信系列(七):System V 信号量 —— 同步互斥的内核原语

System V 三兄弟的压轴成员 —— 信号量(Semaphore) —— 是最特别的一位:它根本不传数据。消息队列传消息、共享内存传字节,信号量只干一件事:当保镖。

倔强的石头的博客 4250
上一篇: naos-riscv(block.c)源码分析
下一篇: naos的device.c源码:设备注册、子类型查找与驱动回调转发
咔_
博客等级 码龄4年 948粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值