无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
楼主: zhaohj
打印 上一主题 下一主题

GRUB4DOS更新建议、bug反馈专帖

    [复制链接]
2011#
发表于 2011-12-20 12:49:17 | 只看该作者
一个简单办法,菜单开头弄个特征串以便搜索定位
回复

使用道具 举报

2012#
发表于 2011-12-20 15:37:50 | 只看该作者

回复 #2015 pseudo 的帖子

Grldr EDITor和bootice、fbinsttool等工具都能准确定位各版本grldr原始的或已编辑过的内置菜单的起始地址,请P大明示这些程序是怎么识别这个内置菜单起始地址的?

[ 本帖最后由 chiannet 于 2011-12-20 15:39 编辑 ]
回复

使用道具 举报

2013#
发表于 2011-12-20 17:38:31 | 只看该作者

Grub4DOS U盘

@chenall

我的电脑相关配置信息:

CPU:Intel E5300 2.60GHz
主板:技嘉 G41MT-ES2L
内存:2G DDR3 1333MHz
硬盘:西数 500G
显卡:NVIDIA GT240

我的U盘品牌及型号:

宇瞻 钢铁侠 AH321

容量为:8G

问题描述:之前用的时候,没出现过这样的问题,现在U盘貌似不能被Grub4Dos 2011-12-13 正常访问了。
我U盘量产成 一个CDROM + 一个可用分区,之前我也是这样用的,没出现过像今天这种问题。



下图,此时已经定住了。(角度一)






下图,此时已经定住了。(角度二)








下图是U盘拨掉之后的效果:

在拨U盘之前仍然是定住的状态,按了三下Tab键 无果。拨掉U盘后,我刚才操作过的Tab就出现了。





请问这是什么怪问题?
回复

使用道具 举报

2014#
发表于 2011-12-20 18:45:45 | 只看该作者

回复 #2017 tea1111980 的帖子

抱歉,我觉得这是你自己的问题。为什么呢?因为你自己没能把这个 U 盘插在别的电脑上试验。你只要大量试验,你自己就知道是什么原因了,几乎不用来这里询问,只有极少数情况需要他人的帮助。
回复

使用道具 举报

2015#
发表于 2011-12-21 00:37:43 | 只看该作者

回复 #2016 chiannet 的帖子

据说bootice是参考grubmenu源码来判定grldr内置菜单偏移的。
回复

使用道具 举报

2016#
发表于 2011-12-21 07:15:15 | 只看该作者

回复 #2019 pseudo 的帖子

有两种方法确定 grldr 内置菜单的起始位置。

其一,采用搜索的方法。搜索到十六进制的四字节 B0 02 1A CE ,紧接它后面有 12 个字节是未使用的(目前是 00),然后再接下来就是内置菜单了。搜索可以从后往前,也可以从文件开头向后,但最好是从后向前搜索,以免碰巧有多个匹配的 B0 02 1A CE 存在,造成判断错误。

其二,采用计算的方法,这个方法避免了搜索。在 GRLDR 偏移 0x206C 处有四个字节的整数,它指示了 B0 02 1A CE 的位置。比如说,当偏移 0x206C 处的值是 0x00048AD4 的时候,B0 02 1A CE 就位于 GRLDR 的偏移 0x428D4 处。这里有个固定的差值:0x00048AD4 - 0x428D4 = 0x6200,这个差值 0x6200 是固定的,永远不会改变。进一步具体解释这个 0x6200 的意义,它又是 0x8200 - 0x2000 的差值。前者 0x8200 是 grldr 的主体代码 pre_stage2 被加载到的内存地址,后者 0x2000 是 GRLDR 头部的大小(即 8K,或者说是 16 扇区)。

有了固定的差值 0x6200,那么就很容易从偏移 0x206C 处的值 0x00048AD4 计算出 B0 02 1A CE 的位置。把 0x00048AD4 减去 0x6200 就得到 0x428D4,这就是 B0 02 1A CE 在 GRLDR 中的偏移位置。找到了 B0 02 1A CE 的位置,再加上 16,就得到内置菜单的位置了。因此,内置菜单位于偏移 0x428D4 + 0x10 = 0x428E4 处。

