79-80 - 硬盘驱动程序设计

---- 整理自狄泰软件唐佐林老师课程

查看所有文章链接:(更新中)深入浅出操作系统 - 目录

文章目录

  • 1. IDE是什么?
    • 1.1 问题
    • 1.2 创建虚拟硬盘
    • 1.3 修改bochsrc
    • 1.4 BIOS留下的遗产
    • 1.5 编程实验:虚拟硬盘创建
  • 2. 硬盘控制器
    • 2.1 硬盘操作基本步骤
    • 2.2 关键寄存器详解 - LBA Register
    • 2.3 关键寄存器详解 - Device Register
    • 2.4 关键寄存器详解 - Command Register
    • 2.5 关键寄存器详解 - Status Register
    • 2.6 思考
  • 3. 硬盘读写注意事项
    • 3.1 注意一
    • 3.2 注意二
    • 3.3 汇编小贴士
    • 3.4 端口读写
    • 3.5 数据结构创建
    • 3.6 硬盘数据读取示例
    • 3.7 编程实验:硬盘驱动程序设计
    • 3.8 思考

1. IDE是什么?

早期,硬盘控制器和硬盘本身是分开的
后来,硬盘控制器和硬盘本身合二为一
于是,有了高大上的名字 Integrated Drive Electronics,IDE
再后来,有了别名ATA,然后是ATA / IDE
最初的硬盘是用并口传输数据,所以IDE常指代并口硬盘接口
后来有了串口硬盘接口,名为: SerialATA,缩写:SATA …

1.1 问题

  • 虚拟机中有硬盘吗?如何创建一块虚拟硬盘?

1.2 创建虚拟硬盘

79-80 - 硬盘驱动程序设计_第1张图片

1.3 修改bochsrc

79-80 - 硬盘驱动程序设计_第2张图片

1.4 BIOS留下的遗产

BIOS运行后会遍历系统中的硬件,并记录相关信息。其中,硬盘数量记录于 0x475地址 处。
79-80 - 硬盘驱动程序设计_第3张图片

1.5 编程实验:虚拟硬盘创建

79-80 - 硬盘驱动程序设计_第4张图片
79-80 - 硬盘驱动程序设计_第5张图片

【参看链接】:79-80 - 硬盘驱动程序设计 / 79 / 00虚拟硬盘创建

79-80 - 硬盘驱动程序设计_第6张图片

2. 硬盘控制器

  • 硬盘控制器:硬盘的原生操作接口
    通过 固定I/O端口 对硬盘控制器进行操作
    操作的 本质读写硬盘控制器中的寄存器
    • 命令块寄存器(Command Block Register)
    • 控制块寄存器(Control Block Register)
  • 硬盘IO端口及寄存器

79-80 - 硬盘驱动程序设计_第7张图片

  • 注意
    • 命令块寄存器对应多个端口(多个寄存器)
    • 控制块寄存器对应单个端口(单个寄存器)
    • 端口可读可写,但读写时意义可能不同

2.1 硬盘操作基本步骤

  1. 命令块寄存器 写数据
  2. 控制块寄存器 写数据
  3. 从数据端口中 读取数据

79-80 - 硬盘驱动程序设计_第8张图片

2.2 关键寄存器详解 - LBA Register

  • LBA是什么?
    LBA:Logical Block Addressing,逻辑块地址,是一种线性寻址的方式(0 ~ n)

79-80 - 硬盘驱动程序设计_第9张图片
注:将CHS地址映射到线性地址

  • 目前绝大多数硬盘支持 LBA扇区寻址方式
    • 通过3.5个寄存器(即:28位)读写硬盘扇区
      • LBA Low:保存逻辑扇区地址的 低8位
      • LBA Mid:保存逻辑扇区地址中的 中8位
      • LBA High:保存逻辑扇区地址的 高8位
    • 8 * 3 = 24,还有 28 - 24 = 4 位在哪里?

2.3 关键寄存器详解 - Device Register

79-80 - 硬盘驱动程序设计_第10张图片

2.4 关键寄存器详解 - Command Register

指定硬盘操作:

79-80 - 硬盘驱动程序设计_第11张图片

2.5 关键寄存器详解 - Status Register

79-80 - 硬盘驱动程序设计_第12张图片

2.6 思考

  • 硬盘读写数据时需要注意哪些问题?

3. 硬盘读写注意事项

3.1 注意一

  • 硬盘以 扇区 为基本读写单位
    读写数据时需要 计算目标扇区的 逻辑地址(LBA)
    确定逻辑地址后,读取扇区数据到内存( 512字节
    • 读:从读取的扇区中拷贝目标数据
    • 写:数据写入读取的扇区中,之后将扇区数据 写回硬盘

3.2 注意二

硬盘数据端口(0x1F0)的读写需要以 双字节为单位(WORD)

在这里插入图片描述

注:双字节对应C语言中的 ushort

3.3 汇编小贴士

cld:清空方向标志位,向高地址方向增加地址值
insw:端口操作,从端口读取一个字(双字节)
outsw:端口操作,向端口写入一个字(双字节)
rep:重复指令,重复次数由ecx寄存器指定

3.4 端口读写

;
; void ReadPortW(ushort port, ushort* buf, uint len)
;
ReadPortW:
    push ebp
    mov ebp, esp
    
    mov edx, [ebp + 8]  ; 参数port
    mov edi, [ebp + 12] ; 参数buf
    mov ecx, [ebp + 16] ; 参数len

    cld
    rep insw

    nop
    nop
    nop

    leave
    ret

;
; void WritePortW(ushort port, ushort* buf, uint len)
;
WritePortW:
    push ebp
    mov ebp, esp

    mov edx, [ebp + 8]  ; 参数port
    mov esi, [ebp + 12] ; 参数buf
    mov ecx, [ebp + 16] ; 参数len

    cld
    rep outsw

    nop
    nop
    nop

    leave
    ret
  • 将esi指向的2n个字节写入edx指定的端口中:
    在这里插入图片描述

  • 从edx指定的端口中读取2n个字节并存入edi指向的地址中:
    在这里插入图片描述

3.5 数据结构创建

79-80 - 硬盘驱动程序设计_第13张图片

3.6 硬盘数据读取示例

79-80 - 硬盘驱动程序设计_第14张图片

注释:si - 指第几个扇区:sector index

3.7 编程实验:硬盘驱动程序设计

  1. 测试硬盘读写

【参看链接】:79-80 - 硬盘驱动程序设计 / 79 / 01测试硬盘读写

79-80 - 硬盘驱动程序设计_第15张图片

  1. 开发文件系统预备工作

【参看链接】:79-80 - 硬盘驱动程序设计 / 80

79-80 - 硬盘驱动程序设计_第16张图片

3.8 思考

-[ ] 能够读取硬盘扇区是否就可以创建文件?

你可能感兴趣的:(深入浅出操作系统,linux,unix,ubuntu,c语言,嵌入式硬件)