标题: 求网上流行的maxdos(基于grub4dos)启动载入dos的原理
[打印本页]
作者: mylovedjn
时间: 2007-4-7 03:59
标题: 求网上流行的maxdos(基于grub4dos)启动载入dos的原理
求网上流行的maxdos(基于grub4dos)启动载入dos的原理
作者: yiyaxuan
时间: 2007-4-8 10:30
希望高手能解答下.
作者: lianjiang2004
时间: 2007-4-8 11:01
找了一篇,不知是否是你要的,反正本人是看不懂。我也不关心为何,只求知道如何用就行了。
--------------------
GRUB for DOS 磁盘仿真命令
技术细节和实现方法:
GRUB for DOS 0.2.x 将要对各种规格的软盘映像给以支持。由于硬盘的仿真也很类似,所以,也要对硬盘的 img 给以支持。另外,GRUB for DOS 0.2.x 也要开放写入虚拟磁盘的操作(写入虚拟盘是一种危险的操作,因为实际上我们写入了硬盘的 img 文件中,万一 GRUB for DOS 0.2.x 的仿真程序有 BUG,写入硬盘其它扇区中,可能造成数据毁损、无法启动等严重问题!)。
对软盘规格:需要解决的技术问题是如何恰当地处理三维的几何地址,也就是平常所说的 CHS(C——磁道柱面号;H——磁头号;S——扇区号)。对于真实的软驱(和软盘),都有这些规格的。然而,我们仿真之后的 img 文件,却无法表示这些规格。例如,一个 1.44M 的没有格式化的 img 文件,里面的数据全部是 00,怎么确定其 CHS 值呢?
当 img 文件已经经过 DOS 的格式化时,就用软盘第一扇区的 BPB 表来确定 CHS 值。如果没有经过 DOS 的格式化,或者发现其 BPB 表是错误的,那么就根据 img 文件的大小来确定 CHS 值。如果是标准的(或者常用的)软盘 img 尺寸,如 1.44M,1.2M,2.88M 等等,就用已知的 CHS 值。我们支持的软盘尺寸甚至可以是任意的(非标准的),如 10M 或 50M 或 500M 的软盘 img 文件。这时候,如果 BPB 表中没有合法的 CHS 值,就需要用 map 命令行参数来手动设置 CHS 值了。如果命令行没有指定 CHS 值,给出一个错误信息,拒绝仿真。当软盘 BPB 表和 map 命令行都有 CHS 的指定时,以命令行的指定为准,如果两者有差别,给出一个警告信息。
软盘规格列表(不支持扇区大小不等于 512 字节的防拷贝加密软盘):
软盘容量 每面磁道数 每道扇区数 磁头数或面数
----------------------------------------------------------------
0160K(标准) 40 08 1
0180K(标准) 40 09 1
0200K 40 05 2
0250K 50(暂用) 10(暂用) 1
0320K 80 08 1
0320K(标准) 40 08 2
0360K(标准) 40 09 2
0400K(优先) 40 10 2
0400K 80 05 2
0420K 42 10 2
0500K 50(暂用) 10(暂用) 2
0640K 80 08 2
0720K(标准) 80 09 2
0729K 81 09 2
0738K 82 09 2
0747K 83 09 2
0756K 84 09 2
0800K 80 10 2
0810K 81 10 2
0820K 82 10 2
0830K 83 10 2
0840K 84 10 2
0902K** 82 11 2
0984K** 82 12 2
1066K** 82 13 2
1200K(标准) 80 15 2
1215K 81 15 2
1230K 82 15 2
1245K 83 15 2
1260K 84 15 2
1360K 80 17 2
1377K 81 17 2
1394K 82 17 2
1411K 83 17 2
1428K 84 17 2
1440K(标准) 80 18 2
1458K 81 18 2
1476K 82 18 2
1494K 83 18 2
1512K 84 18 2
1558K** 82 19 2
1600K 80 20 2
1620K 81 20 2
1640K 82 20 2
1660K 83 20 2
1680K 84 20 2
1680K(优先) 80 21 2
1701K 81 21 2
1722K 82 21 2
1743K 83 21 2
1764K 84 21 2
1804K** 82 22 2
1886K** 82 23 2
2880K(标准) 80 36 2
3198K 82 39 2
3608K** 82 44 2
3690K** 82 45 2
3772K** 82 46 2
(感谢 Roy 兄提供了大量的磁盘规格资料)
硬盘比软盘复杂了一些。硬盘第一扇区不是 DOS 的引导区,而是主引导记录(MBR),这里没有 BPB 表,而是有一个分区表。所以,对于硬盘的 CHS,作如下的处理:
当没有分区表或者分区表错误时,必须由 map 命令行来指定 CHS,否则拒绝仿真。当分区表存在时,由四个分区表项中的任意一项都可以确定 H 和 S 的值。再用 img 文件长度即可确定 C 的值。【大硬盘的 CHS 值也是可以用这种办法来确定的。】
也可能有人不愿意给出命令行 CHS 参数,他们希望 grub for dos 任意选择一个适当的值。map 命令将提供这样一种选项。首先根据上述 BPB 或分区表来确定CHS,如果失败,再用以下的办法来确定。对于软盘,尽量采用具有 2 个磁头的参数。对于硬盘 img 文件,如果让 GRUB for DOS 来自动挑选,则总是选择 63个扇区、256 个磁头。
drive_map_slot 结构:
字节:FROM_DRIVE——把哪个 BIOS 磁盘号映射到另外一个磁盘号或者映射到另一个 img 文件?
字节:TO_DRIVE——被映射到的磁盘号。BIOS 磁盘号:0,1,……表示软盘,0x80,0x81,……表示硬盘。
字节:MAX_HEAD——最大磁头号。取值范围:0 至 255。
字节:MAX_SECTOR——最大扇区号。取值范围:1 至 63。
4字节:START_SECTOR——被映射到的 img 文件的起始扇区号。
4字节:SECTOR_COUNT——被映射到的 img 文件的扇区总数。必须是偶数。
当 MAX_SECTOR 的取值为 0 时,表示禁止常规磁盘读写中断(例如int13/AH=02)【map 的命令行参数 --disable-chs-mode】。MAX_SECTOR 的最高两位还有用。最高位为 1 表示只读操作【map 的命令行参数 --read-only 或者 --fake-write】,写入仿真软盘的扇区数据统统丢弃。次高位为 1 表示禁止扩展磁盘读写中断(例如 int13/AH=42H)【map 的命令行参数 --disable-lba-mode】。SECTOR_COUNT 是总扇区数。这个数目必须是偶数(当它为奇数时,处在末尾的一个扇区不参加仿真)。因此,SECTOR_COUNT 的最低位还有用。当该位为 1 而且 MAX_SECTOR 的最高位也为 1 时,表示“伪装写入扇区”操作【map 的命令行参数 --fake-write】。“伪装写”和“只读”是类似的,区别在于,“只读”在扔掉写入的扇区之后,告诉调用者程序说:“该盘写保护,不能写入”;而“伪装写”在扔掉写入的扇区之后,欺骗调用者程序说:“成功写入,请继续吧。”【我们有时候确实是需要这个功能的】。当 START_SECTOR 为 0 并且 SECTOR_COUNT 的高 31 位都为 0 时,表示用整个磁盘(而不是其中的一部分扇区段)来仿真【SECTOR_COUNT 的最低位表示“伪装写”】,这样仿真的效率要高一些【GNU GRUB 原来的仿真就是这样的,代码也很简单】。
当 SECTOR_COUNT 为奇数(也即 --fake-write 置位)而 MAX_SECTOR 的最高位为 0(也即 --read-only 没有置位)时,称为 safeboot,此时虽然允许写入虚拟磁盘,但不允许写入虚拟磁盘的第一扇区(引导区)。而且如果虚拟磁盘映象是一个硬盘映象,也不允许写入第 0 柱面第 1 磁头第 1 扇区(也就是逻辑扇区号 LBA=63 的扇区,该扇区通常是操作系统的引导扇区,例如 DOS 的 boot record)。这是对于 int13/AH=03h 来说的。程序并不禁止 int13/AH=43h (扩展写盘功能)的写入。也就是说,用 int13/AH=43h 可以写入任何扇区。 safeboot 默认时是开启的,可以使用 map 命令行参数 --unsafe-boot 来关闭它。【注:不存在 --safe-boot 选项。默认时之所以打开 safeboot,是因为曾经碰到 win98 破坏引导区的事情发生。如果您不准备启动 win98,您可以加上 --unsafe-boot 选项,从而允许 int13/AH=03h 写入引导扇区。很明显,只有在对虚拟盘进行分区以及格式化、或者运行 dos 的 sys 命令时才需要 --unsafe-boot 选项。】
map 命令还有两个命令行参数:
--heads-per-cylinder=NUM_HEADS
--sectors-per-track=NUM_SECTORS
NUM_HEADS 的取值范围是 1 至 256;NUM_SECTORS 的取值范围是 1 至 63。但它们也允许是 0,这表示用户允许 grub for dos 任意挑选一个合适的值。如果 map 的命令行没有指定 --heads-per-cylinder 以及 --sectors-per-track,那么,当 grub for dos 不能从 img 文件的第一扇区探测到一个合适的值时,会给出错误信息并拒绝仿真。
这里指出一点限制。GRUB for DOS 扩展了原来 GNU GRUB 的仿真。GNU GRUB 原来的仿真是一种简单的仿真,只能仿真整个磁盘,不能用一部分扇区来仿真。新的仿真可以用磁盘上的部分扇区序列来仿真,但是,这个功能的实现,利用了新型 BIOS 的逻辑块寻址(LBA)功能,也就是磁盘扩展读写功能。这对于老旧的 BIOS 是无效的。所以,老的 BIOS 无法利用新的仿真功能。但 GRUB for DOS 兼容 GNU GRUB 的仿真,所以,老的 BIOS 仍然可以用 GRUB for DOS 的“用整个磁盘来仿真”的功能,这是原来 GNU GRUB 本来就有的功能,其用法在 grub for dos 中完全没有变化。
可以在 grub> 提示符下用 help map 命令察看即时帮助信息。
下面介绍另外几个 map 命令行参数的用法。
map --status 这条命令显示磁盘仿真的状态,很有用。所显示的状态标题栏中,最右边的 Hk 表示 hook 的意思,其值是两位二进制数 xy,因此取值有四种:00,01,10,11。当 x 为 1 时,表示现在 grub 正在使用该虚拟磁盘。当 x 为 0 时,表示现在 grub 没有使用该虚拟磁盘。当 y 为 1 时,表示在运行 map --rehook 命令之后,grub 将使用该虚拟磁盘。当 y 为 0 时,表示在运行 map --rehook 命令之后,grub 将不使用该虚拟磁盘。
map --status 命令所显示的其它状态值都是容易理解的,它们都是以十六进制来表示的数值。
map --hook 这条命令用于直接在 grub 内部就开始使用仿真。通常 grub 本身是不使用仿真的,有了这条命令之后,从 grub 命令行就可以开始检验仿真的效果了。cool!关闭这个功能的命令是 map --unhook
map --unhook 正如上面解释的,关闭 grub 的即时仿真功能。
map --rehook 这条命令的用途:当你使用了 map --hook 命令之后,又用了新的 map 命令映射了别的磁盘,那么,你可以用 map --rehook 命令来激活全部这些仿真。这条命令等价于以下两条命令接连发出:
map --unhook
map --hook
当撤销磁盘仿真时,仅仅用 map --unhook 是不够的,还需要用类似于 map (fd0) (fd0) 的命令来撤销 (fd0) 的仿真。“map --unhook”命令仅仅使得在 grub 命令行之下不再使用仿真了,当您用 boot 命令时,会自动再次 hook 上。要想使得某个 map DESTINATION FROM_DRIVE 命令彻底失效,必须用 map FROM_DRIVE FROM_DRIVE 命令来撤销它【将某个 BIOS 磁盘号码映射到它自己,就意味着撤销它】。撤销部分 BIOS 磁盘号码的仿真之后,一般还需要运行 map --rehook 命令。例如,“map (hd1) (hd1)”命令撤销了对 (hd1) 的仿真,但在运行“map --rehook”之后才起作用。
作者: 人类
时间: 2007-12-31 00:43
分析maxs.sys,其c=80 h=4 s=36,容量高达5.7M,非标磁盘,也确实可用。
Last edited by 人类 on 2007-12-31 at 01:13 AM ]