=========

上述两种方法,对于确定 GRUB.EXE 的内置菜单的位置,也是有帮助的。第一种 “搜索法”完全可以用于确定 GRUB.EXE 的内置菜单的位置。第二种 “计算法”则需要作少量改动,因为 GRLDR 的头部长度是固定的 0x2000,而 GRUB.EXE 的头部长度是可变的。GRUB.EXE 的头部长度记录在偏移 0x1F0 处。GRUB.EXE 的偏移 0x1F0 处的一个 “字节”的值(注意只有一个字节,不是 2 字节,也不是 4 字节),它就表示 GRUB.EXE 的头部所占用的扇区数(注意是 512 字节的扇区数)。至于说如何计算内置菜单的偏移,大家可以自己摸索,这里不再说了。

[ 本帖最后由 不点 于 2011-12-21 07:30 编辑 ]
回复

使用道具 举报

2017#
发表于 2011-12-21 07:21:40 | 只看该作者

回复 #2020 不点 的帖子

嚯嚯,好复杂。我硬着头皮试试。


不点大,根据您的解释,应该就是这样子的吗?

1、读取 0x206C的四个字节的整数0xyyyyyyyy

2、0xyyyyyyyy-0x61F0 就是grldr内置菜单偏移地址。

[ 本帖最后由 chiannet 于 2011-12-21 07:29 编辑 ]
回复

使用道具 举报

2018#
发表于 2011-12-21 08:10:51 | 只看该作者

回复 #2021 chiannet 的帖子

对的。另外,你的用词非常漂亮:“硬着头皮”。很多人 “硬着头皮” 学习了 grub4dos,结果,进来以后发现,学习也并不困难。
回复

使用道具 举报

2019#
发表于 2011-12-21 08:58:38 | 只看该作者

回复 #2018 不点 的帖子

我已经试了很多机子了,都是这样的,连我自己家里的那台刚配的电脑也试了,也是这样的情况 。
但是我用以前较现在这个最新的旧一点版本的GRUB4DOS 可以用。

[ 本帖最后由 tea1111980 于 2011-12-21 09:25 编辑 ]
回复

使用道具 举报

2020#
发表于 2011-12-21 10:20:50 | 只看该作者

回复 #2020 不点 的帖子

我来总结一下:
1.grldr=grldr头部(固定长度0x2000)+pre_stage2
GRUB.EXE =GRUB.EXE 头部(长度记录在GRUB.EXE 的头部占用扇区数记录在偏移 0x1F0 处一个 “字节”)+pre_stage2

2.pre_stage2固定加载到内存地址0x8200.
  pre_stage2偏移0x6C 处四个字节即B0 02 1A CE 在内存中的位置。
  "B0 02 1A CE"及后面的00共占用0x10字节,之后即为内置菜单。

其它就不说了。

[ 本帖最后由 zxw 于 2011-12-21 10:35 编辑 ]
回复

使用道具 举报

2021#
发表于 2011-12-21 12:02:18 | 只看该作者

回复 #2024 zxw 的帖子

你这样说,就完整了。
回复

使用道具 举报

2022#
发表于 2011-12-21 12:12:47 | 只看该作者
原帖由 tea1111980 于 2011-12-21 08:58 发表
我已经试了很多机子了,都是这样的,连我自己家里的那台刚配的电脑也试了,也是这样的情况 。
但是我用以前较现在这个最新的旧一点版本的GRUB4DOS 可以用。


你需要澄清,究竟什么时候的版本可以用,什么时候开始出问题,以便 chenall 很容易地找到首次引入 bug 的版本。

看到你是在访问分区的时候死掉了,而且是 “假死”。这不像是 grub4dos 的 bug。更像是 BIOS 访问 U 盘出现的问题(访问大扇区号时死掉了,或者假死了)。也许你的 U 盘上的分区格式出了问题?总之,可能性很多。
回复

使用道具 举报

2023#
发表于 2011-12-23 08:31:02 | 只看该作者

回复 #2025 不点 的帖子

  1. procedure grldr2skype;
  2. var
  3. ct: Char;
  4. itm:integer;
  5. stm,sorcepath:string;
  6. a,b: TMemoryStream;

  7. begin
  8. sorcepath:=ExtractFilepath(Application.ExeName);
  9. a:=TMemoryStream.Create;

  10. //读取grldr到a
  11. if fileexists(sorcepath+'grldr') then
  12.     a.LoadFromFile(sorcepath+'grldr')
  13.   else  begin
  14.           showmessage('请将GRLDR至于当前目录之下');
  15.           Application.Terminate;
  16.           exit;
  17.         end;


  18. // 以下是为了改名grldr为SKYPE,将其中的“GRLDR”/“grldr”字符串更改为“SKYPE”/“skype”。
  19. a.Position :=0;
  20. while a.Position <= a.Size-5 do
  21. begin
  22. a.Read(ct,1);
  23. if (ct='G') or (ct='g') then
  24.     begin
  25.     a.Read(ct,1);
  26.     if (ct='R') or (ct='r') then
  27.        begin
  28.        a.Read(ct,1);
  29.        if (ct='L') or (ct='l') then
  30.            begin
  31.            a.Read(ct,1);
  32.            if (ct='D') or (ct='d') then
  33.                begin
  34.                a.Read(ct,1);
  35.                if (ct='R') or (ct='r') then
  36.                    begin
  37.                          a.Position:=a.Position-5;
  38.                          if ct='R' then a.Write('SKYPE',5) else a.Write('skype',5);
  39.                          a.Position:=a.Position+5;
  40. end;end;end;end;end;end;


  41. //以下替换原内置菜单的内容
  42. stm:='';
  43. a.Position :=$206C;
  44. for itm:=1 to 4 do
  45.   begin
  46.     a.Read(ct,1);
  47.     stm:=inttohex(Byte(ct),2)+stm;
  48.   end;
  49. a.Position:=0;
  50. b.CopyFrom(a,StrToInt('$'+stm)-$61F0);
  51. a.Clear;
  52. FORM1.grldrhdd.Lines.SaveToStream(a);  
  53. //FORM1.grldrhdd是一个TMemo,其中的内容是新的即将追加到grldr的菜单内容
  54. b.CopyFrom(a, 0);
  55. b.SaveToFile(sorcepath+'skype');   //保存为文件skype
  56. a.free;
  57. b.Free;

  58. end;
复制代码
前天搞成了。代码木有技术含量,老大莫笑话。

作为G4d使用者,在这里对不点chenall  zxw 等等老大的辛勤付出致以敬意。


刚才修改了一下
字符串grldr更改为skype这个过程,这样子性能应该高些。

[ 本帖最后由 chiannet 于 2011-12-23 11:59 编辑 ]
回复

使用道具 举报

2024#
发表于 2011-12-23 21:40:17 | 只看该作者
原帖由 于 2011-12-23 08:31 发表
procedure grldr2skype;
var
ct: Char;
itm:integer;
stm,sorcepath:string;
a,b: TMemoryStream;

begin
sorcepath:=ExtractFilepath(Application.ExeName);
a:=TMemoryStream.Create;

//读取grld ...

chiannet 大,这个是怎么用的呢?有没有个具体的说明?
回复

使用道具 举报

2025#
发表于 2011-12-24 09:04:36 | 只看该作者

怎么find还是有问题

看图:UD中只有grldr其他文件全部放可见区,默认内置菜单不变。find看不到其他盘。默认内置菜单也搜不到可见区的menu.lst

IMG_3032.gif (158.44 KB, 下载次数: 130)

IMG_3032.gif
回复

使用道具 举报

2026#
发表于 2011-12-24 09:55:41 | 只看该作者
可见区成了 (fd0,0),属于 “软盘分区”。也许正是因为这个,所以没能找到。让 chenall 看看吧,应该可以改进 find 命令。

忽然想到,你的 BIOS 数据区里面的 “软盘个数” 可能是 0,所以,find 命令不去查找软盘。这是你的 BIOS 的 bug。

chenall 看看应该采取什么 workaround 吧。

[ 本帖最后由 不点 于 2011-12-24 10:00 编辑 ]
回复

使用道具 举报

2027#
发表于 2011-12-24 22:18:23 | 只看该作者

回复 #2030 不点 的帖子

我在默认菜单
        if "%@root:~1,2%"=="fd" find --set-root --ignore-cd /menu.lst && configfile /menu.lst 后面了如下一句可以找到可见区的菜单了。

       if %?_BOOT%==(ud) configfile (fd0,0)/menu.lst

查找菜单应该是当前盘根下最优先,没找到就按一个固定的顺序去找。
如下从UD启动,新的版本,当前盘为UD区,那么应该就是:UD区-->可见区-->硬盘其他盘等。如果可见区识别为hd,因为是从U盘启动的一般就会占据hd0,这个默认菜单不会有问题,但另外有两种情形,识别为fd0或fd0,0,这可能就会硬盘优先,看来这两句可能要再往前放:

errorcheck off
configfile /menu.lst || configfile /MENU.LST
configfile /boot/grub/menu.lst || configfile /BOOT/GRUB/MENU.LST
configfile /grub/menu.lst || configfile /GRUB/MENU.LST
if "%@root:~1,2%"=="fd" find --set-root --ignore-cd /menu.lst && configfile /menu.lst
if %?_BOOT%==(ud) configfile (fd0,0)/menu.lst
find --set-root --ignore-floppies --ignore-cd /menu.lst && configfile /menu.lst
find --set-root --ignore-floppies --ignore-cd /boot/grub/menu.lst && configfile /boot/grub/menu.lst
find --set-root --ignore-floppies --ignore-cd /grub/menu.lst && configfile /grub/menu.lst
。。。。。

大家有何高见?最好有检测是否出现fd0,0的机制。

[ 本帖最后由 hhh333 于 2011-12-24 22:56 编辑 ]
回复

使用道具 举报

2028#
发表于 2011-12-24 23:20:36 | 只看该作者

回复 #2031 hhh333 的帖子

这个治标不治本,而且不通用。
你可以启动之后用find命令看看能不能找到你的可见区。一般情况下都是可以找到的。
回复

使用道具 举报

2029#
发表于 2011-12-25 09:20:52 | 只看该作者

回复 #2030 不点 的帖子

很早就发现,对于ZIP盘,某些机,用find查找就找不到(fd0),(fd0,0) 经测试,这类BIOS。会虚拟一个不存在的(fd0)。
 如果加上map --floppies=1就正常了。
 而且在使用中发现find命令有时很“弱智”。
 比如:
 在加载plbpt后,如果是zip,则会变成HDD。原来的(fd0)变成了(hd0),原来的硬盘(hd0),变成了(hd1).这时,用find就找不到(hd1)的所有分区。但如果进行磁盘交换,map (hd0)  (hd1) && map (hd1) (hd0) && map --hook 就可以找到了。或者root (hd1,0),用find也可以找到该分区中的文件。
  同理,如果是hdd,则原(hd0)仍为(hd0),原硬盘(hd1)丢失,变成了(hd2),用find也找不到(hd2)的分区及文件。

  不明白find的工作原理,能不能修改find,使其智能一点?因为这是一个使用最频繁的命令,特别在批处理中经常使用,一旦找不到就会出错。
回复

使用道具 举报

2030#
发表于 2011-12-25 09:57:40 | 只看该作者

回复 #2033 幸运的草 的帖子

>>> 如果加上map --floppies=1就正常了。

你这一句,就把问题的症结搞定了。是 BIOS 的 “ 疏忽大意 ”,它没能把软盘个数设定为 1,而是设定为 0 了。执行 map --floppies=1 就是帮助 BIOS 纠正错误,即,设定正确的软盘个数 1。

这个问题其实并不简单,它很 “ 深奥 ”。

如果 BIOS 指示没有软盘(软盘个数为0),而程序试图访问软盘,则有可能死机。这死机就是 BIOS 故意制造的,它可能是想封杀某个开源软件,例如 GRUB、SYSLINUX 等。也有可能 “ 假死 ”,即,访问软盘的动作,持续几分钟以后给出失败信息,活过来,解除了假死状态。不管假死还是真死,都是 BIOS 硬件封杀开源软件的步骤。所以,我们的程序也不敢随便访问软盘,尤其是在内置菜单中自动访问软盘,那肯定很危险,那会导致在启动的时候就死机,用户会认为是 grub4dos 这个软件很 “ 垃圾 ” 的原因,把一切错误归咎于 grub4dos。只要 BIOS 数据区指示没有软盘,那么我们就不再访问软盘。find 命令没有错,它就是按照这个设计来 “ 行动 ” 的。

但在上述特殊情况,虽然 BIOS 指示 “不存在软盘”,但实际上 ud 却是在 (fd0) 上。这就表示,访问软盘不会造成死机。此时可以放心地访问软盘。因此,此时可以设定 map --floppies=1。

grub4dos 仍有改进的空间,就是,当发现 ud 是在软盘上而且软盘个数为 0 的时候,自动设定软盘个数为 1 个。

这个问题就由 chenall 来处理了。
回复

使用道具 举报

2031#
发表于 2011-12-25 10:53:30 | 只看该作者

回复 #2033 幸运的草 的帖子

 在加载plbpt后,如果是zip,则会变成HDD。原来的(fd0)变成了(hd0),原来的硬盘(hd0),变成了(hd1).这时,用find就找不到(hd1)的所有分区。但如果进行磁盘交换,map (hd0)  (hd1) && map (hd1) (hd0) && map --hook 就可以找到了。或者root (hd1,0),用find也可以找到该分区中的文件。


这你就不要归罪于 grub4dos 了。那是 plbpt 的问题。它在更改了软盘和硬盘个数以后,没能把更改后的软盘硬盘个数更新到 BIOS 数据区。可以给 plpbt 的开发者写信,让他们解决。find 命令没有错,它不会擅自访问一个可能不存在的硬盘 (hd1),因为 plpbt 的 BIOS 数据区中仍旧指示只有 1 个硬盘,它应该指示有 2 个硬盘才对。在这种情况,你可以为 plpbt “ 擦屁股 ”(抱歉,这话比较粗鲁,但很传神):用 map --harddrives=2 来补救。根本的原因在 plpbt 这个软件,请它的开发者解决。假如它是开源的,我们或许可以直接给它打补丁,但遗憾的是,它不是开源的,我们毫无办法。

  同理,如果是hdd,则原(hd0)仍为(hd0),原硬盘(hd1)丢失,变成了(hd2),用find也找不到(hd2)的分区及文件。


这仍然暴露出 plpbt 的问题了。它把硬盘 (hd1) 映射为 (hd2),然后就什么也不管了。你还得用 grub4dos 的命令为它 “ 擦屁股 ”:map (hd2) (hd1),即,把 (hd2) 重新映射回来,变成 (hd1)。可能还需要设定 map --harddrives=2。

从我个人的观点,我不鼓励采用 plpbt 这个软件。我的观点简单介绍如下。

1。plpbt 在很多基本的问题上,搞错了,这不是一个成熟软件的标志。它不成熟。那些问题是不该搞错的。一个相当不成熟的软件,没有理由被大面积采纳。

2。plpbt 不是开源的。当今的软件,开源是潮流,闭源没有太大的前途。闭源软件,大大阻碍了别人参与改进的步伐,那么这就注定它很难有快速的发展,除非它本身很有财力,支撑它的快速发展。

3。硬件标准很混乱。如果 BIOS 都不能统一的话,指望硬件的手段解决兼容性问题,那也是不容易做好的。如果兼容性做不好,那么它就不能被普遍接受。不容易做好,不等于说不能够做好。Linux 的 USB 驱动似乎就比较好。只有用户的实际检验,才知道 plpbt 的兼容性究竟好不好。从已有的用户反馈来看,现阶段似乎很不乐观。

以上只是给出我个人的分析。我对于 plpbt 这个软件本身,没有敌意。我和它以及它的开发人员 “ 没有世仇 ”,我也没有理由与它为敌。我也没有指责别人采用 plpbt 的意思,它毕竟也是一种补救手段,填补了空白,在别的情况都失败的时候,它是一个不错的选择。而且,它没有替代品,它是唯一的,这更显得珍贵。但非常遗憾的是,它那些缺点也很严重。
回复

使用道具 举报

2032#
发表于 2011-12-25 11:44:39 | 只看该作者
@chenall:
批处理里标签数量有限制?不能超过126个?
回复

使用道具 举报

2033#
发表于 2011-12-25 13:09:28 | 只看该作者
软驱问题一直很难缠,我一直靠检测0x8280及0x82b8的值,在菜单“初始化”阶段写floppies的值。
回复

使用道具 举报

2034#
发表于 2011-12-25 13:57:01 | 只看该作者

回复 #2036 zxw 的帖子

有限制的,具体数量忘记了。可以自己看一下源码,我记得有注释。

批处理文件不建议太大,目前标签数量还有命令行数都有限制。一百多个标签,这个批处理应该很大,执行效率不可观,解决方法有2

1.改成外部命令。
2.分成多个批处理。

关于软驱的问题,我晚上有空再尝试一下,应该只要判断一下(ud)所在的磁盘,如果是0,并且软驱数量也为0就自动修改为1.
回复

使用道具 举报

2035#
发表于 2011-12-25 13:58:02 | 只看该作者
用PLOP启动U盘我好像还没有成功过,一般都是直接死机。

启动CDROM倒是正常的。
回复

使用道具 举报

2036#
发表于 2011-12-25 14:25:41 | 只看该作者

回复 #2039 chenall 的帖子

我和你一样。我用plpbt没成功一次。。。。
所以我一直不用plpbt,虽然很期待。
回复

使用道具 举报

2037#
发表于 2011-12-25 17:44:17 | 只看该作者
回复:不点:
 你这么解释,我全明白了。

回复:chenall

对于ZIP,或将FB的盘识别成ZIP的机来说,特别是非整体map PE时,速度一般30K/秒左右,这个速度是非常致命的。很不幸,我使用的就是这样的机。6.19以前的G4D版本,加载加速器本身不死机,但是在加载nt5的PE时,会卡死,没办法,我只好借用BURG来加载PE。
  但6.19以后,G4D无意间解决了这个问题,加载加速器后,加载PE不死机了。这可是zip机的福音。

 既然不点解释了find为什么有时会失效,使我明白了其他工作机理,那我就想其他办法解决了。

 谢谢各位的解释

[ 本帖最后由 幸运的草 于 2011-12-25 20:44 编辑 ]
回复

使用道具 举报

2038#
发表于 2011-12-25 18:23:40 | 只看该作者
上传一个测试版。

如果使用UD启动,并且U盘被识别为软盘时,强制设置软驱存在。没有条件测试,有条件有可以试一下。

我只是用QEMU模拟了一下,使用正常。

另外调整了find命令的流程。会根据UD设备的实际情况调整软盘查找的先后顺序。具体的情况自己测试一下就明白了。

[ 本帖最后由 chenall 于 2011-12-25 21:52 编辑 ]
回复

使用道具 举报

2039#
发表于 2011-12-25 19:20:48 | 只看该作者
用12-24的grldr.在宏碁上网本上无法显示VBE背景,字体乱码。同一个U盘,在台式机上一切正常
回复

使用道具 举报

2040#
发表于 2011-12-25 19:37:58 | 只看该作者

回复 #2043 tulongwa 的帖子

你用的是 U 盘,那就很难说了。USB BIOS 有很多 bug。不知道你究竟碰上了哪个 bug。

报告问题要详细。不要说半截话。

无法显示背景,字体也乱码,这无非就是说,你的 U 盘上的背景文件以及字体文件无法访问。

你自己先找原因。关于访问文件失败的问题,属于 FAQ,应该自己解决。

重新分区格式化 U 盘,把 grub4dos 要用到的重要的文件放在 U 盘开头。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-6-7 02:27

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表