无忧启动论坛

标题: 准备基于 fbinst 进行再开发,请各位提供帮助 [打印本页]

作者: 不点    时间: 2013-12-6 19:42
标题: 准备基于 fbinst 进行再开发,请各位提供帮助
本帖最后由 不点 于 2024-10-19 21:10 编辑

有谁以前曾经做了 fbinst 的工作,请把最新的源代码上载到这里(或者给个下载地址)。我将在诸位最新代码的基础上进行开发。



由于新版添加了 html 格式的启动映像生成工具,因此下面这些使用说明就没有多大用处了(可作为历史资料查阅)。以前的安装图解体积太大,放在这里不合适,也已经挪到这里了:http://bbs.wuyou.net/forum.php?mod=redirect&goto=findpost&ptid=320244&pid=3286903&fromuid=250692  (即,大约在本主题 373 楼的位置)万一有人需要的话,还可以点击进去查看。

新版使用方法:用火狐浏览器打开其中的 index.html 网页文件,并按照提示进行操作。



简要使用说明

压缩包里面含有若干 IMG 文件,分别用于 8G、16G、32G、64G 和 128G 的可启动磁盘。

请用 BOOTICE 的 “扇区编辑” 功能,把相应的文件(例如 mbr_16G.img)导入到 U 盘(导入时要勾掉“保留磁盘签名和分区表不变”,就是说,不要勾上,要把勾去掉),覆盖掉 U 盘原有的内容。提示:
编译时,用户可以使用任何版本的 grldr。只需把 grldr 替换掉,然后敲入 make 命令重新编译即可。

!!注意不要阴差阳错把硬盘毁掉!!

导入后,U 盘就已经含有一个 FAT32 主分区。它是启动分区,已经格式化了,不要对其再次格式化。如果把它格式化,那就会抹掉 “多重 MBR” 的启动代码,所制作的启动盘也变成无效的了。你可以向这个分区的根目录拷贝 menu.lst 文件,启动后,它将被 grldr 执行。
【2015-12-04 更新】你也可以拷贝你自己的 GRLDR 文件到根目录,启动后,这个 GRLDR 文件将获得控制权。就根目录下的 grldr 而言,你可以使用老版本的 grldr,也可以使用新版本的 grldr;你可以使用 0.4.5 系列的,也可以使用 0.4.6 系列的。根目录下的 grldr(如果存在的话),是用来让编译时内置的 grldr 进行调用的。编译时内置的 grldr,当它将控制权传递给根目录下的 grldr 之后,就完成任务了(不再起作用了)。因此,根目录下的 grldr(如果存在的话)将取代编译时内置的 GRLDR 完成后续的启动步骤。

0pe 的用户只需把 0pe 里面的 menu.lst 和 0pe.iso 复制到 U 盘根目录即可。以后每次更新 0pe,都只需更新 menu.lst 和 0pe.iso 这两个文件,无需重新制作可启动 U 盘。旧版的 0pe 可能需要在 U 盘根目录下放置一个与 0pe 匹配的 grldr 文件,否则 0pe 可能无法正常工作。

如何让这个 U 盘支持 EFI 启动?

只需把 0pe 里面的 EFI 目录拷贝到这个 U 盘的根目录,即可在支持 EFI 启动的机器上启动 EFI 目录下的 PE(比如 Win7pe 或 Win10pe)。

建议使用 16G 或更大的 U 盘来作为 “多重 MBR” 启动盘。

为防止 Win7、Win8 把这个 U 盘的 FAT32 文件系统搞乱,请按以下步骤纠正 “总扇区数” 错误,也就是让分区表和 BPB 表上的 “总扇区数” 参数与 U 盘实际的大小相匹配。

说明:diskgen 可以纠正分区表上的总扇区数错误,但遗憾的是,diskgen 不能纠正 BPB 表上的总扇区数错误。这两个错误都必须纠正,然后才可以安全地在 Win7、Win8 下使用。纠正的具体步骤如下:

1、在上述 BOOTICE 的导入步骤完成并退出 BOOTICE 后,现在进入 diskgen,让它去读 U 盘,此时 diskgen 会发现 U 盘的总扇区数错误,并询问是否纠正错误。让它纠正,保存所做的更改,退出 diskgen。【注意】先前的 BOOTICE 的导入步骤完成后不要插拔 U 盘,而应该直接进入 diskgen 进行纠正。下面的第 2 步,同样不要插拔 U 盘。待到这两个纠正的步骤都圆满完成之后,再从资源管理器中卸载 U 盘即可。成功卸载之后可以拔出 U 盘。

2、再次打开 BOOTICE,选择 U 盘,用 “扇区编辑” 功能,将扇区 0(扇区0 就是 U 盘的 MBR 扇区) 的分区表上的分区总扇区数(即分区长度,在偏移 0x1CA 处的四个字节)记录下来。它其实就是刚才 diskgen 纠正后的值,这是正确的值。然后选择扇区 63(扇区 63 就是 U 盘的 FAT32 文件系统的首扇区,也称为 PBR 扇区),将 BPB 表上的总扇区数(偏移 0x20 处的四个字节)纠正为刚才所记录的分区总扇区数。其他数据都不用改动。完成后,保存更改,退出 BOOTICE。最后从 Windows 系统中卸载 U 盘,这就可以拔出 U 盘了。【注意】如果您不熟悉分区表和 BPB 的结构,请您放弃,不要胡乱操作。这主要是为了保证安全,尽量避免阴差阳错伤害到您的硬盘。






2017 年 4 月 2 日更新:

本次变更:更新内置的 GRLDR 为 0.4.6a-2017-03-30 最新版;MultiMBR Booter 网页程序添加调试出错对话框,提醒出错时该如何处理。


multimbr.7z.zip

1.28 MB, 下载次数: 298, 下载积分: 无忧币 -2

更新 GRLDR 至 0.4.6a-2017-03-30;MultiMBR Booter 添加出错处理提示信息。

multimbr.zip

1.04 MB, 下载次数: 108, 下载积分: 无忧币 -2

更新 GRLDR 至 0.4.6a-2020-03-04

multimbr.zip

1 MB, 下载次数: 28, 下载积分: 无忧币 -2

添加对 chrome 浏览器的支持


作者: 2011SHENGAI    时间: 2013-12-6 20:42
支持大师!菜鸟们谢谢您!
作者: 135956    时间: 2013-12-6 20:50
板凳坐着。。。
作者: 135956    时间: 2013-12-6 20:51
希望 fbinst 原作者能上传一下最新代码。。。。
作者: bfgxp    时间: 2013-12-6 21:59
不点有新想法了?
作者: 俊采星驰    时间: 2013-12-6 22:47
能否剧透下要增强的功能嘛,呵呵
作者: 月光海洋    时间: 2013-12-6 23:10
支持不点大人…
作者: 月光海洋    时间: 2013-12-6 23:11
记得早些时候神雕大侠好像编译过一个…
作者: 不点    时间: 2013-12-6 23:12
根据多年来论坛所反馈的情况,发现 fbinst 有改进的余地。

我想尝试一下,进一步提高 fbinst 的适应性。

初步打算,尽量不改变 ud 系统的格式,以保持兼容性。

有可能引进以前的三重 MBR 的部分合理概念,强化 fbinst 的适应性。

希望对 fbinst 的源代码进行增强改进的几位作者,能够提供最新的源代码。


作者: shan    时间: 2013-12-6 23:16
感谢不点大师再次奋起!这是个巨大的好消息,十分具有穿透力。期待的很。
作者: caocaofff    时间: 2013-12-7 08:19
这个源码不是最新的,不知道有没有帮助
强烈支持大师再开发!!!
fbinst源码.rar (468.08 KB, 下载次数: 243)
作者: chenall    时间: 2013-12-7 10:04
我很早修改过的在这里
https://code.google.com/p/grubutils/source/browse/#
作者: zbkh    时间: 2013-12-7 14:26
期待大师的新作,非常感谢不点!
作者: 不点    时间: 2013-12-7 15:48
看到大家很支持,我感觉有些压力,唯恐做不好,或由于身体原因而做不了,对不住大家。

其实,这个工作,不一定非得由我来做。我还真没留意 chenall 早已经把 fbinst 放在 google code 上了,并且早就已经开始修补了。Bean 当初做的时候,我身体很糟糕,没有跟得上,大部分帖子都没看。chenall 接管 grub4dos 以后,我竟然没有注意到 chenall 把 bean 的 fbinst 也拿过来了。

好的,先不说这些了。我的想法是,先讨论,发表我的主要看法以及构思。至于说具体的工作,谁有时间谁做,都可以。我感觉 chenall、yaya、jianliulin 等许许多多人都可以做,凡是懂得 BIOS 的人都行。

今天就先谈谈我的想法吧。

单刀直入,fbinst 暴露出缺点了。最近论坛上有一个报告说,明基笔记本从手机启动时,由于手机硬件把 MBR 磁道全部屏蔽,导致 fbinst 无法接到控制权。位于 PBR 的代码取得了控制权。

我们知道,fbinst 的代码本身就是隐藏的,它有 8M 的大小。但这 8M 就被当作 MBR 磁道而屏蔽掉了。

fbinst 无法适应这种情况,因此,fbinst 需要改造或增强。

我想了两天,想来想去,还是觉得,要改造的话,恐怕还是要全新打造,而无法与 fbinst 兼容了。

主要技术思路。研究的过程,分两步。第一步,主要目的是保证从 BIOS 那里取得控制权。这一步的研究过程最重要。我们的测试代码仅仅只需要一个扇区,把这些代码复制到 U 盘所有的扇区上,测试者报告哪个扇区获得了控制。这一阶段不需要启动 grldr,而只要看到屏幕上获得控制后的显示信息便可。

务必保证第一步取得 100% 成功。我们的测试代码永远保留,将来如果有人遇到失败,仍然用这个测试代码来测试,并加以改进,直到成功率仍然是 100%,完全消除死角。

第一步成功后,其实就大功告成了,剩下的只是如何找到 grldr 并启动它了。

有人说了,bean 不是早做过这样的测试工作吗?

bean 是做过了,不过其性质是有差别的。bean 的 MBR 分区表的表项指向 8M 处的 PBR,这太靠后了,在上面所说的情况下,整个 8M 都被屏蔽。我们这次,让第一分区位于第 63 扇区(或第 32 扇区)处。那么这个测试当然就具有不同的性质了。

第二步很简单了,找到 grldr 并加载它。由于第一步已经确定了准确的 H 和 S,所以,第二步就毫无困难了。

所以,我们的 “重中之重” 是要长期做第一步的测试工作,不可懈怠。

最近我会思考具体的路线,也可能提供一些测试映像,以便让大家克隆到 U 盘上进行测试。

等到明年或后年,第一步成熟之后,就由其他人来编写第二步的代码了。

作者: singel    时间: 2013-12-7 16:00
支持不点大师,期待ing
作者: zds1210    时间: 2013-12-7 19:02
强烈支持。
嗯。百草霜大侠也开发过,联系一下他。百大的fbinst plus
现在的主要问题是:在7&8PE下,似乎搜索可见区petools已经失效。
在64位8PE也,导出UD区文件失效。

作者: David.Z    时间: 2013-12-7 21:21
强烈支持!!但大师也要注意身体呀,慢慢来,有好的身体才能长期奋斗。支持你。
作者: 干净的PE    时间: 2013-12-7 22:45
支持曹操
作者: 翅膀    时间: 2013-12-8 07:34
提示: 作者被禁止或删除 内容自动屏蔽
作者: devilma    时间: 2013-12-8 13:46
原作者赶紧上传最新源代码吧。。。。期待不点大大的大作。。。
作者: 不点    时间: 2013-12-8 18:41
引导扇区概念设计

一、打印信息设计

DX=XXXX 最关键的寄存器,含有接管控制时的盘号 DL。

boot=XXXX    表示接管控制的引导扇区的物理扇区号。
mbr0=XXXX    表示 MBR 所在的 BIOS 第 0 扇区的物理扇区号,它表示有多少个扇区被隐藏了。

boot 和 mbr0 应该是相等的,如果不相等,那就暴露出了变态的主板行为。

LBA 表示支持 LBA,如果不支持,则不显示。

S=XX 每道扇区数,它比较容易获得,只需要从 mbr0 开始有连续 64 个扇区的物理扇区号记录便可计算出来。
H=XX 磁头数,获得它要比获得 S 稍稍困难一些。

如果全部都用记录扇区号的方法,则确定 H 需要 8M 的扇区,这就与 S 一样容易获得了。但我们可以稍加改进。我们留出 1024 个扇区不记录物理扇区号(叫做 “自由扇区” 或 “空白扇区”),这样可以方便大家手动嵌入外部引导代码(grldr 或 ntldr)。


二、磁盘数据结构设计

扇区 0 的分区表指向扇区 63(作为分区的起始扇区,下同),而扇区 63 的分区表指向扇区 126,为了保险起见,扇区 126 也设置一个分区表,指向扇区 189。分区表与其对应的第一分区的距离总是 63 个扇区。这样,即使被两次隐藏,扇区 126 也能获得控制。第一次隐藏时,有可能扇区 0 至 63 中的某个扇区被当作 mbr0。但经过第二次隐藏,则有可能扇区 63 至 126 中的某个扇区被当作 mbr0。两次隐藏的总效果是,有可能扇区 0 - 126 中的某个扇区被当作 mbr0 了。我们在扇区 0 至 126 上都设置分区表,其第一分区都是指向其后的 63 扇区偏移。而扇区 127 至 189 的分区表则指向 8M 附近的实际分区数据。扇区 0 至 189 都记录着自己的物理扇区号。从扇区 190 至 1213,总共 1024 个扇区,不记录物理扇区号(即 “空白扇区”)。这个空间是 512K,用来放置外部引导代码(GRLDR 或 NTLDR)。接下来的连续扇区空间,一直延伸到 8M 附近的扇区 126 + 255×63,都记录物理扇区号。

总起来说,头部有 190 个扇区记录着扇区号,接着是 1024 个空白扇区,再往后又是连续记录扇区号的 (126+255×63 - 1213) 个扇区,其后又全都是空白扇区。

如果扇区号 0 - 126 之一获得控制,那么首先读柱面 0 的起始扇区 mbr0(即 C/H/S=0/0/1),这样可以得到 mbr0 的物理扇区号。

接着读柱面 1 的起始扇区 C/H/S=1/0/1。读之前显示信息 3 秒,防止死机或重启。有三种情况,分别讨论如下。


【情况一】

如果读柱面 1 的起始扇区时发生死机、重启,那就证明机器很变态,重启时用户按空格键来强制设定 C=1,这样就认为只有柱面 0,而避免去读柱面 1。如果没有死机但读出的数据无效,或者读取失败(CF=1),这都表明 C=1,即只有一个柱面。在这样的情况下,最大访问能力是 255×63=8M。还需要进一步确定 H 和 S 的值。

读扇区 C/H/S=0/1/1 可以确定 S 的值。如果死机、重启或出错、失败,则表明 H=1,即只有一个磁头。那么最大访问能力只有 63 个扇区了。因此,这种情况没有意义,什么事也干不成,直接放弃得了,就当成 “电脑根本不支持 U 盘启动” 来对待。用户明白这一情况后就有理由淘汰这样的机器了。

S 确定之后,怎么确定 H 的值?只有一个一个试验。读 C/H/S=0/n/1,成功后 H 就等于 (n+1)。其实,没必要确定 H 了,这是因为 C=1,因此 H 直接取最大值 255 就可以了。也就是说,在只有一个柱面的情况下,只要 S 是正确的,几何参数方面就没问题了,H 可以不管了。这一点正如在多柱面情况下 C 值不重要,只要知道 H 和 S 就 OK 了。用户对磁盘的使用,肯定只能尽量使用开头的扇区,否则总是危险的,即,当超出主板 BIOS 访问能力时,总是有死机、重启或出现其他异常情况的危险。因此,不用确定 H 了(取最大值 255),用户自己会尽量使用靠近开头的那些扇区,其 H 值当然也就比较小了。


【情况二】

如果柱面 1 最开头的那个扇区的物理扇区号是有记录的,则可以计算出柱面的长度(即,柱面长度=该扇区号 - mbr0)。

如果柱面长度大于 63,则每个柱面至少有 2 个磁道。于是可以读下一个磁道。现在可以放心地读柱面 0 的扇区 C/H/S=0/1/1,它肯定是有物理扇区号记录的。这样就知道了 S 的值了(S=该扇区号 - mbr0)。

如果柱面长度为 63 或更小,则有可能只有 1 个磁头。当 H=1 时,S=柱面长度,能确定 S。但问题是无法确定 H 是否为 1。

因此,我们冒险假定 H 大于 1,而去读 C/H/S=0/1/1。读之前显示信息 3 秒,如果发生死机或重启,就知道机器很变态了。于是就知道这个机器的 H=1 了。重启时按空格键即可强制以 H=1 来处理,而不再去读柱面 0 磁道 1 的起始扇区了。如果读取成功,可以计算出 S。因而 H 也可以算出来了。

