中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
作者:
标题: 关于[获取硬盘物理参数]... 上一主题 | 下一主题
BSLTT
初级用户





积分 59
发帖 18
注册 2005-12-25
状态 离线
『楼 主』:  关于[获取硬盘物理参数]...

关于[获取硬盘物理参数]...   [DOS]

在网上一大把关于如何获取硬盘物理参数的文章.

我已经在网上找了N久,找出以下两种方法能得到硬盘的参数.

(一) .通过对IDE的I/O端口(1F0-1F7)操作获得硬盘参数.

①向端口3F6写入控制字节,建立相应的硬盘控制方式;
②检验硬盘控制器和驱动器的状态(检测端口的第7和第6两位),如果控制器空闲而且驱动器就绪,即可输入命令;
③完整的输入7个字节长度的命令块,一次写入端口1F1H-1F7H,不论是否需要,端口1F1H-1F6H对应的前6个字节的参数必须读出,端口1F7H的输出命令码为“0ECH”;
④检测端口1F7H的第7和第3两位,如果控制器空闲且第3位置1,表示操作结束,即可读取结果;
⑤通过端口1F0H读取100H字节到缓冲区;
⑥再次读取端口1F7H,判断第0位是否为0,如果为0,表示命令成功,否则表示命令失败;

读出的256字节信息的主要内容如下:
┏━━━━┯━━━━━━━━━┯━━━━━┓
┃ 偏移量  │ 内 容                   │长度(字节)┃
┠────┼─────────┼─────┨
┃02H      │柱面数                   │2            ┃
┃06H      │磁头数                   │2            ┃
┃08H      │每磁道所含的字节数 │2            ┃
┃0AH      │没扇区所含的字节数 │2            ┃
┃0CH      │每磁道所含的扇区数 │2            ┃
┃14H      │产品的序列号          │20          ┃  
┃2AH      │硬盘缓冲区容量       │2            ┃
┃2CH      │ECC校验码的长度     │2            ┃
┃2EH      │硬件修正号             │8            ┃
┃36H      │硬盘型号                │40          ┃
┗━━━━┷━━━━━━━━━┷━━━━━┛
以为这个似乎能解决了,但其实只是读出了 C.H.S 和硬盘序列号而以,先不说能访问8.4G以的磁盘空间.现在的电脑的BIOS都能自己检测硬盘,COMS->AUTO.
这样以来,硬盘是以LBA的方式工作,而不是C.H.S方式工作.
如果我们用BIOSDISK()这个函数再加上以上方式得到的C.H.S参数来用的话.就会出错.所以要得到硬盘的LBA参数.

(二)通过调用中断INT13 AH=48H(扩展)来获取硬盘LBA参数

入口:
    AH = 48h
    DL = 驱动器号
    DS:SI = 返回数据缓冲区地址
返回:
    CF = 0, AH = 0 成功
    DS:SI 硬盘参数数据包地址
    CF = 1, AH = 错误码

[至于程序网上很多,我就不贴了]
---------------------------------------------------------------------------------------------------------------
以上这些我在网上找了!出了什么问题不关我的事哎~!哈哈~!
---------------------------------------------------------------------------------------------------------------
现在有一问题无法解决.

如果用TC来写以上程序没有问题,但要用DJGPP来写的话就有问题!
问题出在INT86X()这个中断调用函数.网上的这个例子全是用TC写的,而TC有里一个FP_SEG()和FP_OFF()来获取硬盘参数数据包的段地址和偏移地址.
而我需要用DJGPP来写程序,根本不怎么怎么样获取硬盘参数数据包的段地址和偏移地址来放入INT86X()这个参数里,一但使用这个它就出错~!
(我读的书少,也不知道问题出在哪!)

知道的兄弟们请帮帮忙!谢谢~!

[ Last edited by BSLTT on 2005-12-28 at 10:36 ]

2005-12-28 10:17
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
taowentao
高级用户





积分 739
发帖 111
注册 2004-11-30
来自 辽宁沈阳
状态 离线
『第 2 楼』:  

连接:
http://www.cn-dos.net/forum/viewthread.php?tid=16538
内有实模式和保护模式的获取硬盘物理参数方法;

从:
http://www.cn-dos.net/forum/atta ... 6&checkid=69e88
下载rtCell_vc5_sources.rar,里面的 rtAta_Disk.c 内有保护模式磁盘操作源代码。

2005-12-28 10:48
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
BSLTT
初级用户





积分 59
发帖 18
注册 2005-12-25
状态 离线
『第 3 楼』:  

老大~!没有你我真不知道怎么过了~!谢谢~!太感谢了~!
(看看先~!)

2005-12-28 10:54
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
BSLTT
初级用户





积分 59
发帖 18
注册 2005-12-25
状态 离线
『第 4 楼』:  

老大!不知道是不是我搞错了还是怎么的~!
DJGPP GCC 编译无法通过~!!!

2005-12-28 11:39
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
taowentao
高级用户





积分 739
发帖 111
注册 2004-11-30
来自 辽宁沈阳
状态 离线
『第 5 楼』:  

用DJGPP GCC 实现rtAta_Disk.h中的

extern void __cdecl repinsw(WORD port, BYTE *buffer, WORD count);  
extern void __cdecl repoutsw(WORD port, BYTE *buffer, WORD count);
/* 从端口 port 输入一字节 */
extern BYTE _cdecl_ in_byte(WORD port);

/* 从端口 port 输入一字 */
extern WORD _cdecl_ in_word(WORD port);

/* 向端口 port 输出一字节 value */
extern void _cdecl_ out_byte(WORD port,WORD value);

/* 向端口 port 输出一字 value */
extern void _cdecl_ out_word(WORD port,WORD value);
几个函数;

用忙等待实现 Sleep(DWORD WAIT_TIMEOUT)延迟函数;

则可读取硬盘参数(调用static void wd_readp(ATA_DISK *pAD));



此程序的其他读写部分调用了实时微内核rtCell的库函数,建议你不要使用。

2005-12-28 13:05
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: