.block { r @$t0=${$sharedata}; aS /x ${/v:@#NtMajorVersion} @@C++(((nt!_KUSER_SHARED_DATA *)@$t0)->NtMajorVersion); aS /x ${/v:@#NtMinorVersion} @@C++(((nt!_KUSER_SHARED_DATA *)@$t0)->NtMinorVersion); }
ad /q ${/v:$sharedata}
.catch { r @$t0 = 0; .foreach (${/v:$addr} {lm1m m nt}) { r @$t0 = ${$addr}; .leave; } }
.if ($vvalid(@$t0, 1)) { aS ${/v:@#DebugMode} 0; .foreach (${/v:$val} {.catch{? @eax}}) { .if ($scmp("${$val}", "\'@eax\'")==0) { aS ${/v:@#DebugMode} 1; } } } .else { aS ${/v:@#DebugMode} 2; }
.block { $$ .echo ${$ImageName} .if ($sicmp("${$ImageName}", "explorer.exe") == 0) { .echo Found the process at ${$ProcAddr}; .process /p /r ${$ProcAddr}; ad ${/v:$ImageName}; ad ${/v:$ProcAddr}; .break; } }
看的没错,这篇文章将描述一些关于Floppy Disk Controller的编程知识。我们知道,在当今的计算机硬件体系中,软盘驱动器是一个已经完全被淘汰的设备,那么为什么还要有这样一篇文章?原因很简单,如果想构建自己的操作系统,必须有相应的存储介质,而软盘正是这样一个好的存储介质。他的容量虽然很小,但是却完全足够应付我们的内核程序,另一方面软盘驱动器的控制相对于之前我所介绍的硬盘的控制要简单的多,而且关于软盘驱动器控制的教程和文章在互联网上也非常的多(虽然绝大部分都是英文的)。基于以上几点,我认为还是有必要把自己学到的知识写下了分享。
Floppy Disk Controller,中文称为:软盘控制器,简称:FDC,是一个用来控制软盘驱动器的芯片。在1980年代到1990年代,软盘控制器普遍使用于个人电脑以及与IBM PC兼容的机型上,如 8272A、82078、82077SL以及82077AA,其中82077AA是最先进的一款芯片(1991年开始生产)。除了软盘控制器,软驱本身也在几十年的历史中留下了许多机型,如图所示: 实际上,我从刚刚接触软盘到最后软盘被淘汰,只使用过3.5英寸1.44MB的软盘,其他型号完全没有接触过。
ISA DMA ISA DMA全称Industry Standard Architecture Direct Memory Access,是一种古老的DMA方式,速度比PIO还要慢,但是编程相对于PCI BusMastering DMA要简单一点。这里我并不打算详细介绍ISA DMA,因为说明它需要的篇幅不亚于这篇。后面的代码中,在必要的地方我会加入一些解释。
3.设置FDC里面三个时钟以及DMA 三个时钟分别是步进速率时钟、磁头卸载时钟和磁头装入时钟。数据格式如下: S S S S H H H H - S=步进速率时钟 H=磁头卸载时钟 H H H H H H H NDMA - H=磁头装入时钟 NDMA=0 (DMA模式) 或者 1 (非DMA模式) 实际上这个大家可以随意设置,我设置的是步进速率时钟=3ms, 磁头卸载时钟=240ms, 磁头装入时钟=16ms
4.发送寻道命令进行寻道 寻道命令的参数是两个自己,分别代表磁头、柱面和驱动器号,格式如下 x x x x x HD DR1 DR0 - HD=磁头 DR1/DR0 = 驱动器 C C C C C C C C - C=柱面
物理区域描述符(Physical Region Descriptor) 进行数据传输的物理内存块都用物理区域描述符进行描述。当所有在物理区域描述符表中的物理区域描述符所指向的内存都被传输完成后,数据传输就会停止。每个物理区域描述符是8字节。前4个字节指定的是物理内存区域的地址。接下来的两个字节指定内存数量。最后一个字节的第7位表示此理区域描述符是该表中最后一个描述符。
物理区域描述符表(Physical Region Descriptor Table) 这张表中包含一定数量的物理区域描述符(PRD),描述符表必须是4字节对齐且不能跨越64K边界的内存。