我们还有一个(候选的)冒险方法,就是假定 H=1,S=(柱面长度)。这时,我们冒险读柱面 0 上的 S 个扇区。如果读取成功,并且每个扇区的物理扇区号都正确,那么就 OK 了。否则,一定是相反的情况,即 H 大于 1,此时又可以用前面的方法确定 S 的值了。如果读取时失败、死机、重启,那都证明 H 大于 1,因而重启时注意用键盘按键来控制。


【情况三】

如果柱面 1 上最开头的扇区没有记录物理扇区号,那么就知道柱面长度一定大于 63,因此和刚才的情况一样,可以确定 S 的值。由于柱面长度未知,因此,还需要一个步骤来确定 H 的值。我们先前已经知道,未记录扇区号的那些扇区号范围是从扇区 190 到扇区 1213。柱面 1 的起始扇区一定落在其中。那么柱面的长度的变化范围就是

最小值 = 190 - 126 = 64

最大值 = 1213 - 0 = 1213


柱面长度如果取最小值 64,那么柱面 20 的起始扇区的物理扇区号就是

20×64 + mbr0 = 1280 + mbr0


这一定落在我们事先已经记录扇区号的区域了。

柱面长度如果取最大值 1213,那么柱面 2 的起始扇区的物理扇区号就是


2×1213 + mbr0 = 2426 + mbr0


这也落在了已经记录扇区号的区域。

因此,无论如何,只要从柱面 2 到柱面 20 逐个读取柱面的起始扇区(最多读 19 次),一定可以碰到一个记录了物理扇区号的扇区。这样,就可以算出 H 的值了。如果读取失败或死机,则表明 BIOS 的访问能力不足 1.44M(仅有 1.213M)。读取时,屏幕有信息显示,让用户能够看到。如果发生死机或重启,用户记住最后一行信息,就可以知道 BIOS 的访问能力太差了。用户甚至有理由淘汰这样的机器了。

这样,H 和 S 都得到了。在屏幕上打印出 H 和 S 的值,圆满完成第一阶段的任务。

第二阶段,其实简单得很,直接加载位于物理扇区号 190 开始的外部引导器代码(grldr 或 ntldr)即可。


作者: 快雪时晴    时间: 2013-12-8 20:33
本帖最后由 快雪时晴 于 2013-12-8 20:34 编辑

记得对fbinst研究较深的有:天涯海角、Plantsoot、P大... 当然还有chenall和不点你自己咯


我就知道不点歇不了的,因为他是个有想法的人
作者: zds1210    时间: 2013-12-8 20:34
也希望老大们出一个UD驱动出来,PE启动后,只读显示UD区出来。
作者: ggmm888    时间: 2013-12-8 20:47
本帖最后由 ggmm888 于 2013-12-8 21:10 编辑

支持不点大侠的工作

实机使用fbinst制做的U盘,在启动电脑时,BIOS设置成USB-zip时,启动成功率要高。
实机使用fbinst制做的U盘不能启动的电脑,往往可以使用三重 MBR的U盘启动电脑。具体原因没有去考查,因不是自己的机子,但这种情况很多,大家应该容易找到这样的机器。我不能提供这样的机器做实验,请愿谅。

还有BIOS设置成USB-HDD时,U盘做成了USB-HDD格式,从U盘启动,但有的机器不读U盘上的grldr,而读取了硬盘上的grldr,有时还找不到U盘。这样的机器,使用fbinst制做的U盘,没有此现像,正确读取fbinst制做的U盘上的grldr


作者: jianliulin    时间: 2013-12-9 19:21
本帖最后由 jianliulin 于 2013-12-9 19:28 编辑

fbinstTool 1.606世界末日版,是在chenall 在本贴#12楼发布的(https://code.google.com/p/grubutils/source/browse/#) 基础上把fb_data 中未利用的2个字节其中一个做了标记,0:文件列表为ansi编码,1:为utf-8,读取或写入文件列表时候就根据标志用相应的编码来处理,由于命令行和GUI的操作不同,我是用delphi把除了汇编部分全部重新写fbinst以便满足GUI的需求,语言不同代码我就不贴了,我改的部分主要是用户操作上,所以可以忽略我的修改,不需考虑兼容。


struct fb_data
{
    uchar2 boot_size;                /* 0x200  */
    uchar is_utf8_list; /* 0x201  */  //0:文件列表为ANSI,1:文件列表为 utf-8
    uchar flags;                          /* 0x202  */  //未使用
    uchar ver_major;                /* 0x204  */
    uchar ver_minor;                /* 0x205  */
    uchar2 list_used;                /* 0x206  */
    uchar2 list_size;                /* 0x208  */
    uchar2 pri_size;                /* 0x20a  */
    uchar4 ext_size;                /* 0x20c  */
} PACK;
作者: 2011yaya2007777    时间: 2013-12-9 21:43
https://code.google.com/p/grubutils/source/browse/#

进不去。
作者: 306344381    时间: 2013-12-9 21:44
支持不点大人…
作者: feifanll    时间: 2013-12-9 21:52
支持大师......
作者: 不点    时间: 2013-12-9 23:03
2011yaya2007777 发表于 2013-12-9 21:43
进不去。

点击就进去了。你的 ISP 把这个网址屏蔽了?

chenall 为 wee 建立的那个空间,就是与 grubinst 在一起的。都是google 空间,应该可以访问。
作者: mygamexxx    时间: 2013-12-10 08:26
本帖最后由 mygamexxx 于 2013-12-10 08:28 编辑
2011yaya2007777 发表于 2013-12-9 21:43
进不去。


开了两个页面,一个能进去,但等待时间比较长,一个最后显示“无法显示此页”。
作者: freesoft00    时间: 2013-12-10 10:45
http://code.google.com/p/grubutils/source/browse/#
试试
作者: 2011yaya2007777    时间: 2013-12-10 11:25
下载了,谢谢
作者: 讯极天度    时间: 2013-12-10 23:29
mygamexxx 发表于 2013-12-10 08:26
开了两个页面,一个能进去,但等待时间比较长,一个最后显示“无法显示此页”。

进不去就借助GAE,肯定是可以的
作者: 20100660    时间: 2013-12-11 22:29
好消息………………………
作者: 20121223445667    时间: 2013-12-12 21:01
后排膜拜大神!

作者: 2011yumeiren    时间: 2013-12-14 10:24
难道是打酱油的!
作者: 天使的魔翼    时间: 2013-12-17 16:03
我来座等测试吧,这个星期完了后,我可以着手测试相关内容,05年至今的电脑都有,几乎涵盖了HP、DELL、IBM、联想等,笔记本有四种:IBM、HP、DELL、三星。新的电脑马上到手主要是DELL和东芝,都可以拿来练手的,随便拆,随便改,用坏了直接换货的。
作者: 不点    时间: 2013-12-17 18:32
看到有 “天使的魔翼” 这样有条件的测试者,令人鼓舞。不过,我听说有很多新电脑已经不再支持 BIOS 了(只支持 EFI),因此这会让你的测试直接 “泡汤”。你还是尽量多准备一些旧电脑吧。我们是要保证在旧电脑上有较高的成功率,争取达到不折不扣的 100% 成功率。新电脑是不敢保证的。一方面,新电脑有可能不支持 BIOS,另一方面,即使支持 BIOS,它也可能针对 grub4dos 以及 fbinst 进行新的攻击,这样,我们就不敢保证支持新电脑了。


作者: rgiskard    时间: 2013-12-18 18:46
fbinst兼容性必须增强啊,优盘启动测试必备!!
作者: 不点    时间: 2013-12-23 23:23
初步尝试,开始写代码了。目前的 MBR 扇区代码的主框架已经完成。但后续的工作仍然是很繁琐的。

目前暴露出的问题主要是,MBR 里面的代码空间太少了。

MBR 要放个 BPB,这占用 0x60 个字节。

MBR 还得有分区表,这也要占用 0x48 个字节。

两者合起来占用 0xA8 个字节。

剩下的空间只有 0x158 个字节了。

就是说,512 字节当中,有三分之一的空间被 BPB 和分区表占用,剩下的三分之二,空间太小、太紧张。

因此,有很多概念都得简化。比如说,原来打算要智能地分辨出内嵌的究竟是 grldr 还是 ntldr,现在照顾不了 ntldr 了,只对 grldr 给以直接的支持,而 ntldr 的启动则需要用户用 hack 的手段实现,即,用户自己把 ntldr 的代码进行重新包装,以便让系统能够启动它。


这个 MBR 代码会探测出正确的 H 和 S 值,最后,加载位于物理扇区号 190 开始的 1152 个扇区(也就是 576K)。加载的目的地址是 0x7E00,也就是紧跟 0x7C00 之后的那个扇区位置。加载完成后,控制将跳转到 0000:7E00 去执行。

为什么是 576K 呢?这是最大可能的加载长度,如果再大,就有可能与常规内存顶部的 EBDA 相冲突了。我们假定这 576K 是 grldr 文件的内容。其实,任何代码都可以放在这里,不一定非得是 grldr。

由于 grldr 的内置菜单可以是 LZMA 压缩格式并且带有字库,因此,grldr 的体积可能会很大,用户有可能制作出一个很大的 grldr 文件。而加载一个 576K 的大文件,基本可以满足这方面的需要了。

简言之,这个单扇区的 MBR 代码,在完成 CHS 探测之后,立即加载内嵌的 GRLDR 文件。探测 CHS 的过程类似于 fbinst 的做法,需要 8M 的空间。



作者: 月光海洋    时间: 2013-12-24 09:07
每天都来关注有没有进展…项目开始了就好…
作者: 2011hjcjie    时间: 2013-12-24 15:29
期待更好的工具诞生,支持!
作者: 不点    时间: 2013-12-25 20:56
现在能够在开始的时候打印出 DL 的值了。目前是采用直接写屏显示信息,不采用 BIOS 的 INT10 视频功能调用。

打印 DL 的值之后,等待 3 秒钟,以便用户确实能够看见它。

仔细想想,其实,能够打印出信息,这一点是很重要的。别小看它,这不是一件可以忽略的小事。假如没有信息显示,则当失败情况出现时,用户无法了解其失败的根源,也无法给开发者提供有用的描述。

至于说打印的内容,倒不是很重要。随便打印一个内容便可,只要能够让用户明白,我们的 MBR 代码确实已经成功从 BIOS 那里获得了控制权便可。究竟是获得控制权了?还是没有获得?这是清楚明白的,而不至于模棱两可、说不清楚。走一步是一步,做好记号,让开发、探索的过程透明。

这就像嫦娥登月,开始的时候,先确定能够绕行,然后再尝试落下去。落下去之后,再看看那里有什么新情况。每一步都要扎实可靠。

先前的 fbinst 就做了很好的工作,提供了很多有价值的信息,成为我们进一步发展的良好开端。


这次改进的一个方面,就是要在正式的版本中嵌入调试信息。如果正式版中缺乏必要的、关键的调试信息,那就不方便用户报告问题。

用户遇到问题,不一定有时间、有精力来寻找专门的调试版,甚至也不一定会使用调试版。正式版往往随某个第三方的发行版一起发行,而调试版往往是被忽略的。最终用户因为有了高手们制作的傻瓜化的正式版而很快 “适应” 了,故而甚至他们自己不知道怎么使用调试版。这种情况就造成了调试版与正式版的脱节。

因此,在正式版里面嵌入调试信息,不再单独发行调试版,这是一个很重要的改进。


在道理上澄清这一认识之后,还存在着 “实际可行性” 的问题。

其实这在技术上是有难度的,不容易在狭小的空间里面嵌入很多调试信息。

目前做到了以下几点:

1、打印初始的 DL 信息,并等待 3 秒。

2、用 CHS 模式读逻辑扇区0,从而得知隐藏的扇区数。

3、判断是否支持 LBA 模式。如果支持 LBA 模式,则接下来就使用 LBA 模式来读盘。

4、如果不支持 LBA 模式,则探测 CHS 参数,并用 CHS 模式读盘。

5、可以读取连续多个(比如说1152个)扇区到内存 0x7E00 并递交控制权。

6、在保持 1152 个扇区不记录物理扇区号的情况下,依旧能够完成几何参数的探测。

7、读盘出现失败时,能够显示 “disk fail” 信息。

虽然实现了以上这些功能,但是,0x1A8 字节的代码空间也用光了。而且,这个代码已经进行了充分的优化,很难再通过技术性的手段来节约空间了。然而,这个 “首扇区” 里面的调试信息太少,需要继续塞入其他几个比较关键的调试信息。那就得取消某些功能了。以下两个功能在原则上是可以考虑取消的:

1、取消 LBA 支持功能,这能够节约不少空间。首扇区可以考虑取消 LBA 支持功能,留待第二阶段的次级扇区对这一功能进行增补。
2、取消 1152 个空白扇区的设置,这样会让探测的逻辑更简单,也能够切实减少占用 “首扇区” 里面的宝贵空间。

如果首扇区的打印信息很重要,而且信息又比较多,那可能就得把上述两个功能都取消。目前打算先取消 1152 个空白扇区,然后试试看可否加入足够的调试信息。


作者: 不点    时间: 2013-12-25 21:34
我把楼上所说的阶段性的代码贴出来,一方面是作为一个备份来防止代码丢失,另一方面也许有人对此感兴趣,那就可以帮助开发完善了。目前这个代码还没有取消楼上在结尾处所谈到的 “拥有 1152 空白扇区” 的功能。

这个代码编译完成后,已经抵达偏移 0x1B7 了,也就是说,连一个字节的剩余空间都没有了。从偏移 0x1B8 开始,那是大家熟悉的微软磁盘签名以及分区表。

  1.         .text
  2.         .code16

  3. start:
  4.         jmp        1f

  5.         . = start + 0x02

  6.         .byte        0x90

  7.         . = start + 0x03

  8.         .ascii        "MSWIN4.1"

  9.         . = start + 0x0B

  10.         .word        0x200

  11.         . = start + 0x0D

  12.         /* Sectors per cluster. Valid values are 1, 2, 4, 8, 16, 32, 64 and 128.
  13.          * But a cluster size larger than 32K should not occur.
  14.          */

  15.         .byte        0x01        // sectors per cluster, should be changed by installer

  16.         . = start + 0x0E

  17.         .word        0x0001        // reserved sectors, should be changed by installer

  18.         . = start + 0x10

  19.         .byte        0x02        // number of FATs

  20.         . = start + 0x11

  21.         .word        0        // FAT12/16 root dir entries. Must be 0

  22.         . = start + 0x13

  23.         .word        0        // FAT12/16 total sectors. Must be 0

  24.         . = start + 0x15

  25.         .byte        0xF8        // media descriptor

  26.         . = start + 0x16

  27.         .word        0        // FAT12/16 sectors per FAT. Must be 0

  28.         . = start + 0x18

  29.         .word        0x3f        // sectors per track

  30.         . = start + 0x1A

  31.         .word        0xff        // number of heads

  32.         . = start + 0x1C

  33.         .long        0        // hidden sectors, should be changed by installer

  34.         . = start + 0x20

  35.         .long        0        // total sectors, should be changed by installer

  36.         . = start + 0x24

  37.         .long        0        // sectors per FAT, should be changed by installer

  38.         . = start + 0x28

  39.         .word        0        // current active FAT

  40.         . = start + 0x2A

  41.         .word        0        // FAT32 revision number

  42.         . = start + 0x2C

  43.         .long        0        // root dir starting cluster

  44.         . = start + 0x30

  45.         .word        0        // file system information sector number

  46.         . = start + 0x32

  47.         .word        6        // boot record backup sector number

  48.         . = start + 0x34

  49.         .long        0        // reserved
  50.         .long        0        // reserved
  51.         .long        0        // reserved

  52.         . = start + 0x40

  53.         .byte        0x80        // drive number

  54.         . = start + 0x41

  55.         .byte        0

  56.         . = start + 0x42

  57.         /* Signature (must be 28h or 29h to be recognised by NT). */

  58.         .byte        0x29                // extended boot signature for FAT12/FAT16

  59.         . = start + 0x43

  60.         .long        0x0AC4AF63        // volume serial number

  61.         . = start + 0x47

  62.         .ascii        "NO NAME    "        // volume label, 11 bytes

  63.         . = start + 0x52

  64.         .ascii        "FAT32   "        // filesystem ID, 8 bytes

  65.         . = start + 0x5A

  66.         .word        0        // reserved
  67.         .word        0        // reserved
  68.         .word        0        // reserved

  69.         . = start + 0x60

  70. 1:
  71.         xorw        %di, %di
  72.         movw        %di, %ds        /* constant DS=0 */
  73.         movw        $0x7C00, %bp        /* constant BP=0x7C00 */

  74.         movw        %di, %ss        /* constant SS=0 */
  75.         movw        %bp, %sp

  76.         movb        %dl, 0x40(%bp)        /* assume BIOS pass correct drive number. */

  77.         /* Got control! Print DL on the screen. */
  78.         movw        $0xB800, %bx
  79.         movw        %bx, %es
  80.         xchgw        %ax, %dx        /* DX -> AX */
  81.         /* Undocumented AAM instruction Opcode: D4 imm8 */
  82.         .byte        0xD4, 0x10        // AH= AL / 16, AL= AL % 16
  83.         addw        $0x3030, %ax
  84.         xchgw        %ax, %dx
  85.         movb        %dh, %al
  86.         movb        $0x9F, %ah        # back/fore ground=bright blue/white
  87.         cld
  88.         stosw                        /* DI=2 */
  89.         xchgw        %ax, %dx
  90.         movb        $0x9F, %ah        # back/fore ground=bright blue/white
  91.         stosw                        /* DI=4 */

  92.         /* sleep 3 seconds */

  93.         movw        $55, %cx        /* 55 / 18.2 = 3 seconds */
  94. 1:
  95.         movl        0x46c, %eax        /* get old timer counter */
  96.         sti                        /* enable interrupt for int8 timer */
  97.         cmpl        0x46c, %eax        /* timer counter changed by int8 ? */
  98.         je        1b                /* user will report it if it hangs here */
  99.         loop        1b                /* no change, wait a timer interrupt */

  100.         /* DI=4 */
  101.         //movw        $4, %di                /* try 4 times on read failure */
  102.         movw        %di, 0x18(%bp)        /* set a known value 4: sectors per track */
  103.         movw        %di, 0x1a(%bp)        /* set a known value 4: number of heads */

  104.         pushw        $0x0201        //---        /* BP-2 point to int13/AX: read 1 sector */

  105.         /* read C/H/S=0/0/1 to 0000:7E00 */
  106.         xorw        %ax, %ax
  107.         movw        %ax, %es
  108.         movw        $0x7E00, %bx
  109.         pushw        %es        //---
  110.         pushw        %bx        //---        /* BP-6 point to 0x00007E00 on stack */
  111.         movw        $1, %cx                /* read 1 sector */
  112.         call        readDisk        /* CX=1, DX=0 */

  113.         pushw        0x0E(%bx) //---        /* save sector serial number at BP-8 */

  114.         movb        $0x41, %ah
  115.         movw        $0x55AA, %bx
  116.         call        int13
  117.         jc        1f                /* no ebios */
  118.         subw        $0xAA55, %bx
  119.         jnz        1f                /* no ebios */
  120.         //testb        $1, %cl
  121.         //jz        1f
  122.         .byte        0xD0, 0xD9        // RCR CL,1; D0 C9  ROR CL,1 also OK
  123.         jnc        1f                /* no ebios */

  124.         movb        $0x42, -1(%bp)        /* LBA supported */

  125. geometry_OK:

  126.         /* read GRLDR to 0000:7E00 */
  127.         /* calculate grldr starting sector number */
  128.         /* grldr serial number = (0x28 + 126 + 255*63 - 190) */
  129.         movw        -8(%bp), %ax
  130.         subw        $(0x28 + 126 + (255*63) - 190), %ax
  131.         //cdq                        /* EDX=0 */
  132.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  133.         //xorl        %ecx, %ecx
  134.         movw        $1152, %cx        /* read 576K grldr */
  135.         call        readDisk        /* CX=1152, DX=0 */

  136.         movb        0x40(%bp), %dl
  137.         movb        $0xFF, %dh
  138.         pushw        %dx

  139.         //ljmp        $0, $0x7E00
  140.         pushw        %ds                /* DS=0 */
  141.         pushw        %bx                /* BX=0x7E00 */
  142.         lret
  143. 1:

  144.         /* no LBA */

  145.         /* XXX: should confirm 0x18(%bp)=63, 0x1A(%bp)=255 */

  146.         /* read C/H/S=0/1/1 to 0000:7E00 */
  147.         //xorl        %eax, %eax
  148.         movw        %di, %ax        /* AX=4, start sector number */
  149.         //cdq                        /* EDX=0 */
  150.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  151.         movw        $1, %cx                /* read 1 sector */
  152.         call        readDisk        /* CX=1, DX=0 */

  153.         movw        -8(%bp), %ax
  154.         subw        0x0E(%bx), %ax        /* the real sectors per track */
  155.         pushw        %ax        //---        /* save it at BP-10 */
  156.         pushw        %dx        //---        /* initial 0 at BP-12 */
  157.         //movb        %al, 0x18(%bp)        /* update it! */

  158.         /* read C/H/S=1/0/1 to 0000:7E00 */
  159.         movw        $21, %cx
  160.         xorw        %ax, %ax
  161. 1:
  162.         addw        $(4*4), %ax        /* 16=sectors per cylinder */
  163.         movw        -10(%bp), %dx
  164.         addw        %dx, -12(%bp)
  165.         pushw        %cx
  166.         pushw        %ax
  167.         //cdq                        /* EDX=0 */
  168.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  169.         //xorl        %ecx, %ecx
  170.         movw        %di, %cx        /* read 4 sectors */
  171.         call        readDisk        /* CX=4, DX=0 */

  172.         movw        0x0E(%bx), %ax
  173.         movw        %ax, %cx
  174.         decw        %ax
  175.         cmpw        0x20E(%bx), %ax
  176.         jne        2f
  177.         decw        %ax
  178.         cmpw        0x40E(%bx), %ax
  179.         jne        2f
  180.         decw        %ax
  181.         cmpw        0x60E(%bx), %ax
  182.         jne        2f
  183.         movw        -8(%bp), %ax
  184.         subw        %cx, %ax        /* sectors in cylinders */
  185.         divw        -12(%bp)        /* rem=DX, should be 0 */
  186.                                 /* quo=AX, number of heads */

  187.         /* XXX: if DX != 0, here should halt! */

  188.         movw        %ax, 0x1A(%bp)        /* update number of heads! */
  189.         movb        -12(%bp), %al
  190.         movb        %al, 0x18(%bp)        /* update sectors per track! */
  191.         jmp        geometry_OK        /* ready to load GRLDR */       
  192. 2:
  193.         popw        %ax
  194.         popw        %cx
  195.         loop        1b
  196. 1:
  197.         hlt
  198.         jmp        1b

  199. /* Read sectors from disk, using LBA or CHS
  200. * input:        AX    = 16-bit LBA sector number, and AX <= 0x7FFF
  201. *                CX    = number of sectors to read
  202. *                ES:BX = destination buffer
  203. *                SS    = DS
  204. *                BP+0x18 -> sectors per track
  205. *                BP+0x1A -> number of heads
  206. *                BP+0x40 -> drive number
  207. *
  208. * output:        No return on error
  209. *                BX not changed
  210. *                CX not changed
  211. *                ES    = ES + 0x20 * CX
  212. *                AX    = AX + CX
  213. *                DX    = 0
  214. *                ZF    = 0
  215. *                CF    = 0
  216. */

  217. readDisk:
  218.         cwd                        /* DX=0 */
  219. 2:
  220.         pushaw
  221.         pushw        %dx                /* 0 */
  222.         pushw        %dx                /* 0 */
  223.         pushw        %dx                /* 0 */
  224.         pushw        %ax                /* lo 16bit of sector number */
  225.         pushw        %es                /* buffer segment */
  226.         pushw        %bx                /* buffer offset */
  227.         pushw        $1                /* 1 sector to read */
  228.         pushw        $16                /* size of this parameter block */

  229.         cmpb        $0x42, -1(%bp)        /* LBA supported */
  230.         je        1f                /* LBA mode */

  231.         /* CHS mode */
  232.         divw        0x18(%bp)        /* rem=DX */
  233.                                 /* quo=AX */
  234.                                 /* DH=0 */
  235.         incw        %dx                /* DL=sector number */
  236.         xchgw        %dx, %cx        /* CH=0, CL=sector number */

  237.         cwd                        /* DX=0 */
  238.         divw        0x1A(%bp)        /* rem=DX */
  239.                                 /* quo=AX, cylinder number */
  240.                                 /* DH=0, DL=head number */

  241.         xchgb        %dl, %dh        /* DL=0, DH=head number */
  242.         xchgb        %al, %ch        /* AL=0, CH=lo 8bit cylinder */
  243.         //shlb        $6, %ah                /* hi 2bit cylinder ... */
  244.         //orb        %ah, %cl        /* ... should be in CL */
  245.         shrw        $2, %ax                /* hi 2bit cylinder ... */
  246.         orb        %al, %cl        /* ... should be in CL */
  247.         testb        %ah, %ah
  248.         jnz        disk_error        /* cylinder overflow */
  249. 1:
  250.         movw        -2(%bp), %ax        /* (E)BIOS read 1 sector */
  251.         movw        %sp, %si        /* DS:SI points to disk address packet */
  252.         movb        0x40(%bp), %dl        /* drive number */
  253.         pushw        %es
  254.         call        int13_retry
  255.         popw        %bx
  256.         //jc        disk_error
  257.         leaw        0x20(%bx), %bx
  258.         movw        %bx, %es
  259.         popaw                        /* remove parameter block from stack */
  260.         popaw
  261.         incw         %ax                /* next sector, here ZF=0 */
  262.         loop        2b
  263.         ret

  264. //        . = . - (. - readDisk)/68

  265. int13_retry:
  266.         //movw        $4, %di                /* try 4 times on failure */
  267. 1:
  268.         pushaw
  269.         call        int13
  270.         popaw
  271.         jc        2f
  272.         ret
  273. 2:
  274.         pushaw
  275.         cbw                        /* AH=0, reset disk */
  276.         //xorw        %ax, %ax        /* reset disk */
  277.         call        int13
  278.         popaw
  279.         decw        %di
  280.         jnz        1b

  281. disk_error:

  282.         movw        $(msg_DiskReadError - start + 0x7c00), %si

  283. //boot_error:

  284. /* prints string DS:SI (modifies AX BX SI) */
  285. 1:
  286.         lodsb        (%si), %al        /* get token */
  287.         //xorw        %bx, %bx        /* video page 0 */
  288.         movb        $0x0e, %ah        /* print it */
  289.         int        $0x10                /* via TTY mode */
  290.         cmpb        $0, %al                /* end of string? */
  291.         jne        1b                /* until done */

  292. 1:        jmp        1b


  293. int13:
  294.         pushw        %ds
  295.         pushw        %es
  296. //        pushw        %bx        /* int13/ah=41h use BX, so do not save. */
  297. //        pushw        %dx        /* drive number already saved in memory. */
  298.         pushw        %si
  299.         pushw        %di
  300.         pushw        %bp
  301.         stc
  302.         int        $0x13
  303.         sti
  304.         popw        %bp
  305.         popw        %di
  306.         popw        %si
  307. //        popw        %dx
  308. //        popw        %bx
  309.         popw        %es
  310.         popw        %ds
  311.         ret

  312. msg_DiskReadError:

  313.         .ascii        "disk fail\0"
复制代码



作者: 7112650    时间: 2013-12-26 10:43
巨大的好消息,十分具有穿透力。期待的很。
作者: 不点    时间: 2013-12-27 02:09
这次去掉了 1152 个空白扇区,增加了调试输出信息。

  1.         . = start + 0x60

  2. 1:
  3.         xorw        %di, %di
  4.         movw        %di, %ds        /* constant DS=0 */
  5.         movw        $0x7C00, %bp        /* constant BP=0x7C00 */

  6.         movw        %di, %ss        /* constant SS=0 */
  7.         movw        %bp, %sp

  8.         movb        %dl, 0x40(%bp)        /* assume BIOS pass correct drive number. */

  9.         /* Got control! */

  10.         /* print DX */
  11.         xchgw        %ax, %dx        /* store DX into AX */
  12.         call        print_hex        # BX changed

  13.         /* print serial number of this sector */
  14.         movw        0x0E(%bp), %ax
  15.         call        print_hex        # BX changed

  16.         /* sleep 3 seconds */

  17.         sti                        /* enable interrupt for int8 timer */
  18.         movw        $55, %cx        /* 55 / 18.2 = 3 seconds */
  19. 2:
  20.         movw        0x46c, %ax        /* get new ticks */
  21.         cmpw        %ax, %bx        /* changed? */
  22.         je        2b                /* no, continue to wait */
  23.         /* ticks changed by int8 */
  24.         xchgw        %ax, %bx        /* update ticks */
  25.         loop        2b

  26.         /* CX=0 */

  27.         pushw        $0x0201        //---        /* BP-2 point to int13/AX: read 1 sector */

  28.         /* read C/H/S=0/0/1 to 0000:7E00 */
  29.         /* Generally, it is safe enough. */
  30.         xorw        %ax, %ax
  31.         movw        %ax, %es
  32.         movw        $0x7E00, %bx
  33.         pushw        %es        //---
  34.         pushw        %bx        //---        /* BP-6 point to 0x00007E00 on stack */
  35.         incw        %cx                /* read 1 sector */
  36.         call        readDisk        /* CX=1, DX=0 */

  37.         incw        %cx                /* CX=2 */
  38.         movw        %cx, 0x18(%bp)        /* interim sectors per track */
  39.         movw        %cx, 0x1a(%bp)        /* interim number of heads */

  40.         movw        0x0E(%bx), %si        # mbr0

  41.         /* print serial number of mbr0 */
  42.         movw        %si, %ax
  43.         call        print_hex        # BX changed

  44.         /* check LBA support */
  45.         /* This can also be considered safe. */
  46.         movb        $0x41, %ah
  47.         movw        $0x55AA, %bx
  48.         call        int13
  49.         jc        1f                /* no ebios */
  50.         cmpw        $0xAA55, %bx
  51.         jnz        1f                /* no ebios */
  52.         //testb        $1, %cl
  53.         //jz        1f
  54.         .byte        0xD0, 0xD9        # RCR CL,1; D0 C9  ROR CL,1 also OK
  55.         jnc        1f                /* no ebios */

  56.         movb        $0x42, -1(%bp)        /* LBA supported */

  57.         /* print "AA55" */
  58.         xchgw        %ax, %bx        /* store BX into AX */
  59.         call        print_hex        # BX changed

  60.         jmp        geometry_OK        /* ready to load GRLDR */       

  61. 1:

  62.         /* CHS mode. Must determine geometry. */

  63.         /* read C/H/S=0/1/1 to 0000:7E00 */
  64.         movw        $2, %ax                /* AX=2, interim sectors per track */
  65.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  66.         movw        $1, %cx                /* read 1 sector */
  67.         call        readDisk        # AX=3, CX=1, DX=0

  68.         movw        %si, %ax        # mbr0
  69.         subw        0x0E(%bx), %ax        /* real sectors per track */
  70.         jbe        disk_error        /* installation problem? */
  71.         movw        %ax, 0x18(%bp)        /* update sectors per track! */

  72.         /* print real sectors per track */
  73.         call        print_hex        # BX changed

  74.         cmpw        $63, %ax
  75.         ja        disk_error        /* installation problem? */

  76.         /* read C/H/S=1/0/1 to 0000:7E00 */
  77.         shlw        $1, %ax                /* AX=interim sectors per cylinder */
  78.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  79.         //movw        $1, %cx                /* read 1 sector */
  80.         call        readDisk        # AX=5, CX=1, DX=0

  81.         movw        %si, %ax        # mbr0
  82.         subw        0x0E(%bx), %ax        /* real sectors per cylinder */
  83.         jbe        disk_error        /* installation problem? */

  84.         /* DX=0 */
  85.         divw        0x18(%bp)        /* rem=DX, should be 0 */
  86.                                 /* quo=AX, number of heads */

  87.         /* if DX != 0, stop! */
  88.         testw        %dx, %dx
  89.         jnz        disk_error        /* installation problem? */

  90.         movw        %ax, 0x1A(%bp)        /* update number of heads! */

  91.         /* print real number of heads */
  92.         call        print_hex        # BX changed

  93.         cmpw        $0xFF, %ax
  94.         ja        disk_error        /* installation problem? */

  95. geometry_OK:

  96.         /* read GRLDR to 0000:7E00 */
  97.         /* calculate grldr starting sector number */
  98.         /* grldr serial number = (0x21 + 126 + 255*63 - 190) */
  99.         movw        %si, %ax        # mbr0
  100.         subw        $(0x21 + 126 + (255*63) - 190), %ax
  101.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  102.         movw        $1152, %cx        /* read 576K grldr */
  103.         call        readDisk        /* CX=1152, DX=0 */

  104.         movb        0x40(%bp), %dl
  105.         movb        $0xFF, %dh
  106.         pushw        %dx

  107.         //ljmp        $0, $0x7E00
  108.         pushw        %ds                /* DS=0 */
  109.         pushw        %bx                /* BX=0x7E00 */
  110.         lret

  111. /* Read sectors from disk, using LBA or CHS
  112. * input:        AX    = 16-bit LBA sector number
  113. *                CX    = number of sectors to read
  114. *                AX + CX <= 0x8000
  115. *                ES:BX = destination buffer
  116. *                SS    = DS
  117. *                BP-0x02 -> function call number for AX
  118. *                BP+0x18 -> sectors per track
  119. *                BP+0x1A -> number of heads
  120. *                BP+0x40 -> drive number
  121. *
  122. * output:        No return on error
  123. *                BX not changed
  124. *                CX not changed
  125. *                ES    = ES + 0x20 * CX
  126. *                AX    = AX + CX
  127. *                DX    = 0
  128. *                ZF    = 0
  129. *                CF    = 0
  130. */

  131. readDisk:
  132.         cwd                        /* DX=0 */
  133. 2:
  134.         pushaw
  135.         pushw        %dx                /* 0 */
  136.         pushw        %dx                /* 0 */
  137.         pushw        %dx                /* 0 */
  138.         pushw        %ax                /* lo 16bit of sector number */
  139.         pushw        %es                /* buffer segment */
  140.         pushw        %bx                /* buffer offset */
  141.         pushw        $1                /* 1 sector to read */
  142.         pushw        $16                /* size of this parameter block */

  143.         cmpb        $0x42, -1(%bp)        /* LBA supported */
  144.         je        1f                /* LBA mode */

  145.         /* CHS mode */
  146.         divw        0x18(%bp)        /* rem=DX */
  147.                                 /* quo=AX */
  148.                                 /* DH=0 */
  149.         incw        %dx                /* DL=sector number */
  150.         xchgw        %dx, %cx        /* CH=0, CL=sector number */

  151.         cwd                        /* DX=0 */
  152.         divw        0x1A(%bp)        /* rem=DX */
  153.                                 /* quo=AX, cylinder number */
  154.                                 /* DH=0, DL=head number */

  155.         xchgb        %dl, %dh        /* DL=0, DH=head number */
  156.         xchgb        %al, %ch        /* AL=0, CH=lo 8bit cylinder */
  157.         //shlb        $6, %ah                /* hi 2bit cylinder ... */
  158.         //orb        %ah, %cl        /* ... should be in CL */
  159.         shrw        $2, %ax                /* hi 2bit cylinder ... */
  160.         orb        %al, %cl        /* ... should be in CL */
  161.         testb        %ah, %ah
  162.         jnz        disk_error        /* cylinder overflow */
  163. 1:
  164.         movw        -2(%bp), %ax        /* (E)BIOS read 1 sector */
  165.         movw        %sp, %si        /* DS:SI points to disk address packet */
  166.         //movb        0x40(%bp), %dl        /* drive number */
  167.         pushw        %es
  168.         call        int13_retry
  169.         popw        %bx
  170.         //jc        disk_error
  171.         leaw        0x20(%bx), %bx
  172.         movw        %bx, %es
  173.         popaw                        /* remove parameter block from stack */
  174.         popaw
  175.         incw         %ax                /* next sector, here ZF=0 */
  176.         loop        2b
  177.         ret

  178. //        . = . - (. - readDisk)/68

  179. int13_retry:
  180.         movw        $3, %di                /* try 3 times on failure */
  181. 1:
  182.         pushaw
  183.         call        int13
  184.         popaw
  185.         jc        2f
  186.         ret
  187. 2:
  188.         pushaw
  189.         cbw                        /* AH=0, reset disk */
  190.         //xorw        %ax, %ax        /* reset disk */
  191.         call        int13
  192.         popaw
  193.         decw        %di
  194.         jnz        1b

  195. disk_error:
  196.         //movw        $0xDEAD, %ax
  197.         movw        $0xACCE, %ax        # disk access error
  198.         call        print_hex        # BX changed

  199. 1:        jmp        1b


  200. int13:
  201.         pushw        %ds
  202.         pushw        %es
  203. //        pushw        %bx        /* int13/ah=41h use BX, so do not save. */
  204. //        pushw        %dx        /* drive number already saved in memory. */
  205.         pushw        %si
  206.         pushw        %di
  207.         pushw        %bp
  208.         stc
  209.         movb        0x40(%bp), %dl        /* drive number */
  210.         int        $0x13
  211.         sti
  212.         popw        %bp
  213.         popw        %di
  214.         popw        %si
  215. //        popw        %dx
  216. //        popw        %bx
  217.         popw        %es
  218.         popw        %ds
  219.         ret



  220. print_hex:
  221.         # input                AX = value to print
  222.         #                DI = video text offset
  223.         #
  224.         # output        ES = 0xB800
  225.         #                DF = 0
  226.         #                DI = changed
  227.         #                BX = changed
  228.         pushw        $0xB800
  229.         popw        %es                # text mode video memory

  230.         cld
  231.         pushw        %ax
  232.         pushw        %cx
  233.         pushw        %bx
  234.         movw        $4, %cx
  235.         xchgw        %ax, %bx
  236. 1:
  237.         rol        $4, %bx
  238.         movw        %bx, %ax
  239.         andb        $0x0F, %al
  240.         cmpb        $10, %al
  241.         jb        2f
  242.         addb        $7, %al
  243. 2:
  244.         addb        $0x30, %al
  245.         movb        $0x9F, %ah        # back/fore ground=bright blue/white
  246.         stosw
  247.         loop        1b
  248.         movw        $0x2F20, %ax        # back/fore ground=green/bright white
  249.         stosw
  250.         popw        %bx
  251.         popw        %cx
  252.         popw        %ax
  253.         ret

复制代码


作者: 天使的魔翼    时间: 2013-12-27 15:56
  今天中午花了近一小时时间来学习上述两段代码,由于已经很多年没有继续学习这方面的知识,所以学习起来很吃力;让人感觉不点大师花了很大的精力对代码进行设计,目前正在利用一台本本搭建编译环境,由于工作原因,时间有限,只有利用休息时间进行了。

  再谈点不成熟的想法吧,当初开发WEE的时候,我一直在想有什么实用吗?到最后chenall大大开发出自用的“基于grub4dos的硬盘工具箱”,引导程序WEE+GRUB4DOS,我想不点大师可以考虑直接取消一些高级手工调试功能,或者类似于WEE一样,保留一些基本命令就行了;采取G4D现在发展模式,基本+模块+调用;
  再说一下关于调试部分,可以进一步深化,可以借鉴一些U盘检测工具的做法,在虚拟环境下对U盘进行调试,最方便的做法是:U盘启动到DOS下,运行批处理切换至G4D环境,调用FBINST环境,使用模块化检测U盘是否能适应启动,然后保存至TXT文本,供开发人员检查。
  以上一些想法有些地方不是很成熟,只不过提出一个概念:

      


作者: 不点    时间: 2013-12-27 23:01
又做了一些优化的工作,节约了几个字节。现在比较满意了。

1152 扇区的外部引导器(GRLDR)是含有物理扇区号记录的,因此,还需要在加载 GRLDR 引导扇区之后,进行一些整理。由于已经加载了 1152 个扇区到 0000:7E00 了,因此,这开头的扇区就要负责这些整理工作了。

开头这个扇区,权且当作 MBR “首扇区” 引导器的第二阶段辅助代码吧。就是说,这 1152 个扇区最开头的扇区,是引导器自己的补充、辅助代码。紧接着的下一个扇区,才是外部引导器的开始。也就是说,外部引导器本身只有 1151 个扇区了。如果将来某个时候有人希望增加辅助代码的功能,增加辅助扇区的个数,那只需要(用户或第三方开发者)自己安排辅助扇区数量、代码以及 grldr 的位置便可。两者的总扇区数是不变的,即,1152 个扇区。

目前,我们的目的仅仅是加载 grldr 而已,因此,一个辅助扇区已经绰绰有余了。辅助扇区的功能虽然简单,但是这个工作还是需要做的,不能省略掉。接下来就准备写辅助扇区的代码了。


  1.         . = start + 0x60

  2. 1:
  3.         xorw        %di, %di
  4.         movw        %di, %ds        /* constant DS=0 */
  5.         movw        $0x7C00, %bp        /* constant BP=0x7C00 */

  6.         movw        %di, %ss        /* constant SS=0 */
  7.         movw        %bp, %sp

  8.         /* save DL first */
  9.         movb        %dl, 0x40(%bp)        /* assume BIOS pass correct drive number. */

  10.         /* Got control! */

  11.         /* print DX */
  12.         xchgw        %ax, %dx        /* store DX into AX */
  13.         call        print_hex        # BX changed

  14.         /* print serial number of this sector */
  15.         movw        0x0E(%bp), %ax
  16.         call        print_hex        # BX changed

  17.         /* sleep 3 seconds */

  18.         sti                        /* enable interrupt for int8 timer */
  19.         movw        $55, %cx        /* 55 / 18.2 = 3 seconds */
  20. 2:
  21.         movw        0x46c, %ax        /* get new ticks */
  22.         cmpw        %ax, %bx        /* changed? */
  23.         je        2b                /* no, continue to wait */
  24.         /* ticks changed by int8 */
  25.         xchgw        %ax, %bx        /* update ticks */
  26.         loop        2b

  27.         /* CX=0 */

  28.         pushw        $0x0201        //---        /* BP-2 point to int13/AX: read 1 sector */

  29.         /* read C/H/S=0/0/1 to 0000:7E00 */
  30.         /* Generally, it is safe enough. */
  31.         xorw        %ax, %ax
  32.         movw        %ax, %es
  33.         movw        $0x7E00, %bx
  34.         pushw        %es        //---
  35.         pushw        %bx        //---        /* BP-6 point to 0x00007E00 on stack */
  36.         incw        %cx                /* read 1 sector */
  37.         call        readDisk        /* CX=1, DX=0 */

  38.         pushw        %cx                /* 1, no POP in LBA branch. See below. */
  39.         incw        %cx                /* CX=2 */
  40.         movw        %cx, 0x18(%bp)        /* interim sectors per track */
  41.         movw        %cx, 0x1a(%bp)        /* interim number of heads */
  42.         pushw        %cx                /* 2, no POP in LBA branch. See below. */

  43.         movw        0x0E(%bx), %si        # mbr0

  44.         /* print serial number of mbr0 */
  45.         movw        %si, %ax
  46.         call        print_hex        # BX changed

  47.         /* check LBA support */
  48.         /* This can also be considered safe. */
  49.         movb        $0x41, %ah
  50.         movw        $0x55AA, %bx
  51.         call        int13
  52.         jc        1f                /* no ebios */
  53.         cmpw        $0xAA55, %bx
  54.         jnz        1f                /* no ebios */
  55.         //testb        $1, %cl
  56.         //jz        1f
  57.         .byte        0xD0, 0xD9        # RCR CL,1; D0 C9  ROR CL,1 also OK
  58.         jnc        1f                /* no ebios */

  59.         movb        $0x42, -1(%bp)        /* LBA supported */

  60.         /* print "AA55" */
  61.         xchgw        %ax, %bx        /* store BX into AX */
  62.         call        print_hex        # BX changed

  63.         /* Keep the pushed 1 and 2 on stack without POPs. There is no harm. */
  64.         jmp        geometry_OK        /* ready to load GRLDR */       

  65. 1:

  66.         /* CHS mode. Must determine geometry. */

  67.         /* read C/H/S=0/1/1 to 0000:7E00 */
  68.         //movw        $2, %ax                /* AX=2, interim sectors per track */
  69.         popw        %ax                /* AX=2, interim sectors per track */
  70.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  71.         popw        %cx                /* CX=1, read 1 sector */
  72.         call        readDisk        # AX=3, CX=1, DX=0

  73.         movw        %si, %ax        # mbr0
  74.         subw        0x0E(%bx), %ax        /* real sectors per track */
  75.         jbe        boot_error        /* installation problem? */
  76.         cmpw        $63, %ax
  77.         ja        boot_error        /* installation problem? */

  78.         movw        %ax, 0x18(%bp)        /* update sectors per track! */

  79.         /* print real sectors per track */
  80.         call        print_hex        # BX changed

  81.         /* read C/H/S=1/0/1 to 0000:7E00 */
  82.         shlw        $1, %ax                /* AX=interim sectors per cylinder */
  83.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  84.         //movw        $1, %cx                /* read 1 sector */
  85.         call        readDisk        # AX=5, CX=1, DX=0

  86.         movw        %si, %ax        # mbr0
  87.         subw        0x0E(%bx), %ax        /* real sectors per cylinder */
  88.         jbe        boot_error        /* installation problem? */

  89.         /* DX=0 */
  90.         divw        0x18(%bp)        /* rem=DX, should be 0 */
  91.                                 /* quo=AX, number of heads */

  92.         /* if DX != 0, stop! */
  93.         testw        %dx, %dx
  94.         jnz        boot_error        /* installation problem? */

  95.         movw        %ax, 0x1A(%bp)        /* update number of heads! */

  96.         /* print real number of heads */
  97.         call        print_hex        # BX changed

  98.         testb        %ah, %ah
  99.         jnz        boot_error        /* installation problem? */

  100. geometry_OK:

  101.         /* read GRLDR to 0000:7E00 */
  102.         /* calculate grldr starting sector number */
  103.         /* grldr serial number = (0x21 + 126 + 255*63 - 190) */
  104.         movw        %si, %ax        # mbr0
  105.         subw        $(0x21 + 126 + (255*63) - 190), %ax
  106.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  107.         movw        $1152, %cx        /* read 576K grldr */
  108.         call        readDisk        /* CX=1152, DX=0 */

  109. #if 0
  110.         /* We can do it later in the second stage. */
  111.         movb        0x40(%bp), %dl
  112.         movb        $0xFF, %dh
  113.         pushw        %dx
  114. #endif

  115.         //ljmp        $0, $0x7E00
  116.         pushw        %ds                /* DS=0 */
  117.         pushw        %bx                /* BX=0x7E00 */
  118.         lret

  119. int13_retry:
  120.         movw        $3, %di                /* try 3 times on failure */
  121. 2:
  122.         pushaw
  123.         call        int13
  124.         popaw
  125.         jc        1f
  126.         ret
  127. 1:
  128.         pushaw
  129.         cbw                        /* AH=0, reset disk */
  130.         call        int13
  131.         popaw
  132.         decw        %di
  133.         jnz        2b

  134. disk_error:
  135.         //movw        $0xDEAD, %ax
  136.         movw        $0xACCE, %ax        # disk access error
  137. boot_error:
  138.         call        print_hex        # BX changed
  139. 2:
  140.         jmp        2b

  141. /* Read sectors from disk, using LBA or CHS
  142. * input:        AX    = 16-bit LBA sector number
  143. *                CX    = number of sectors to read
  144. *                AX + CX <= 0x8000
  145. *                ES:BX = destination buffer
  146. *                SS    = DS
  147. *                BP-0x02 -> function call number for AX
  148. *                BP+0x18 -> sectors per track
  149. *                BP+0x1A -> number of heads
  150. *                BP+0x40 -> drive number
  151. *
  152. * output:        No return on error
  153. *                BX not changed
  154. *                CX not changed
  155. *                ES    = ES + 0x20 * CX
  156. *                AX    = AX + CX
  157. *                DX    = 0
  158. *                ZF    = 0
  159. *                CF    = 0
  160. */

  161. readDisk:
  162.         cwd                        /* DX=0 */
  163. 2:
  164.         pushaw
  165.         pushw        %dx                /* 0 */
  166.         pushw        %dx                /* 0 */
  167.         pushw        %dx                /* 0 */
  168.         pushw        %ax                /* lo 16bit of sector number */
  169.         pushw        %es                /* buffer segment */
  170.         pushw        %bx                /* buffer offset */
  171.         pushw        $1                /* 1 sector to read */
  172.         pushw        $16                /* size of this parameter block */

  173.         cmpb        $0x42, -1(%bp)        /* LBA supported */
  174.         je        1f                /* LBA mode */

  175.         /* CHS mode */
  176.         divw        0x18(%bp)        /* rem=DX */
  177.                                 /* quo=AX */
  178.                                 /* DH=0 */
  179.         incw        %dx                /* DL=sector number */
  180.         xchgw        %dx, %cx        /* CH=0, CL=sector number */

  181.         cwd                        /* DX=0 */
  182.         divw        0x1A(%bp)        /* rem=DX */
  183.                                 /* quo=AX, cylinder number */
  184.                                 /* DH=0, DL=head number */

  185.         xchgb        %dl, %dh        /* DL=0, DH=head number */
  186.         xchgb        %al, %ch        /* AL=0, CH=lo 8bit cylinder */
  187. #if 1
  188.         shrw        $2, %ax                /* hi 2bit cylinder ... */
  189.         orb        %al, %cl        /* ... should be in CL */
  190.         testb        %ah, %ah
  191. #else
  192.         /* equivalently, this should also work. */
  193.         rolw        $6, %ax                /* hi 2bit cylinder in AH */
  194.         orb        %ah, %cl        /* put into CL */
  195.         testb        %al, %al
  196. #endif
  197.         jnz        boot_error        /* cylinder overflow */
  198. 1:
  199.         movw        -2(%bp), %ax        /* (E)BIOS read 1 sector */
  200.         movw        %sp, %si        /* DS:SI points to disk address packet */
  201.         //movb        0x40(%bp), %dl        /* drive number */
  202.         pushw        %es
  203.         call        int13_retry
  204.         popw        %bx
  205.         //jc        disk_error
  206.         leaw        0x20(%bx), %bx
  207.         movw        %bx, %es
  208.         popaw                        /* remove parameter block from stack */
  209.         popaw
  210.         incw         %ax                /* next sector, here ZF=0 */
  211.         loop        2b
  212.         ret

  213. //        . = . - (. - readDisk)/68


  214. int13:
  215.         pushw        %ds
  216.         pushw        %es
  217. //        pushw        %bx        /* int13/ah=41h use BX, so do not save. */
  218. //        pushw        %dx        /* drive number already saved in memory. */
  219.         pushw        %si
  220.         pushw        %di
  221.         pushw        %bp
  222.         stc
  223.         movb        0x40(%bp), %dl        /* drive number */
  224.         int        $0x13
  225.         sti
  226.         popw        %bp
  227.         popw        %di
  228.         popw        %si
  229. //        popw        %dx
  230. //        popw        %bx
  231.         popw        %es
  232.         popw        %ds
  233.         ret

  234. print_hex:
  235.         # input                AX = value to print
  236.         #                DI = video text offset
  237.         #
  238.         # output        ES = 0xB800
  239.         #                DF = 0
  240.         #                DI = changed
  241.         #                BX = changed
  242.         pushw        $0xB800
  243.         popw        %es                # text mode video memory

  244.         cld
  245.         pushw        %ax
  246.         pushw        %cx
  247.         pushw        %bx
  248.         movw        $4, %cx
  249.         xchgw        %ax, %bx
  250. 2:
  251.         rolw        $4, %bx
  252.         movw        %bx, %ax
  253.         andb        $0x0F, %al
  254.         cmpb        $10, %al
  255.         jb        1f
  256.         addb        $7, %al
  257. 1:
  258.         addb        $0x30, %al
  259.         movb        $0x9F, %ah        # back/fore ground=bright blue/white
  260.         stosw
  261.         loop        2b
  262.         movw        $0x2F20, %ax        # back/fore ground=green/bright white
  263.         stosw
  264.         popw        %bx
  265.         popw        %cx
  266.         popw        %ax
  267.         ret
复制代码

作者: xyzxp    时间: 2013-12-27 23:45
感谢不点,辛苦了,非常期待!
作者: 詹姆斯草    时间: 2013-12-28 15:09
只能精神上表示支持了, 一无技术,二无能力,三无条件,三无人员呵呵。当然有的是些许的兴趣和些许的时间,但愿能早点见到公测的成品,一定好好试用
作者: 不点    时间: 2013-12-29 05:49
这是第一个测试版,主要目的是测试第一扇区代码是否有毛病。

注意,如果测试成功,屏幕的顶部会显示一些 16 进制的数字。最后一个数字如果是 ACED,则表示测试 OK。

请下载附件,并解压,生成 8M 的映像文件。这个文件是用来克隆到 U 盘的。

请使用 dd 以及类似的克隆软件进行操作。

严重警告!请确保不要写入你的本地硬盘!如果你不懂,请放弃操作!
如果误操作导致硬盘分区丢失,则无法恢复。请谨慎!每一步都要小心!


把 8M.mbr 文件按照扇区写入 U 盘的最开头,覆盖掉 U 盘原来的 MBR 以及分区表。这当然就破坏了 U 盘原有的数据。所以,请选择一个废弃了的 U 盘来操作,比如说,这个 U 盘的容量比较小,这样的 “废盘” 正好可以用来测试。

注意,这个 8M.mbr 自己含有分区表以及 BPB,请原封不动克隆到你的废弃了的 U 盘上。克隆之后,不要在 Windows 下查看 U 盘内容,因为现阶段还没有安排数据分区。另外也担心 Windows 会写入数据破坏已经建立的扇区结构,所以,克隆以后,不要在资源管理器中查看 U 盘的状况。克隆完了之后,你可以拔掉 U 盘,然后插到某个电脑上进行重启测试。

建议先在虚拟机上测试,消除安全隐患。

8M.rar

47.43 KB, 下载次数: 32, 下载积分: 无忧币 -2

试试看,这是第一个测试版。小心哦!别毁了你的硬盘!


作者: cchessbd    时间: 2013-12-29 09:00
本帖最后由 cchessbd 于 2013-12-29 09:02 编辑

关于ud的文件列表,我希望默认采用ANSI格式,而不是UTF-8。
因为用jianliulian的fbinstool回写fba到u盘时,老是采用UTF-8的文件列表。
这样在我接触的两台电脑出错。
不能载入dos启动镜像及pe,居然把2.88m的识别为2000多m了,pe直接没反应。

郁闷了一段时间,因为这个。

其实说这个只是希望不点大师能做好这个。
作者: 不点    时间: 2013-12-29 21:18
本帖最后由 不点 于 2013-12-29 21:37 编辑

报告一个消息,我的 U 盘测试失败了,根本就死机一个,屏幕上任何信息都没有,应该是没能接到控制权。它要是成功了,那就没劲了。失败了正好有活干,可以折腾了。希望通过折腾,让秘密透露得更多一点。

而原来的 fbinst 当然是能够成功启动的。


它死了,可以用 ctrl+alt+del 重启,重启后机器仍然不正常,会死机。死机时,在有些时候,拔掉 U 盘就可以继续启动。

拔掉 U 盘可以继续走,从这个现象,也可分析,BIOS 没有把控制权传过来,而是 BIOS 自己在 “死读” U 盘。

接下来再做一个试验,让 8M 的扇区全都带有引导代码,这次看看能否接管控制。估计依旧不会接管控制的。

可能性最大的,那就是 BPB 表以及分区表的影响了。



作者: pseudo    时间: 2013-12-29 22:58
不点大人早点休息保重身体
有活干时慢慢折腾
就像章回小说,且听下回分解
作者: 假大空    时间: 2013-12-30 15:47
关注一下。就像P大所说的,保重身体,*下回分解。顺便说下,P大文字功底不错哦。
作者: jack95    时间: 2013-12-30 18:22
cchessbd 发表于 2013-12-29 09:00
关于ud的文件列表,我希望默认采用ANSI格式,而不是UTF-8。
因为用jianliulian的fbinstool回写fba到u盘时 ...

fbinst 核心代码读取文件件列表本身并不区分ansi或者utf-8,它是根据beyte对比,只有grldr或者查看文件列表才有编码之分。你启动不了应该是其他问题,为什么不提供详细的信息让大家帮你分析,说不定会发现新的bug或者是你自己pe的问题
作者: pseudo    时间: 2013-12-30 22:47
cchessbd 发表于 2013-12-29 09:00
关于ud的文件列表,我希望默认采用ANSI格式,而不是UTF-8。
因为用jianliulian的fbinstool回写fba到u盘时 ...

cchessbd兄久违,你所用fbinsttool版本可能太旧。
用新版重新强格u盘,重新制作fba应可解决问题。
最新版在ansi、utf-8方面未见问题报告。
作者: 不点    时间: 2013-12-30 22:52
章回小说,来个插曲。

今天 Windows 资源管理器要把我的 U 盘格式化。我同意了。用的是 FAT32 格式。完了之后,重启,我想看看微软的代码可否启动成功。结果,无论如何都是死机。反复插拔、反复折腾,达 10 次之多,都是死机,无任何信息显示。这个情况与我的代码很相似(即前面所提到的失败的测试结果)。

确信微软的代码已经不是 U 盘启动的标准了。而 fbinst 无论是用 FAT16 还是 FAT32,都能成功启动。


作者: shan    时间: 2013-12-31 08:24
怎么看不到大家测试回馈?只有不点大师自己在测试吗?有时间测试,只是不了解原理,看不懂代码。菜啊。建议大师把每次测试包放在顶楼,日期标号,以便大家测试。
作者: cchessbd    时间: 2013-12-31 12:53
本帖最后由 cchessbd 于 2013-12-31 13:18 编辑


pseudo 发表于 2013-12-30 22:47

cchessbd兄久违,你所用fbinsttool版本可能太旧。
用新版重新强格u盘,重新制作fba应可解决问题。
最新 ...


多谢p大也来关注,看来我抓到个小的bug,下次有机会上传个图片看看。

但是我要回家确认下,以免出错。

fbinstool版是1.73m大小,世界末日版本。

fbinstool强制格式化时,文件列表不是fba原来格式.rar

454.88 KB, 下载次数: 25, 下载积分: 无忧币 -2

操作录像


作者: cchessbd    时间: 2013-12-31 12:59
本帖最后由 cchessbd 于 2013-12-31 13:21 编辑
jack95 发表于 2013-12-30 18:22
fbinst 核心代码读取文件件列表本身并不区分ansi或者utf-8,它是根据beyte对比,只有grldr或者查看文件列 ...


很有道理,可能不是fbinst的bug,而是grldr或memdisk的bug。
ud用fbinst强制格式化时选择备份好的fba(备份时fba为ansi菜单),fb菜单由grldr 还有memdisk来引导启动文件。
不过grldr(2013.07.24/2013.11.30都试了)和syslinux(4.03)的出错好像不是一样。

我需要重新确认下,会上传在ud文件列表格式为utf-8时出错的照片。
(手机拍到memdisk出错的了,但是grldr现在又不出错了,我很清楚记得以前出错提示文件大小为 204?Mb。
而且现在不能传到电脑上)
作者: 不点    时间: 2013-12-31 14:43
cchessbd 兄,字符编码的事,与这里的讨论没有太大关系。我觉得没必要在这里讨论。您可以开个新的帖子来专门讨论。

我主要是担心,离题太远的话,将来不利于其他人(包括我自己)查看这里的有关 U 盘启动成功率的技术探讨话题。

我个人目前的打算,不再建立一个类似于 ud 的文件系统,因此,也就不存在编码问题了。

我主要只做一件事,那就是设法提高启动的成功率。只要能达到这个目的,我认为就满意了。

也就是说,我没打算建立一个文件系统。用户把文件放在 8M 以内,是以扇区的形式放进来的,只不过插入了一些 “物理扇区号” 的记录罢了。用户是怎么放进来,就怎么读出。不用建立一个特别的文件系统。至少我目前不考虑这个问题。既然没有文件系统,也就不存在文件名的字符编码问题了。


作者: 不点    时间: 2013-12-31 15:37
又做了一个试验:用 FBinstTool 把 U 盘格式化成 FAT16,然后手动修改第一扇区的分区表,把可见分区的起始扇区 00 40 00 00 改成 3F 00 00 00,当然了,分区长度也做适当调整。然后也相应地调整扇区 63,让它的 BPB 是正确的。经过验证,这样改动后仍然可以成功启动,启动后 U 盘是 (hd0)。

接下来又做了一个测试:把第一扇区添加上 BPB。我原来以为这样启动就要死机,但实际试验时,却成功启动了。在一台联想电脑上,启动后 U 盘是 (fd0);在一台 DELL 机器上,启动后 U 盘是 (hd0)。

看到没有?微软的 XP 对 U 盘进行格式化,也是在第一扇区生成了 BPB。然而在联想的电脑上启动失败死机(DELL 机器没有测试此项功能)。而第一扇区含有分区表的类似结构(即,也含有 BPB),却可以在联想电脑上成功启动为 (fd0)。这暗示,即使是在 MBR 上的 BPB 表起作用的情况下,其上的分区表也仍然是有用的,比如说,主板有可能(事先)对分区表和 BPB 表都进行检查,这检查的过程,一旦遇到异常情况(例如,非法分区表),就会直接死机。


作者: jianliulin    时间: 2013-12-31 20:59
测试反馈:
电脑thinkpad x61,用bootice写8M.mbr到U盘,bios认u盘为hdd,测试成功,屏幕显示:0080 3f60 3f60 aa55 aced

作者: 不点    时间: 2013-12-31 22:22
本帖最后由 不点 于 2013-12-31 23:00 编辑

谢谢 jianliulin 的测试。你的成功,表明了代码本身不含错误。而我的测试失败,则表明没能从 BIOS 那里成功获得控制权。

只要有一例失败,那就是失败。必须与失败的逻辑进行周旋。最后我们的目标就是获得一个相对比较高的成功率。

根据目前的测试情况,我有另外一些想法,通报一下。

我打算 “全权” 管理这个 U 盘。什么意思呢?就是说,这个 U 盘就不要有别的用途了,它只用来启动。由于启动的复杂性,可能需要很变态地设计扇区数据结构,这样的话,就很难保证这个 U 盘的结构仍然能够当作普通 U 盘来存贮数据了。诚然,与启动相关的代码可能仅仅需要开头的若干 M 的空间。但是,由于 BPB 表以及分区表的结构可能需要进行 “变态” 的设计,所以,这就不一定能够当成普通的存储型 U 盘来使用了。用户很可能得采用 “直接扇区读写” 的方法来使用 U 盘上的剩余空间了。这是最坏的打算。如果情况不是特别糟糕,那还是可以保持普通的文件系统访问的。

另外,还有一个 “开源授权协议” 的选用问题。我初步打算采用 Public Domain (公共域)的形式。代码都是全新设计的,我不从别人那里拷贝代码。因此,我可以把代码的授权协议确定为 “公共域”。那些支持开发的协同工作者们,也得明白,代码是要放到 “公共域” 去了。万一有人不同意这样的授权协议,比如说,有人认为这样做吃亏了,那么,他就可以(根据自己的自由意愿)选择不支持本次开发。事先声明这一点,目的是保证支持者不会受到损失,因为这是早早提前声明的,而不是到了很晚才告知的。项目当中有可能内嵌 grldr 等别的软件,那些软件是各自独立的,不受 Public Domain 的控制或约束。


作者: pppfj    时间: 2014-1-1 15:25
看到大师的声明,赶快补习了一下知识:
    公有领域(英语:Public domain)是人类的一部分作品与一部分知识的总汇,可以包括文章、艺术品、音乐、科学理论、发明等等。对于领域内的知识财产,任何个人或团体都不具所有权益。这些知识发明属于公有文化遗产,任何人可以不受限制地使用和加工它们。
作者: 不点    时间: 2014-1-1 15:35
本帖最后由 不点 于 2014-1-1 19:00 编辑

哎呀,真把我害惨了!原来我的测试是成功的!它只是没有显示出信息!

为什么没显示出来呢?那是因为处于图形模式!!直接文本写屏的方法,不适合于图形模式。教训!

要么更改成电传打字视频 BIOS 调用方式,要么先执行切换到 80x25 彩色文本模式。




于是改进了一下,花费了几个字节,增添了切换到 80x25 文本模式的代码。这就不会再黑屏了。

同样地,最后显示出 ACED 就表示 “成功”。

解释一下其他数字的含义:

第一个数字是 DX 寄存器的值,如果是 0000 就表示 U 盘是 “软盘”,如果是 0080 就表示 U 盘是 “硬盘”。

第二个数字表示接管控制的这个引导扇区的物理序列号。序列号如果是 3F60,则表示它就是最开头的扇区。如果是其他值,则表示不是最开头的扇区。每个扇区的物理序列号是按照降序安排的:最开头的扇区,序列号最大(3F60),后续的扇区,物理序列号逐步递降。扇区的物理序列号位于该扇区的偏移 0x0E 处,占用 2 个字节。

第三个数字表示逻辑 MBR 的物理序列号。它通常应该等于刚才所说的这个 “接管控制的引导扇区的物理序列号”。如果不相等,则表示主板有异常。

如果显示的数字中有 AA55 的字样,则表示主板支持 LBA。当主板支持 LBA 时,不进行 CHS 几何参数探测。

如果主板不支持 LBA,则接下来会显示探测到的 S 值,即,每道扇区数;然后显示探测到的 H 值,即,磁头数。

如果发生 BIOS 读盘失败,则会显示 CEDE,表示 “放弃”,然后进入死循环,等待用户按 Ctrl+Alt+Del。

如果一切顺利,最后会显示 ACED,表示 “很棒”,然后进入死循环,等待用户按 Ctrl+Alt+Del。

8M_2.rar

47.44 KB, 下载次数: 29, 下载积分: 无忧币 -2

改进了一下,仍然只是用来测试的


作者: 不点    时间: 2014-1-1 21:05
把改进后的代码贴出来,供查看。

  1. .text

  2.         .code16

  3. start:
  4.         jmp        1f

  5.         . = start + 0x02

  6.         .byte        0x90

  7.         . = start + 0x03

  8.         .ascii        "MSWIN4.1"

  9.         . = start + 0x0B

  10.         .word        0x200

  11.         . = start + 0x0D

  12.         /* Sectors per cluster. Valid values are 1, 2, 4, 8, 16, 32, 64 and 128.
  13.          * But a cluster size larger than 32K should not occur.
  14.          */

  15.         .byte        0x08        // sectors per cluster, should be changed by installer

  16.         . = start + 0x0E

  17.         .word        0x0020        // reserved sectors, should be changed by installer

  18.         . = start + 0x10

  19.         .byte        0x02        // number of FATs(nearly always 2)

  20.         . = start + 0x11

  21.         .word        0        // FAT12/16 root dir entries. Must be 0 for FAT32

  22.         . = start + 0x13

  23.         .word        0        // FAT12/16 total sectors. Must be 0 for FAT32

  24.         . = start + 0x15

  25.         .byte        0xF8        // media descriptor

  26.         . = start + 0x16

  27.         .word        0        // FAT12/16 sectors per FAT. Must be 0 for FAT32

  28.         . = start + 0x18

  29.         .word        0x3f        // sectors per track

  30.         . = start + 0x1A

  31.         .word        0xff        // number of heads

  32.         . = start + 0x1C

  33.         .long        0x3F        // hidden sectors, installer will change it

  34.         . = start + 0x20

  35.         .long        0x00FC0000        // total sectors, installer will change it

  36.         . = start + 0x24

  37.         /* 4-byte FAT32 sectors per FAT, installer will change it */

  38.         /* The byte at offset 0x026 in this entry should never become
  39.          * 0x28 or 0x29 in order to avoid any misinterpretation with the
  40.          * EBPB format under non-FAT32 aware operating systems.
  41.          */

  42.         .byte        0x00, 0x3F, 0x00, 0x00
  43.         //.byte        0x80, 0x00, 0x29, 0x00
  44.         //.long        0

  45.         . = start + 0x28

  46.         .word        0        // current active FAT, installer will change it

  47.         . = start + 0x2A

  48.         .word        0        // FAT32 revision number, installer will change it

  49.         . = start + 0x2C

  50.         .long        2        // root dir starting cluster, installer will change it

  51.         . = start + 0x30

  52.         .word        1        // file system information sector number
  53.                         // installer will change it

  54.         . = start + 0x32

  55.         .word        6        // boot record backup sector number
  56.                         // installer will change it

  57.         . = start + 0x34

  58.         .long        0        // reserved
  59.         .long        0        // reserved
  60.         .long        0        // reserved

  61.         . = start + 0x40

  62.         .byte        0x80        // drive number

  63.         . = start + 0x41

  64.         /* Windows NT use it for CHKDSK flags:
  65.          * Bits 7-2 always cleared;
  66.          * Bit 1: disk I/O errors encountered, possible bad sectors,
  67.                   run surface scan on next boot;
  68.          * Bit 0: volume is "dirty" and was not properly unmounted before
  69.                   shutdown, run CHKDSK on next boot.
  70.          */

  71.         .byte        0        // reserved, should be set to 0 by formating tools.

  72.         . = start + 0x42

  73.         /* Signature (must be 28h or 29h to be recognised by NT). */

  74.         .byte        0x29                // extended boot signature for FAT32

  75.         . = start + 0x43

  76.         /* Originally it was 4-byte volume serial number. */

  77.         /* hi word at offset 0x45 is used for serial number of sector 190 */

  78.         .word        0xAF63                // hour, minutes, seconds

  79.         .word        (0x21 + 126 + (255*63) - 190)        // installer will change it

  80.         . = start + 0x47

  81.         .ascii        "NO NAME    "        // volume label, 11 bytes

  82.         . = start + 0x52

  83.         .ascii        "FAT32   "        // filesystem ID, 8 bytes

  84.         . = start + 0x5A

  85.         .word        0        // reserved
  86.         .word        0        // reserved
  87.         .word        0        // reserved

  88.         . = start + 0x60

  89. 1:
  90.         xorw        %di, %di
  91.         movw        $0x7C00, %bp        /* constant BP=0x7C00 */

  92.         movw        %di, %ss        /* constant SS=0 */
  93.         movw        %bp, %sp

  94.         /* save DL first */
  95.         movb        %dl, 0x40(%bp)        /* assume BIOS pass correct drive number. */

  96.         /* Got control! */

  97.         movw        $0x0003, %ax        /* Must switch to 80x25 color text mode! */
  98.         pushaw
  99.         int        $0x10
  100.         popaw

  101.         movw        %di, %ds        /* constant DS=0 */

  102.         /* print DX */
  103.         xchgw        %ax, %dx        /* store DX into AX */
  104.         call        print_hex        # BX changed

  105.         /* print serial number of this sector */
  106.         movw        0x0E(%bp), %ax
  107.         call        print_hex        # BX changed

  108.         /* sleep 3 seconds */

  109.         sti                        /* enable interrupt for int8 timer */
  110.         movw        $55, %cx        /* 55 / 18.2 = 3 seconds */
  111. 2:
  112.         movw        0x46c, %ax        /* get new ticks */
  113.         cmpw        %ax, %bx        /* changed? */
  114.         je        2b                /* no, continue to wait */
  115.         /* ticks changed by int8 */
  116.         xchgw        %ax, %bx        /* update ticks */
  117.         loop        2b

  118.         /* CX=0 */

  119.         pushw        $0x0201        //---        /* BP-2 point to int13/AX: read 1 sector */

  120.         /* read C/H/S=0/0/1 to 0000:7E00 */
  121.         /* Generally, it is safe enough. */
  122.         xorw        %ax, %ax
  123.         movw        %ax, %es
  124.         movw        $0x7E00, %bx
  125.         pushw        %es        //---
  126.         pushw        %bx        //---        /* BP-6 point to 0x00007E00 on stack */
  127.         incw        %cx                /* read 1 sector */
  128.         call        readDisk        /* CX=1, DX=0 */

  129.         pushw        %cx                /* 1, no POP in LBA branch. See below. */
  130.         incw        %cx                /* CX=2 */
  131.         movw        %cx, 0x18(%bp)        /* interim sectors per track */
  132.         movw        %cx, 0x1a(%bp)        /* interim number of heads */
  133.         pushw        %cx                /* 2, no POP in LBA branch. See below. */

  134.         movw        0x0E(%bx), %si        # mbr0

  135.         /* print serial number of mbr0 */
  136.         movw        %si, %ax
  137.         call        print_hex        # BX changed

  138.         /* check LBA support */
  139.         /* This can also be considered safe. */
  140.         movb        $0x41, %ah
  141.         movw        $0x55AA, %bx
  142.         call        int13
  143.         jc        1f                /* no ebios */
  144.         cmpw        $0xAA55, %bx
  145.         jnz        1f                /* no ebios */
  146.         //testb        $1, %cl
  147.         //jz        1f
  148.         .byte        0xD0, 0xD9        # RCR CL,1; D0 C9  ROR CL,1 also OK
  149.         jnc        1f                /* no ebios */

  150.         movb        $0x42, -1(%bp)        /* LBA supported */

  151.         /* print "AA55" */
  152.         xchgw        %ax, %bx        /* store BX into AX */
  153.         call        print_hex        # BX changed

  154.         /* Keep the pushed 1 and 2 on stack without POPs. There is no harm. */
  155.         jmp        geometry_OK        /* ready to load GRLDR */       

  156. 1:

  157.         /* CHS mode. Must determine geometry. */

  158.         /* read C/H/S=0/1/1 to 0000:7E00 */
  159.         //movw        $2, %ax                /* AX=2, interim sectors per track */
  160.         popw        %ax                /* AX=2, interim sectors per track */
  161.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  162.         popw        %cx                /* CX=1, read 1 sector */
  163.         call        readDisk        # AX=3, CX=1, DX=0

  164.         movw        %si, %ax        # mbr0
  165.         subw        0x0E(%bx), %ax        /* real sectors per track */
  166.         jbe        boot_error        /* installation problem? */
  167.         cmpw        $63, %ax
  168.         ja        boot_error        /* installation problem? */

  169.         movw        %ax, 0x18(%bp)        /* update sectors per track! */

  170.         /* print real sectors per track */
  171.         call        print_hex        # BX changed

  172.         /* read C/H/S=1/0/1 to 0000:7E00 */
  173.         shlw        $1, %ax                /* AX=interim sectors per cylinder */
  174.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  175.         //movw        $1, %cx                /* read 1 sector */
  176.         call        readDisk        # AX=5, CX=1, DX=0

  177.         movw        %si, %ax        # mbr0
  178.         subw        0x0E(%bx), %ax        /* real sectors per cylinder */
  179.         jbe        boot_error        /* installation problem? */

  180.         /* DX=0 */
  181.         divw        0x18(%bp)        /* rem=DX, should be 0 */
  182.                                 /* quo=AX, number of heads */

  183.         /* if DX != 0, stop! */
  184.         testw        %dx, %dx
  185.         jnz        boot_error        /* installation problem? */

  186.         movw        %ax, 0x1A(%bp)        /* update number of heads! */

  187.         /* print real number of heads */
  188.         call        print_hex        # BX changed

  189.         testb        %ah, %ah
  190.         jnz        boot_error        /* installation problem? */

  191. geometry_OK:

  192.         /* read GRLDR to 0000:7E00 */
  193.         /* calculate grldr starting sector number */
  194.         /* grldr serial number = (0x21 + 126 + 255*63 - 190) */
  195.         xchgw        %ax, %si        # AX=mbr0
  196. #if 0
  197.         movw        $(0x21 + 126 + (255*63) - 190), %si
  198. #else
  199.         movw        0x45(%bp), %si
  200. #endif
  201.         subw        %si, %ax
  202.         jbe        boot_error        /* installation problem? */
  203.         lesw        -6(%bp), %bx        /* ES:BX=0000:7E00 */
  204.         movw        $1152, %cx        /* read 576K grldr */
  205.         call        readDisk        /* CX=1152, DX=0 */

  206.         cmpw        %si, 0x0E(%bx)
  207.         jne        boot_error        /* installation problem? */
  208. #if 0
  209.         /* We can do it later in the second stage. */
  210.         movb        0x40(%bp), %dl
  211.         movb        $0xFF, %dh
  212.         pushw        %dx
  213. #endif

  214. #if 1
  215.         movw        $0xACED, %ax        /* OK! passed. */
  216.         jmp        boot_error        /* Test succeeded. Halt. */
  217. #else
  218.         /* jump to stage 2 */
  219.         //ljmp        $0, $0x7E00
  220.         pushw        %ds                /* DS=0 */
  221.         pushw        %bx                /* BX=0x7E00 */
  222.         lret
  223. #endif

  224. int13_retry:
  225.         movw        $3, %di                /* try 3 times on failure */
  226. 2:
  227.         pushaw
  228.         call        int13
  229.         popaw
  230.         jc        1f
  231.         ret
  232. 1:
  233.         pushaw
  234.         cbw                        /* AH=0, reset disk */
  235.         call        int13
  236.         popaw
  237.         decw        %di
  238.         jnz        2b

  239. disk_error:
  240.         //movw        $0xDEAD, %ax
  241.         movw        $0xCEDE, %ax        # disk read error, give up
  242. boot_error:
  243.         call        print_hex        # BX changed
  244. 2:
  245.         jmp        2b

  246. /* Read sectors from disk, using LBA or CHS
  247. * input:        AX    = 16-bit LBA sector number
  248. *                CX    = number of sectors to read
  249. *                AX + CX <= 0x8000
  250. *                ES:BX = destination buffer
  251. *                SS    = DS
  252. *                BP-0x02 -> function call number for AX
  253. *                BP+0x18 -> sectors per track
  254. *                BP+0x1A -> number of heads
  255. *                BP+0x40 -> drive number
  256. *
  257. * output:        No return on error
  258. *                BX not changed
  259. *                CX not changed
  260. *                ES    = ES + 0x20 * CX
  261. *                AX    = AX + CX
  262. *                DX    = 0
  263. *                ZF    = 0
  264. *                CF    = 0
  265. */

  266. readDisk:
  267.         cwd                        /* DX=0 */
  268. 2:
  269.         pushaw
  270.         pushw        %dx                /* 0 */
  271.         pushw        %dx                /* 0 */
  272.         pushw        %dx                /* 0 */
  273.         pushw        %ax                /* lo 16bit of sector number */
  274.         pushw        %es                /* buffer segment */
  275.         pushw        %bx                /* buffer offset */
  276.         pushw        $1                /* 1 sector to read */
  277.         pushw        $16                /* size of this parameter block */

  278.         cmpb        $0x42, -1(%bp)        /* LBA supported */
  279.         je        1f                /* LBA mode */

  280.         /* CHS mode */
  281.         divw        0x18(%bp)        /* rem=DX */
  282.                                 /* quo=AX */
  283.                                 /* DH=0 */
  284.         incw        %dx                /* DL=sector number */
  285.         xchgw        %dx, %cx        /* CH=0, CL=sector number */

  286.         cwd                        /* DX=0 */
  287.         divw        0x1A(%bp)        /* rem=DX */
  288.                                 /* quo=AX, cylinder number */
  289.                                 /* DH=0, DL=head number */

  290.         xchgb        %dl, %dh        /* DL=0, DH=head number */
  291.         xchgb        %al, %ch        /* AL=0, CH=lo 8bit cylinder */
  292. #if 1
  293.         shrw        $2, %ax                /* hi 2bit cylinder ... */
  294.         orb        %al, %cl        /* ... should be in CL */
  295.         testb        %ah, %ah
  296. #else
  297.         /* equivalently, this should also work. */
  298.         rolw        $6, %ax                /* hi 2bit cylinder in AH */
  299.         orb        %ah, %cl        /* put into CL */
  300.         testb        %al, %al
  301. #endif
  302.         jnz        boot_error        /* Cylinder overflow! Stop misreading! */
  303. 1:
  304.         movw        -2(%bp), %ax        /* (E)BIOS read 1 sector */
  305.         movw        %sp, %si        /* DS:SI points to disk address packet */
  306.         //movb        0x40(%bp), %dl        /* drive number */
  307.         pushw        %es
  308.         call        int13_retry
  309.         popw        %bx
  310.         //jc        disk_error
  311.         leaw        0x20(%bx), %bx
  312.         movw        %bx, %es
  313.         popaw                        /* remove parameter block from stack */
  314.         popaw
  315.         incw         %ax                /* next sector, here ZF=0 */
  316.         loop        2b
  317.         ret

  318. //        . = . - (. - readDisk)/68


  319. int13:
  320.         pushw        %ds
  321.         pushw        %es
  322. //        pushw        %bx        /* int13/ah=41h use BX, so do not save. */
  323. //        pushw        %dx        /* drive number already saved in memory. */
  324.         pushw        %si
  325.         pushw        %di
  326.         pushw        %bp
  327.         stc
  328.         movb        0x40(%bp), %dl        /* drive number */
  329.         int        $0x13
  330.         sti
  331.         popw        %bp
  332.         popw        %di
  333.         popw        %si
  334. //        popw        %dx
  335. //        popw        %bx
  336.         popw        %es
  337.         popw        %ds
  338.         ret

  339. print_hex:
  340.         # input                AX = value to print
  341.         #                DI = video text offset
  342.         #
  343.         # output        ES = 0xB800
  344.         #                DF = 0
  345.         #                DI = changed
  346.         #                BX = changed
  347.         pushw        $0xB800
  348.         popw        %es                # text mode video memory

  349.         cld
  350.         pushw        %ax
  351.         pushw        %cx
  352.         pushw        %bx
  353.         movw        $4, %cx
  354.         xchgw        %ax, %bx
  355. 2:
  356.         rolw        $4, %bx
  357. #if 0
  358.         movw        %bx, %ax
  359.         andb        $0x0F, %al
  360.         cmpb        $10, %al
  361.         jb        1f
  362.         addb        $7, %al
  363. 1:
  364.         addb        $0x30, %al
  365.         movb        $0x9F, %ah        # back/fore ground=bright blue/white
  366. #else
  367.         /* this can save 2 bytes of code. */
  368.         movzbw        %bl, %ax        # AH=0
  369.         sahf                        # AF=0
  370.         aaa                        # AAA operation:
  371.                                 // { IF (((AL & 0x0F) > 9) || AF == 1)
  372.                                 //        { AL += 6; AH++ ; AF = CF = 1; }
  373.                                 //   ELSE
  374.                                 //        { AF = CF = 0; }
  375.                                 //   AL &= 0x0F; }
  376.         add        %ah, %al
  377.         .byte        0xD5, 0x10        # AAD imm8 operation:
  378.                                 // { AL += (AH * imm8); AH = 0; }
  379.         addw        $0x1F30, %ax        # back/fore ground=blue/bright white
  380. #endif
  381.         stosw
  382.         loop        2b
  383.         movb        $0x20, %al        # keep colors in AH untouched
  384.         stosw
  385.         popw        %bx
  386.         popw        %cx
  387.         popw        %ax
  388.         ret

  389.         . = start + 0x1B8

  390.         . = start + 0x1BE

  391.         .byte        0x80, 1, 1, 0, 0x0C, 0xFE, 0xFF, 0xFF
  392.         .byte        0x3F, 0, 0, 0, 0x00, 0x00, 0xFC, 0x00

  393.         . = start + 0x1FE

  394.         .word        0xAA55
复制代码


作者: 天使的魔翼    时间: 2014-1-2 19:54
测试标准,用最杂牌的硬件,在不同配置环境下测试。
测试反馈:
主板:ASUS M2N-e  GIGABYTE M52L-S3P   
U盘:SSK 8G(DM8261主控)
挂载硬盘/无硬盘测试
U盘作了量产清零处理,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 ACED

作者: 天使的魔翼    时间: 2014-1-2 21:15
       
电脑型号        海尔 T68 Series 笔记本电脑
操作系统        Windows 7 旗舰版 32位 SP1 ( DirectX 11 )
       
处理器        英特尔 Pentium(奔腾) 双核 T2370 @ 1.73GHz 笔记本处理器
主板        海尔 T68 (英特尔 PM965/GM965/GL960/GS965 - ICH8M 笔记本芯片组)
内存        2 GB ( 威刚 DDR2 667MHz )
主硬盘        富士通 MHY2120BH ( 120 GB / 5400 转/分 )
显卡        Nvidia GeForce 8400M G ( 128 MB / 华硕 )
显示器        奇美 CMO1425 ( 14 英寸 )
光驱        东芝-三星 CDW/DVD TS-L462D 康宝
声卡        瑞昱 ALC660 @ 英特尔 82801H(ICH8) 高保真音频
网卡        瑞昱 RTL8168C(P)/8111C(P) PCI-E Gigabit Ethernet NIC / 华硕
测试反馈:
U盘:SSK 8G(DM8261主控)
挂载硬盘/无硬盘测试
U盘作了量产清零处理,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 ACED
作者: 月光海洋    时间: 2014-1-3 10:15
本帖最后由 月光海洋 于 2014-1-3 10:22 编辑

                             电脑型号
                           NEC LL550/T 笔记本电脑
       
                  操作系统
                        Microsoft Windows 7 旗舰版 32-bit SP1
                处理器
                        Intel Mobile Core 2 Duo P8600 @ 2.40GHz       
                        Penryn 45nm 工艺
                内存
                        2.00 GB 双通道 DDR3 @ 533 兆赫 (7-7-7-20)
                主板
                        NEC AK3M2 (Socket P uFCPGA)       
                图形系统
                        通用即插即用监视器 (1280x800@60Hz)
                        Mobile Intel 4 Series Express Chipset Family
                        Mobile Intel 4 Series Express Chipset Family
                硬盘
                        298 GB ATA FUJITSU MHZ2320B SCSI Disk Device (SATA)       
                        Ricoh Memory Stick Disk Device (IDE)
                光驱
                        HL-DT-ST DVDRAM_GSA-T50N SCSI CdRom Device
                音频
                        Realtek High Definition Audio
测试反馈:
U盘:台电乐威 8G(DM8261主控)
用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,测试结果,屏幕显示:0080 3F60 3F60 AA55 053E


是不是我操作有误!菜鸟参与测试请指点。。。。
作者: 天使的魔翼    时间: 2014-1-3 10:19
本帖最后由 天使的魔翼 于 2014-1-3 10:22 编辑

今天空闲时间连续测试了几台联想电脑,发现都能正常读取U盘信息,并屏显信息。是不是联想支持好一些?
测试反馈:
U盘:SSK 8G(DM8261主控)
挂载硬盘/无硬盘测试
U盘作了量产清零处理,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 ACED




电脑型号        联想 启天M7150 台式电脑
操作系统        Windows 7 旗舰版 32位 SP1 ( DirectX 11 )       
处理器        英特尔 Pentium(奔腾) 双核 E6500 @ 2.93GHz
主板        联想主板 (英特尔 4 Series 芯片组 - ICH7)
内存        1 GB ( 尔必达 DDR3 1067MHz )
       
电脑型号        联想 Product 台式电脑
操作系统        Windows 7 旗舰版 32位 SP1 ( DirectX 11 )
处理器        英特尔 Pentium(奔腾) G630 @ 2.70GHz 双核
主板        联想主板 (英特尔 H61 芯片组)
内存        4 GB ( 记忆科技 DDR3 1333MHz )

电脑型号        联想  台式电脑
操作系统        Windows XP 专业版 32位 SP3 ( DirectX 9.0c )       
处理器        英特尔 Pentium(奔腾) 双核 E2200 @ 2.20GHz
主板        联想主板 (英特尔 P35/G33/G31/P31 Express - ICH7 DH)
内存        2 GB ( 圣创雷克 DDR2 667MHz )

电脑型号        联想 ThinkCentre 7339AL2 台式电脑
操作系统        Windows XP 专业版 32位 SP3 ( DirectX 9.0c )       
处理器        AMD Athlon(速龙) 64 X2 双核 4400+
主板        联想 1.0 (ATI RS690)
内存        1 GB ( 记忆科技 DDR2 800MHz )
作者: 天使的魔翼    时间: 2014-1-3 10:21
以上都是原装系统,硬件未改动过。对另一台品牌电脑进行测试:
U盘:SSK 8G(DM8261主控)
挂载硬盘/无硬盘测试
U盘作了量产清零处理,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 ACED

测试环境:

电脑型号        方正 Founder PC 台式电脑
操作系统        Windows XP 专业版 32位 SP2 ( DirectX 9.0c )       
处理器        AMD Athlon(速龙) II X4 645 四核
主板        富士康 M61PMP-K (Nvidia nForce 430(MCP61))
内存        2 GB ( 金士顿 DDR3 1333MHz )

作者: 天使的魔翼    时间: 2014-1-3 10:28
月光海洋 发表于 2014-1-3 10:15
电脑型号
                           NEC LL550/T 笔记本电脑
       

你的测试前面好像是正确显示了,只是最后的“053E”有问题,这个原因要不点大师来解答,我只不过是协助测试,提供测试环境。
建议你换个U盘试试,我使用DM8261主控的U盘是个废盘,玩坏了也没有什么,我在准备测试之前量产重置过的。

解释一下其他数字的含义:
第一个数字是 DX 寄存器的值,如果是 0000 就表示 U 盘是 “软盘”,如果是 0080 就表示 U 盘是 “硬盘”。
第二个数字表示接管控制的这个引导扇区的物理序列号。序列号如果是 3F60,则表示它就是最开头的扇区。如果是其他值,则表示不是最开头的扇区。每个扇区的物理序列号是按照降序安排的:最开头的扇区,序列号最大(3F60),后续的扇区,物理序列号逐步递降。扇区的物理序列号位于该扇区的偏移 0x0E 处,占用 2 个字节。

第三个数字表示逻辑 MBR 的物理序列号。它通常应该等于刚才所说的这个 “接管控制的引导扇区的物理序列号”。如果不相等,则表示主板有异常。
如果显示的数字中有 AA55 的字样,则表示主板支持 LBA。当主板支持 LBA 时,不进行 CHS 几何参数探测。
如果主板不支持 LBA,则接下来会显示探测到的 S 值,即,每道扇区数;然后显示探测到的 H 值,即,磁头数。

如果发生 BIOS 读盘失败,则会显示 CEDE,表示 “放弃”,然后进入死循环,等待用户按 Ctrl+Alt+Del。

如果一切顺利,最后会显示 ACED,表示 “很棒”,然后进入死循环,等待用户按 Ctrl+Alt+Del。
作者: 天使的魔翼    时间: 2014-1-3 10:33
今天工作不忙,抽空把华硕大部分主板测试了一遍,5个人同时手动,一小时搞定,真很累啊。
U盘:SSK 8G(DM8261主控)
挂载硬盘/无硬盘测试
U盘作了量产清零处理,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 ACED

测试环境:
华硕  Z87系列B75系列B85系列Z77系列H61系列A85X系列970系列760G系列FM2A55系列X79系列FM2+A88X系列990X系列H77系列H81系列990FX系列H87系列FM2+A55系列
作者: 月光海洋    时间: 2014-1-3 10:42
天使的魔翼 发表于 2014-1-3 10:28
你的测试前面好像是正确显示了,只是最后的“053E”有问题,这个原因要不点大师来解答,我只不过是协助测 ...

我没量产过,兄台有量产工具跟教程吗?我看你那个主控和我的一样,这个盘我也是拿来测试的,坏了就不管他。。。
作者: nivigo    时间: 2014-1-3 11:27
虚拟机测试显示 0080 3f60 3f60 aa55 aced ,算不算成功?
作者: mygamexxx    时间: 2014-1-3 12:29
本帖最后由 mygamexxx 于 2014-1-3 12:30 编辑

128M的SD卡用两个不同的读卡器,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,
联想台式机
测试成功,屏幕显示:0080 3F60 3F60 AA55 ACED

明基笔记本(需要一次读一个扇区的明基笔记本)
测试成功,屏幕显示:0000 3F60 3F60 AA55 ACED
不过字符出现过程比联想台式机稍慢
作者: Plantsoot    时间: 2014-1-3 12:32
很久没来论坛了,听J大他们说,不点您再进一步开发fbinst,我估计是底层的东西,我也许帮不上什么忙。
上次我和J大还有群里的几个网友发现fbinst一个重大的bug,在Chenall修改的版本里面,可能没有修正这个BUG,
虽然这个不是底层的内容,但我想还是有必要修正一下,下面是修正后的部分代码:

  1. int
  2. check_space (uchar4 *start, uchar4 size, uchar4 *count,
  3.              uchar4 begin, uchar4 end, int is_ext)
  4. {
  5.     /* 下面一段代码比较难看懂,拆分一下:
  6.         1、begin >= fb_pri_size,就是begin在扩展区的时候,其实只有一种情况:
  7.            不管is_ext = 0 还是 1,都只能在扩展区判断空间大小,这个时候,如果
  8.             (end - begin >= *count) 也就是说,碎片的空间(或者尾部空间)大于
  9.             等于文件大小,就满足存放条件。
  10.         2、如果(end <= fb_pri_size),也就是说,最后一个文件在主分区,这个时候如果
  11.            is_ext = 0 并且 (end - begin >= *count),也就是说主分区内有大于等于
  12.            该文件大小的空间,就分配给他。如果没有返回失败信息 0 ,以便循环继续执行。
  13.         3、如果在碎片中找不到适合的空间,那么这个时候begin等于最后一个文件的下一个位置,
  14.            end等于ud区的总大小,这个时候分两种情况:
  15.            1)begin在主分区,再如果指定导入主分区,主分区 - begin 的空间可以容纳文件,满足条件,
  16.               *start = begin;  如果指定导入扩展区后主分区导入失败,这个时候整个扩展区是空的,
  17.               且大小可以容纳文件,就从扩展区开始的地方写入该文件,*start = fb_pri_size;
  18.            2)begin在扩展区,begin >= fb_pri_size,如果扩展区剩余的空间满足要求,就分配空间,
  19.               (end - begin >= *count),*start = begin;       
  20.    
  21.         BUG分析:如果 begin >= fb_pri_size ,就是说begin已经在扩展区了,而这个时候
  22.                 count = (size + 509) / 510 ,count的值一般情况下是大于真实值的,应该改为
  23.                 *count = (size + 511) >> 9;        再进行 (end - begin) 和 *count 的对比.
  24.                 否则造成,刚删除的文件,再导入,不会占用原来的位置,而是占用更大的位置或者
  25.                 排到最后。
  26.                
  27.        plantsoot @ 2012-1-31   
  28.     */
  29.    
  30.         if (begin >= fb_pri_size) // 修复bug语句,2012-2-1
  31.         {
  32.                 *count = (size + 511) >> 9;
  33.         }                                                  // 修复bug结束
  34.     if ((begin >= fb_pri_size) || (end <= fb_pri_size))        // 如果开始扇区在扩展区,或者end在主分区
  35.     {
  36.                 // 如果 开始扇区位于扩展区或者未指定导入扩展区,并且空闲区域大于等于文件大小
  37.         if (((begin >= fb_pri_size) || (! is_ext)) && (end - begin >= *count))
  38.         {
  39.             *start = begin;        // 那么可以存放文件,返回该空闲空间的起始扇区
  40.             return 1;
  41.         }
  42.     }
  43.     else //((begin < fb_pri_size) and (end > fb_pri_size))
  44.     {        /* 如果未指定导入到扩展区,并且begin在主分区内,当前文件的起始扇区在扩展区
  45.                  * 这个时候不能按  end - begin >= *count 来算,为什么呢?因为文件存放不可以跨区,
  46.                  * 要么主分区,要么扩展区。如果主分区剩余的空间大于等于文件大小,begin位置赋值给start */
  47.         if ((! is_ext) && (fb_pri_size - begin >= *count))
  48.         {
  49.             *start = begin;
  50.             return 1;
  51.         }
  52.                
  53.                 //如果指定了扩展区,begin在主分区内,当前文件的起始扇区在扩展区
  54.         *count = (size + 511) >> 9;                        // 扩展区扇区有效大小是512字节
  55.         if (end - fb_pri_size >= *count)        // 扩展区第一个文件和主分区之间如果有足够大的空间       
  56.         {
  57.             *start = fb_pri_size;
  58.             return 1;
  59.         }
  60.     }

  61.     return 0;
  62. }
复制代码


注释写的不是很严谨,见谅。
作者: Plantsoot    时间: 2014-1-3 12:42
cchessbd 发表于 2013-12-29 09:00
关于ud的文件列表,我希望默认采用ANSI格式,而不是UTF-8。
因为用jianliulian的fbinstool回写fba到u盘时 ...

更换下你的fbinst版本,可以用fbinst修正版,也可以用不才的 fbinst plus。
作者: 月光海洋    时间: 2014-1-3 12:44
本帖最后由 月光海洋 于 2014-1-3 13:24 编辑

268M的SD卡用川宇的读卡器,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,
杂牌组装台式机
测试不成功,屏幕显示:CEDE 3F60 3F60

268M的SD卡用川宇的读卡器,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,
NEC笔记本
测试结果,屏幕显示:0000 3F60 3F60  AA55 053E




作者: 不点    时间: 2014-1-3 16:09
本帖最后由 不点 于 2014-1-15 20:09 编辑

鸟枪换炮,又一个测试版来了。这次是 24M 的,带有 FAT32 分区,用户自己可以在 Windows 资源管理器里面向 U 盘添加 menu.lst 文件。测试期间,最好不要添加别的文件,即不要增加复杂度。【注意:千万不要对这个 U 盘进行格式化操作!格式化的动作,会抹掉我们的测试代码!】

克隆到 U 盘时,要保证 “原封不动”。不要更改任何字节。克隆软件如果提示你保留 U 盘原来的分区表或 BPB,都不要让它保留,而应该直接用我们的映像文件去覆盖。60M 的 U 盘是可以测试的,我已经测试过了。U 盘越大越好。小容量的 U 盘,就没有必要去支持了。所以,请至少使用 60M 容量的 U 盘来测试。

注意,这个版本已经写好了第二阶段的扇区,并且也嵌入了一个第三阶段的 grldr 文件。如果正常,您可以启动到 grub4dos 环境。内置菜单添加了必要的 geometry --lba1sector 命令,用来强制单扇区访问,防止启动时死机。

用户在自己的外部 menu.lst 中可以添加 geometry --lba127sector 命令,来加快 U 盘访问速度。


测试的详细说明:

第一阶段成功之后,不再打印 ACED 标志,而是直接进入第二阶段的程序。

在第二阶段中,您看到 Repeatedly press P to pause... 的信息时,赶快按 P 键,并且连续按(也可以按住不放手),这样可以让程序暂停,以便您能看清屏幕显示的内容。一旦停止按 P 键,grldr 很快就会启动。grldr 就属于 “第三阶段” 了。


请从头至尾看完所有的帖子,了解安装使用的方法、安装时存在的危险,以及屏幕显示信息的解释,等等。小米的路由器是拆开的,需要用户自己组装。我们这个启动工具,目前连名字都没有,也是发烧中的发烧。您能找到这里,是缘分;如果找不到这里,也就不用冒着很大风险来测试这个启动工具了。鼓励但不鼓动;自愿而不强迫。我觉得不适合把测试文件的下载放在 “一楼”,因为 “一楼” 放不下所有这些说明信息,也不能反映发展变化的过程。只有这样,原汁原味,才给人以真实的参与感,而不是经过美化了的 “海市蜃楼” 一样的感觉。一切都在您的掌控之中,您也是脚踏实地的,您是一步一步弄清楚的,这样您就不至于有 “虚无缥缈” 的感觉。希望大家都玩得痛——并快乐着。


附件 24M.img 已于 2014 年 1 月 5 日更新,请重新下载测试。
附件 24M.img 已于 2014 年 1 月 14 日更名为 mbr_24M.img,并修正了内嵌 GRLDR 的一个 bug,请重新下载测试。
2014 年 1 月 15 日更新:再次修复 GRLDR,请测试。


mbr_24M.7z

150 KB, 下载次数: 100, 下载积分: 无忧币 -2

全功能的测试版,轻松愉快地做测试


作者: 月光海洋    时间: 2014-1-3 17:21
本帖最后由 月光海洋 于 2014-1-3 19:16 编辑

                  电脑型号
                           NEC LL550/T 笔记本电脑
       
                  操作系统
                        Microsoft Windows 7 旗舰版 32-bit SP1
                处理器
                        Intel Mobile Core 2 Duo P8600 @ 2.40GHz       
                        Penryn 45nm 工艺
                内存
                        2.00 GB 双通道 DDR3 @ 533 兆赫 (7-7-7-20)
                主板
                        NEC AK3M2 (Socket P uFCPGA)       
                图形系统
                        通用即插即用监视器 (1280x800@60Hz)
                        Mobile Intel 4 Series Express Chipset Family
                        Mobile Intel 4 Series Express Chipset Family
                硬盘
                        298 GB ATA FUJITSU MHZ2320B SCSI Disk Device (SATA)       
                        Ricoh Memory Stick Disk Device (IDE)
                光驱
                        HL-DT-ST DVDRAM_GSA-T50N SCSI CdRom Device
                音频
                        Realtek High Definition Audio
测试反馈:
U盘:台电乐威 8G(DM8261主控)
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 然后顺利进入GRLDR
268M的SD卡用川宇的读卡器
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到SD卡,测试成功,屏幕显示:0000 3F60 3F60 AA55 然后顺利进入GRLDR
作者: 月光海洋    时间: 2014-1-3 17:24
本帖最后由 月光海洋 于 2014-1-3 19:15 编辑

                  电脑型号
                           台式组装电脑
                操作系统
                        Microsoft Windows XP Professional 32-bit SP3
                处理器
                        Intel Celeron 430 @ 1.80GHz       
                        Conroe-L 65nm 工艺
                内存
                        2.00 GB 单通道 DDR3 @ 402 兆赫 (6-6-6-15)
                主板
                        BIOSTAR Group G41D3+ (CPU 1)       
                图形系统
                        MAYA V-151 (1024x768@75Hz)
                        Intel G41 Express Chipset
                硬盘
                        298 GB Western Digital WDC WD3200AAKX-001CA0 (SATA)       
                光驱
                        SONY DVD-ROM DDU1681S
                音频
                        Intel High Definition Audio HDMI Service
测试反馈:
U盘:台电乐威 8G(DM8261主控)
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 然后顺利进入GRLDR
268M的SD卡用川宇的读卡器
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到SD卡,测试不成功,屏幕显示:0000 3F21 3F21  然后就卡在这里,按Ctrl+Alt+Del不能重启,只能热启
作者: 不点    时间: 2014-1-3 19:16
回复 月光海洋:

写入8M_2.img到U盘,测试结果,屏幕显示:0080 3F60 3F60 AA55 053E


这个测试基本是成功的,出了一点小问题。最后读位于 190 处的 1152 个扇区,读出来后,发现其扇区序列号不正确。说明你的安装过程出问题了,你没有把全部的扇区都写入 U 盘,造成扇区序列号错误。



作者: 月光海洋    时间: 2014-1-3 19:18
不点 发表于 2014-1-3 19:16
回复 月光海洋:

是的,我是从63扇区开始写入的,所以出现那样的错误,
作者: 月光海洋    时间: 2014-1-3 19:21
本帖最后由 月光海洋 于 2014-1-3 19:22 编辑

                电脑型号
                        台式组装电脑
                操作系统
                        Microsoft Windows XP Professional 32-bit SP3
                处理器
                        Intel Pentium @ 2.80GHz       
                        Ivy Bridge 22nm 工艺
                内存
                        4.00 GB 单通道 DDR3 @ 665 兆赫 (10-10-10-24)
                主板
                        ECS H61H2-MV (SOCKET 0)       
                图形系统
                        MD195W (1366x768@60Hz)
                        Intel HD Graphics
                硬盘
                        466 GB Western Digital WDC WD5000AAKX-08ERMA0 (SATA)       
                光驱
                        没有检测到光盘驱动器
                音频
                        Realtek High Definition Audio
测试反馈:
U盘:台电乐威 8G(DM8261主控)
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 然后顺利进入GRLDR
268M的SD卡用川宇的读卡器
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到SD卡,测试成功,屏幕显示:0000 3F21 3F21AA55 然后顺利进入GRLDR
作者: 月光海洋    时间: 2014-1-3 19:37
                操作系统
                        Microsoft Windows XP Professional 32-bit SP3
                处理器
                        AMD Sempron X2 180       
                        Regor 45nm 工艺
                内存
                        1.00 GB 单通道 DDR3 @ 535 兆赫 (7-7-7-20)
                主板
                        To be filled by O.E.M. To be filled by O.E.M. (CPU 1)       
                图形系统
                        LCD919 (1280x800@60Hz)
                        128 MBGeForce 6150SE nForce 430 (nVidia)
                硬盘
                        75 GB Maxtor 6 V080E0 SCSI Disk Device (ATA)       
                光驱
                        没有检测到光盘驱动器
                音频
                        VIA High Definition Audio
测试反馈:
U盘:台电乐威 8G(DM8261主控)
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 然后顺利进入GRLDR
268M的SD卡用川宇的读卡器
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到SD卡,测试不成功,屏幕显示:0000 3F21 3F21  然后就卡在这里,按Ctrl+Alt+Del不能重启,只能热启
作者: 不点    时间: 2014-1-3 19:51
谢谢 百草霜 提供的 fbinst 代码补丁。我相信其他 fbinst 开发者看了之后,也会注意修正代码的。

由于目前我已经决定全新开发,所以,我不用太过于关注 fbinst 的代码了。我只需要侧重于了解 fbinst 在实际应用中的表现,作为一个对比资料即可。
作者: 不点    时间: 2014-1-3 20:13
268M的SD卡用川宇的读卡器,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,
杂牌组装台式机
测试不成功,屏幕显示:CEDE 3F60 3F60

268M的SD卡用川宇的读卡器,用BOOTICE-扇区编辑-从文件恢复扇区,写入8M_2.img到U盘,
NEC笔记本
测试结果,屏幕显示:0000 3F60 3F60  AA55 053E


你的诸多此类失败测试,可能都属于写错位置了。你没能写到物理扇区最开头,而是从中间某个地方(例如从偏移 63 处)开始写。


作者: 不点    时间: 2014-1-3 20:26
本帖最后由 不点 于 2014-1-3 21:05 编辑
268M的SD卡用川宇的读卡器
用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到SD卡,测试不成功,屏幕显示:0000 3F21 3F21  然后就卡在这里,按Ctrl+Alt+Del不能重启,只能热启


这个情况值得研究,它死在探测 LBA 支持的时候!这是个新情况,以前我们不曾了解过这一点。哦,想起来了,bean 的 fbinst 就有 chs 模式的开关,说的大概就是不支持 LBA 的情况。

我再去看看 bean 的代码……

【更新】确实,bean 用 --chs 来控制不再探测 LBA 支持。从此分析,我们干脆在这第一阶段放弃探测 LBA 支持,而只用 chs 模式。这样甚至还节约了大量的代码空间。

请等待下一个版本。

评论一下,真是作恶无极限,连探测 LBA 支持与否,都要死机。







作者: 天使的魔翼    时间: 2014-1-3 21:06
不点 发表于 2014-1-3 20:26
这个情况值得研究,它死在探测 LBA 支持的时候!这是个新情况,以前我们不曾了解过这一点。哦,想起来 ...

唉,早来看一下,就不用再花一小时测试60M的了,不过测试中发现一个问题:
所有国产品牌都能直接到到第二阶段,但DELL、HP不能通过,在第一阶段后卡死。
同时测试24M,所有品牌都能顺利测试到最后成功。
作者: 不点    时间: 2014-1-3 21:57
本帖最后由 不点 于 2014-1-5 16:41 编辑

现在这个版本,只是在第一阶段屏蔽掉 LBA 探测。第二阶段没有读盘动作。第三阶段的 grldr 没有改变,仍然是探测 LBA 的。估计第一、二阶段可以顺利通过,但对于不支持 LBA 的主板 BIOS 来说,第三阶段进入 grub4dos 后,在访问 U 盘的时候会死机的。

请从头至尾看完所有的帖子,了解安装使用的方法、安装时存在的危险,以及屏幕显示信息的解释,等等。小米的路由器是拆开的,需要用户自己组装。我们这个启动工具,目前连名字都没有,也是发烧中的发烧。您能找到这里,是缘分;如果找不到这里,也就不用冒着很大风险来测试这个启动工具了。鼓励但不鼓动;自愿而不强迫。

附件 24M_2.img 已于2014年1月5日更新,请重新下载测试。

24M_2.rar

201.35 KB, 下载次数: 67, 下载积分: 无忧币 -2

第一阶段屏蔽掉 LBA,第三阶段未屏蔽 LBA,请测试。


作者: mygamexxx    时间: 2014-1-4 09:17
不点 发表于 2014-1-3 21:57
现在这个版本,只是在第一阶段屏蔽掉 LBA 探测。第二阶段没有读盘动作。第三阶段的 grldr 没有改变,仍然是 ...

128M的SD卡用两个不同的读卡器,用BOOTICE-扇区编辑-从文件恢复扇区,写入24M_2.img到U盘,
联想台式机(实机)
屏幕显示:0080 3F60 3F60 0100 卡死

联想台式机(硬盘测试器虚拟机)
屏幕显示:0080 3F60 3F60 后变为 CEDE 3F60 3F60  卡死
作者: mygamexxx    时间: 2014-1-4 20:31
128M的SD卡用两个不同的读卡器,用BOOTICE-扇区编辑-从文件恢复扇区,写入24M.img到U盘,
联想台式机(实机/虚拟机一样结果)

1.jpg (17.22 KB, 下载次数: 188)

1.jpg

作者: 不点    时间: 2014-1-4 23:18
很抱歉,犯了一个低级错误,导致以前的测试无效。

请大家重新下载 84 楼的 24M.img 进行测试。它是启用 LBA 的。我希望它能够坚持很长时间的考验,直到最后有人发现它是失败的为止。

24M_2.img 是屏蔽掉 LBA 的版本。它作为候补版本。如果有一天 24M.img 被证明失败,那就只好采用 24M_2.img 了。


作者: mygamexxx    时间: 2014-1-5 07:45
联想台式机(硬盘测试器虚拟机)

24.jpg (22 KB, 下载次数: 182)

24.jpg

24_2.jpg (14.21 KB, 下载次数: 202)

24_2.jpg

作者: 不点    时间: 2014-1-5 09:23
本帖最后由 不点 于 2014-1-5 17:04 编辑

很抱歉,程序代码弄好之后,又把尾部的文件弄错了。刚刚又更新了,试试。

8M 的测试文件暂时就不需要了。我们主要是用 24M 的测试文件。

关于 24M 映像文件结构的说明:总扇区数 48481。开头部分是 16193 个扇区(大约 8M),这是带有物理序列号的。每个扇区的物理序列号位于该扇区偏移 0x0E 处。最开头的扇区,其物理序列号是 0x3F60,其后的扇区,其物理序列号逐步递降,到最后一个扇区,其物理序列号为 0x20。然后是不带物理序列号的结尾部分。结尾部分是 FAT32 的文件系统,共 32288 个扇区(保留扇区是 31 个,即 0x1F 个,接着是从 FAT 表直到根目录的扇区),这是与开头部分配合的,用户不可以随意手动替换。这个 FAT32 文件系统的容量是 8G。刚才所说的 32288 个扇区(大约 16M),仅仅是 FAT32 的主框架,不是它的容量。

精细结构描述:

扇区 0 - 扇区 189,共 190 个扇区,填充的是第一阶段的扇区。目的是为了能够捕捉到 BIOS 传递过来的控制。只要屏幕有显示信息,就是捕捉到了控制。第一阶段在完成必要的探测之后,会加载第二阶段和第三阶段的代码到内存 0000:7E00。

扇区 190,共 1 个扇区,是第二阶段的扇区(stage2),它的物理序列号是 0x3EA2。第二阶段接管控制时, CS:IP=0000:7E00。第二阶段的代码首先检查 CPU 寄存器以及内存的数据是否正常,如果有错误,则停机并打印失败信息,让用户了解失败的原因。如果一切正常,则把内存中的第三阶段的 GRLDR 进行整理(即去掉其内嵌的物理序列号);然后打印一条信息,让用户有机会按 P 键暂停。用户松开 P 键,2 秒之后就启动 GRLDR 了。用户每秒按一次 P 键,可保持程序处于暂停状态。GRLDR 取得控制时, CS:IP=0000:8000,DH=0xFF,DL=启动盘的盘号(0 是软盘,0x80 是硬盘);同时,堆栈上也压入了 DX 的值,虽然这对于 GRLDR 来说,没什么用处。

扇区 191 - 扇区 1341,共 1151 个扇区,是第三阶段的扇区(grldr)。注意,它的每个扇区都带有正确的物理序列号。它的物理序列号是从 0x3EA1 (十进制 16033)开始的,逐步递降。grldr 的最后一个扇区的物理序列号是 0x3A23(十进制 14883)。

扇区 1342 - 扇区 16192,共 14851 个扇区(大约 7M),是空白扇区,但每个扇区都带有物理序列号。其最开头的扇区的物理序列号是 0x3A22(十进制 14882),其结尾的扇区的物理序列号是 0x0020(十进制 32)。空白扇区是用户可以使用的。当然了,用户不可以破坏扇区的物理序列号,要保持正确的物理序列号。用户可能需要在自己的 menu.lst 菜单中添加自己的特殊工具,才能使用空白扇区上的数据。

扇区 16193 - 扇区 48480,共 32288 个扇区(大约 16M),是 FAT32 的分区结构数据。目前是固定的,用户不可以随意修改。其开头的 31 个扇区(0x1F 个扇区)是保留扇区数,紧接着是两份 FAT 表,每一份占用 0x3F00 个扇区,两份共占用 0x7E00 个扇区。最后剩下一个扇区,就是 FAT32 根目录的数据。31 + 0x7E00 + 1 = 32288。

用户可以在 Windows 资源管理器中,向 FAT32 分区拷贝文件。建议首先拷贝 menu.lst 文件。menu.lst 文件的开头(也或者在某个 title 之后),可以添加一条 geometry --lba127sector 命令,来加快 U 盘的读取速度。默认的 grldr 的内置菜单,已经用 geometry --lba1sector 屏蔽掉 U 盘的多扇区读取功能。要知道,对于变态的主板,geometry 命令的 --lba127sector 参数会引起死机。


以上这些信息(位置、长度、序列号,等),将来还可能发生变动。根据大家的测试情况,将来为了应付变态的 BIOS,我们有可能被迫改变上述数据结构。

作者: 月光海洋    时间: 2014-1-5 10:17
本帖最后由 月光海洋 于 2014-1-5 10:19 编辑

NEC LL550/T   笔记本电脑
主板          NEC AK3M2 (Socket P uFCPGA)

测试反馈:
U盘:台电乐威 8G(DM8261主控)
用BOOTICE-扇区编辑-从文件恢复扇区,写入今早上刚不点更新的84楼24M.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 然后顺利进入GRLDR
268M的SD卡用川宇的读卡器
用BOOTICE-扇区编辑-从文件恢复扇区,写入今早上刚不点更新的84楼24M.img到SD卡,测试成功,屏幕显示:0000 3F60 3F60 AA55 然后顺利进入GRLDR


台式组装电脑
主板           BIOSTAR Group G41D3+ (CPU 1)  
测试反馈:
U盘:台电乐威 8G(DM8261主控)
用BOOTICE-扇区编辑-从文件恢复扇区,写入今早上刚不点更新的84楼24M.img到U盘,测试成功,屏幕显示:0080 3F60 3F60 AA55 然后顺利进入GRLDR    进入较慢
268M的SD卡用川宇的读卡器
用BOOTICE-扇区编辑-从文件恢复扇区,写入今早上刚不点更新的84楼24M.img到SD卡,测试成功,屏幕显示:0000 3F21 3F21 003F 00FF 然后顺利进入GRLDR    进入较慢

作者: 不点    时间: 2014-1-5 11:52
月光海洋的测试情况很好。

显示 AA55 的,表示支持 LBA,这样也就不需要探测几何参数了。

最后的一个情况是不支持 LBA 的,它的 S=63,H=255,很不错。它的 MBR 的扇区号是 3F21,距离开头的 3F60 刚好是 63 个扇区,说明它隐藏了 63 个扇区(即,隐藏了一个磁道)。它是以软盘 00 启动的。






欢迎光临 无忧启动论坛 (http://wuyou.net/) Powered by Discuz! X3.3