无忧启动论坛

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

[求助] 疑似grub4dos比较大的bug

  [复制链接]
跳转到指定楼层
#
发表于 2013-6-25 03:01:56 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 sratlf 于 2013-6-25 03:16 编辑

1,下面测试用的脚本  文件夹含有少量文件时不会发生下面截图的错误  过多的时候会执行错误
2,06-24 0.45c版在vmware虚拟机启动失败  卡死时出现光标  但没出现Running menu commands(hangup means you have a problematic config)...提示
  1. !BAT
  2. ls (hd0,0)/winxp/windows/system32/ | call :automake %0
  3. exit

  4. :automake
  5. echo A
  6. setlocal
  7. echo B
  8. exit
复制代码
下面截图是多个版本的测试  暂时还没找到是从哪个版本开始出现问题的




dir.zip

8.02 KB, 下载次数: 3, 下载积分: 无忧币 -2

(hd0,0)/winxp/windows/system32/下文件列表

49#
发表于 2013-7-4 16:45:48 | 只看该作者
已经把 usb 驱动放在 asm.S 中。使用方法依旧。
回复

使用道具 举报

48#
发表于 2013-7-3 10:19:41 | 只看该作者
不知情者,不为过

好吧,我试一试
回复

使用道具 举报

47#
发表于 2013-7-3 10:07:23 | 只看该作者
比如在 asm.S 中有一 grub_usb 函数,如何知道函数的地址?
回复

使用道具 举报

46#
发表于 2013-7-3 09:54:07 | 只看该作者
2011yaya2007777 发表于 2013-7-3 07:25
好吧,那就在 asm.S 中实现。
那只能是在加载 grldr 之后,从菜单中加载 usb 驱动了。
怎样从菜单加载?即 ...

不知情者,不为过。其实那很简单啊。asm.S 的第一条指令就是 JMP 指令。你顺着 JMP 指令走,看看你的代码适合插入在什么地方,就可以插入了。你的代码不长,只有几个 K 的大小,可以插入。还可以把你的代码放在 asm.S 中的某个位置,然后用 call 指令调用你的代码便可。

在 asm.S 的 618 行,有如下注释和代码:

/* transition to protected mode */
call EXT_C(real_to_prot)

这显然是必经之路,切换到保护模式。所以,如果你的实模式代码插入到这个之前,肯定会执行的。这只是举例而已,其实可插入的地方很多,你自己看究竟插入到什么地方最合适,就插入到什么地方。如果你不知道插入到哪里最合适,那就插入到这里吧:

1:
#endif /* !STAGE1_5 */

你的 USB 实模式处理程序插入在这里

/* transition to protected mode */
call EXT_C(real_to_prot)


asm.S 在切换到 32 位保护模式并做适当的准备工作后,就要调用 common.c 中的 C 语言程序 init_bios_info () 和 stage2.c 里面的 cmain()。

call EXT_C(init_bios_info)
call EXT_C(cmain)

如果你的代码可以转换成 32 位的 C 语言代码,你也可以把它插入到 call init_bios_info 之前,或者插入在 call init_bios_info 和 call cmain 之间。cmain 就是开始处理菜单的地方,也就是真正的 grub4dos 的核心主程序。
回复

使用道具 举报

45#
发表于 2013-7-3 08:50:38 | 只看该作者
本帖最后由 chenall 于 2013-7-3 08:51 编辑

这个驱动是如何调用的???

目前的call命令可以调用某个地址处的程序.
比如这个驱动程序的开始地址是0x8000

则可以用以下命令来调用,后面还可以加参数
call Fn.0x8000

一个例子:
我们知道grub_printf函数的地址在(*(int **)0x8300)[0]处.
这时先读取0x8300处的值
read 0x8300
比如得到的值是0x30d81d
再读一下0x30d81d的值就是printf函数的地址了.
read 0x30d81d
比如得到的值是0x324e47
现在我们知道printf函数的地址了就可以调用.

call Fn.0x324e47 0 "Test Printf"
上面就是call Fn.X 功能的执行过程.这些内部函数都已经简化了处理方法直接调用第几个函数就行了.
call Fn.0 和上面的是一样的.

当然了这个应该是只能调用32程序.
回复

使用道具 举报

44#
发表于 2013-7-3 07:25:11 | 只看该作者
好吧,那就在 asm.S 中实现。
那只能是在加载 grldr 之后,从菜单中加载 usb 驱动了。
怎样从菜单加载?即菜单语句如何写?如何带入参数?可否给一个示例?

点评

不知情者,不为过。其实那很简单啊。asm.S 的第一条指令就是 JMP 指令。你顺着 JMP 指令走,看看你的代码适合插入在什么地方,就可以插入了。你的代码不长,只有几个 K 的大小,可以插入。还可以把你的代码放在 asm.  详情 回复 发表于 2013-7-3 09:54
回复

使用道具 举报

43#
发表于 2013-7-2 23:47:03 | 只看该作者
本帖最后由 不点 于 2013-7-3 00:56 编辑
2011yaya2007777 发表于 2013-7-2 10:14
是的。错误源于判断原 0x2000 处的内核头部 4 字节 EA 70 82 00 。现在 0x2000-0x33ff 插入 usb 驱动代码 ...


为何要插入到内核头部之前?在 asm.S 中实现,不是更好吗?

挪动内核头部,只怕会带来一连串的不兼容问题。

给 0.4.5c 打补丁,那么老版本就放弃支持了?这个思路是不对头的。假如实在没有办法了,只好这么做。问题是,我很怀疑这是 “实在没办法” 了。

幸亏原来的代码检查内核头部,否则你这个改动所带来的混乱,不知道会等到何时才能发现。

当我们能够保持兼容性的时候,就不要破坏兼容性。除非是做不到,或者代价太高。

这个 USB 驱动也属于内核吧?那么他就应该放在内核头部之后。

grldr 的头部只有 8K 是可以被 NTLDR 加载的。你的 0x2000-0x33ff 的代码,不可能被 ntldr 加载到。所以,它放在这里没有意义,不如放在内核头部之后好。



背景:

内核起始于 grldr 偏移 0x2000,是固定的。内核头部有很多控制变量,是用户可以读写的。用户甚至在启动 grldr 之前可以动态修改内核头部中的变量,比如,启动盘的 drive number 以及启动盘的 chs 信息。你把头部一挪动,那原来的外部程序就要写错位置,失效了。

内核头部还记录了 preset menu 的位置。外部程序可以读出内核头部的指针,计算出 preset menu 的位置。头部被挪动到 0x2000 之后,那些外部程序都要泡汤了。

甚至 grldr 自己的头部代码(位于 grldr 第2扇区的代码)也写内核头部信息(有关 PXE 启动的控制信息)。头部一挪动,就好像没有坐标了,所有的东西都得改。

我们的文档早都公开过了(虽然是零零散散公开的),内核头部起始于 grldr 的偏移 0x2000 处。头部的变量也公布了。外部程序都把这当成依据了。此时再挪动,那不就是自乱阵脚吗?连文档也得修改了。

现在忽然想起,论坛上报告 bootice 写 preset menu 竟然会导致程序死锁,写入的结果 grldr 文件竟然达 4G 之多!我感到很疑惑:怎么会呢?这下子终于可以猜到原因了:内核头部被挪动造成的。
回复

使用道具 举报

42#
发表于 2013-7-2 10:36:33 | 只看该作者
2011yaya2007777 发表于 2013-7-2 10:14
是的。错误源于判断原 0x2000 处的内核头部 4 字节 EA 70 82 00 。现在 0x2000-0x33ff 插入 usb 驱动代码 ...

@不点

不知是否可以使用0x1FFC处的grldr_signature来判断?这个应该不会变吧.

回复

使用道具 举报

41#
 楼主| 发表于 2013-7-2 10:27:50 | 只看该作者
chenall 发表于 2013-7-2 10:15
先用这个试试吧,取消了批处理call的参数长度限制..

只受限于重定向输出缓冲区大小,目前是128KB,如果 ...

应该是没问题了  虚拟机测试通过
回复

使用道具 举报

40#
发表于 2013-7-2 10:15:29 | 只看该作者
本帖最后由 chenall 于 2013-7-2 10:16 编辑
sratlf 发表于 2013-7-2 10:07
也不是我遇到的  是另外一个用户遇到的  还是在实机上。。。  http://bbs.wuyou.net/forum.php?mod=redir ...


先用这个试试吧,取消了批处理call的参数长度限制..

只受限于重定向输出缓冲区大小,目前是128KB,如果这样还不够用的话需要自己想办法了,我WIN7的I386目录列表也没有超过64KB.

grub4dos-0.4.5c-07-02.rar

135.26 KB, 下载次数: 15, 下载积分: 无忧币 -2

点评

应该是没问题了 虚拟机测试通过  详情 回复 发表于 2013-7-2 10:27
回复

使用道具 举报

39#
发表于 2013-7-2 10:14:42 | 只看该作者
是不是修改了 chainloader 命令,让它识别 0.4.6a 的 GRLDR 格式?

是的。错误源于判断原 0x2000 处的内核头部 4 字节 EA 70 82 00 。现在 0x2000-0x33ff 插入 usb 驱动代码,内核头部移动到了 0x3400。
建议:0.4.5c 与 0.4.6a 同时打补丁。

点评

为何要插入到内核头部之前?在 asm.S 中实现,不是更好吗? 挪动内核头部,只怕会带来一连串的不兼容问题。  详情 回复 发表于 2013-7-2 23:47
@不点 不知是否可以使用0x1FFC处的grldr_signature来判断?这个应该不会变吧.  详情 回复 发表于 2013-7-2 10:36
回复

使用道具 举报

38#
发表于 2013-7-2 10:09:23 | 只看该作者
zhaohj 发表于 2013-7-2 09:41
if (arg_len > 0x8000)
        {
            errnum = ERR_WONT_FIT;  //Error 28: Select item cannot fit into mem ...

列文件所占的空间,32K 绝对不够。即使预留 1M 也不够。这应该属于 “超限使用 grub4dos” 的范畴吧。
回复

使用道具 举报

37#
 楼主| 发表于 2013-7-2 10:07:36 | 只看该作者
zhaohj 发表于 2013-7-2 09:41
if (arg_len > 0x8000)
        {
            errnum = ERR_WONT_FIT;  //Error 28: Select item cannot fit into mem ...

也不是我遇到的  是另外一个用户遇到的  还是在实机上。。。  http://bbs.wuyou.net/forum.php?m ... &fromuid=330930

我再想想怎么办吧  因为是用脚本实现的检索文件  如果强行截断的话用户又该说脚本有bug  找不到文件了。。。

点评

先用这个试试吧,取消了批处理call的参数长度限制.. 只受限于重定向输出缓冲区大小,目前是128KB.  详情 回复 发表于 2013-7-2 10:15
回复

使用道具 举报

36#
发表于 2013-7-2 10:03:26 | 只看该作者
本帖最后由 chenall 于 2013-7-2 10:10 编辑
sratlf 发表于 2013-7-2 00:27
貌似还是有点bug  看截图


看13楼的说明..
你的参数太长了,已经超过32KB.建议分段处理..

确实有必要的话再改大一些..

想了想下一版还是改掉好了,不限制,但是还是要受管道缓冲区的大小限制(目前是0x20000 共128KB,我想应该没有那么变态的应用会超过这个限制)
回复

使用道具 举报

35#
发表于 2013-7-2 09:57:26 | 只看该作者
2011yaya2007777 发表于 2013-7-2 08:49
关于 0.4.6a 的 grldr 格式识别问题已经解决。

是不是修改了 chainloader 命令,让它识别 0.4.6a 的 GRLDR 格式?

如果这样做,那么老版本的 grub4dos 还是无法用 chainloader 加载 0.4.6a 的 GRLDR。

最好是修改新版的 GRLDR 的格式,让它可以被老版本的 chainloader 加载。除非根本做不到这一点。

回复

使用道具 举报

34#
发表于 2013-7-2 09:41:06 | 只看该作者
本帖最后由 zhaohj 于 2013-7-2 11:25 编辑

        if (arg_len > 0x8000)
        {
            errnum = ERR_WONT_FIT;  //Error 28: Select item cannot fit into memory  
            return 0;
        }
-----------------------------
@sratlf:
目前是超过0x20(kb)就直接报错退出
你这个也太变态了,一般不会遇到的吧。但我认为截断比较好,并给出提示。

点评

列文件所占的空间,32K 绝对不够。即使预留 1M 也不够。这应该属于 “超限使用 grub4dos” 的范畴吧。  详情 回复 发表于 2013-7-2 10:09
也不是我遇到的 是另外一个用户遇到的 还是在实机上。。。 http://bbs.wuyou.com/forum.php?mod=redirect&goto=findpost&ptid=191301&pid=2805791&fromuid=330930 我再想想怎么办吧 因为是用脚本实现的检索文  详情 回复 发表于 2013-7-2 10:07
回复

使用道具 举报

33#
 楼主| 发表于 2013-7-2 09:20:01 | 只看该作者
2011yaya2007777 发表于 2013-7-2 08:49
关于 0.4.6a 的 grldr 格式识别问题已经解决。

用0630 0.45c还是启动不了0702 0.46a...
回复

使用道具 举报

32#
发表于 2013-7-2 08:49:49 | 只看该作者
关于 0.4.6a 的 grldr 格式识别问题已经解决。

点评

是不是修改了 chainloader 命令,让它识别 0.4.6a 的 GRLDR 格式? 如果这样做,那么老版本的 grub4dos 还是无法用 chainloader 加载 0.4.6a 的 GRLDR。 最好是修改新版的 GRLDR 的格式,让它可以被老版本的 c  详情 回复 发表于 2013-7-2 09:57
用0630 0.45c还是启动不了0702 0.46a...  详情 回复 发表于 2013-7-2 09:20
回复

使用道具 举报

31#
 楼主| 发表于 2013-7-2 00:27:18 | 只看该作者
chenall 发表于 2013-6-30 17:47
刚上传的版本应该解决了,,眼花没有注意看,.

貌似还是有点bug  看截图


点评

看13楼的说明.. 你的参数太长了,已经超过32KB.建议分段处理..  详情 回复 发表于 2013-7-2 10:03
回复

使用道具 举报

30#
发表于 2013-6-30 18:36:50 | 只看该作者
感觉 有关 0.4.6 的 grldr 格式问题,最好由 yaya 来解决。yaya 原来都解决过一次了,这次又出问题,需要再次解决。正如 bootlace64 需要重新解决那样,grldr 格式问题应该也需要重新解决。

回复

使用道具 举报

29#
发表于 2013-6-30 18:20:14 | 只看该作者
sratlf 发表于 2013-6-30 18:17
0630版没有#1的两个问题了  还有个问题忘记说了  用0.45c的grldr启动0.46a的grldr会报错  最近的几个版 ...

的确如此,用0.46a grldr  ---->0.46a grldr 也会报错,非法格式。
(ud)/grldr   --------> U可见区 /GRLDR
回复

使用道具 举报

28#
 楼主| 发表于 2013-6-30 18:17:10 | 只看该作者
chenall 发表于 2013-6-30 17:47
刚上传的版本应该解决了,,眼花没有注意看,.


0630版没有#1的两个问题了  还有个问题忘记说了  用0.45c的grldr启动0.46a的grldr会报错  最近的几个版本都这样

grldr2是0630 0.46a的grldr改名的

点评

的确如此,用0.46a grldr ---->0.46a grldr 也会报错,非法格式。 (ud)/grldr --------> U可见区 /GRLDR  详情 回复 发表于 2013-6-30 18:20
回复

使用道具 举报

27#
发表于 2013-6-30 17:47:18 | 只看该作者
刚上传的版本应该解决了,,眼花没有注意看,.

点评

貌似还是有点bug 看截图  详情 回复 发表于 2013-7-2 00:27
0630版没有#1的两个问题了 还有个问题忘记说了 用0.45c的grldr启动0.46a的grldr会报错 最近的几个版本都这样  详情 回复 发表于 2013-6-30 18:17
回复

使用道具 举报

26#
发表于 2013-6-30 12:45:42 | 只看该作者
我记得不点大已经取消了stage1及stage1.5,应该更加精简啊。


完全是两回事。源代码精简了,不等于执行码能精简。

我们的执行码中,一直都不存在 stage1 和 stage1.5,所以,执行码根本不受影响。
回复

使用道具 举报

25#
发表于 2013-6-30 12:24:03 | 只看该作者
编译的文件大小为何比以前还大?我记得不点大已经取消了stage1及stage1.5,应该更加精简啊。
我测试srsf6n(22楼的grldr)也卡死,自己用gebian gcc4.8.1-2下载最新源码编译后的grldr测试srsf6n没问题。
是否是编译的问题?
回复

使用道具 举报

24#
发表于 2013-6-30 11:08:56 | 只看该作者
没道理啊,这个改动不应该影响才对的..

麻烦把可以重现问题的文件打包一份上来,我下午抽空看下.
回复

使用道具 举报

23#
 楼主| 发表于 2013-6-30 09:40:18 | 只看该作者
不点 发表于 2013-6-29 17:57
死机的问题解决了,那么 chenall 接下来应该删除 0.4.5c-2013-06-24 的下载,以免别人再下载这个已经被证明 ...

貌似还是有点问题  用的#22的grldr  启动没问题了  但是执行脚本时还是卡死  已在其他版本测试过执行没问题的

回复

使用道具 举报

22#
发表于 2013-6-29 17:57:48 | 只看该作者
死机的问题解决了,那么 chenall 接下来应该删除 0.4.5c-2013-06-24 的下载,以免别人再下载这个已经被证明是有问题的版本。

点评

貌似还是有点问题 用的#22的grldr 启动没问题了 但是执行脚本时还是卡死 已在其他版本测试过执行没问题的  详情 回复 发表于 2013-6-30 09:40
回复

使用道具 举报

21#
发表于 2013-6-29 17:50:05 | 只看该作者
本帖最后由 chenall 于 2013-6-29 17:57 编辑
不点 发表于 2013-6-29 17:27
已经修复,附件是修复后的 grldrstart.S 文件,适用于 0.4.5c,不适用于 0.4.6a。

如果测试成功,请 che ...


测试正常,源码先提交了.

grub4dos-0.4.5c.rar

135.4 KB, 下载次数: 23, 下载积分: 无忧币 -2

回复

使用道具 举报

20#
发表于 2013-6-29 17:27:17 | 只看该作者
已经修复,附件是修复后的 grldrstart.S 文件,适用于 0.4.5c,不适用于 0.4.6a。

如果测试成功,请 chenall 直接提交。

grldrstart.rar

41.76 KB, 下载次数: 6, 下载积分: 无忧币 -2

0.4.5c 源代码

点评

测试正常,源码先提交了.  详情 回复 发表于 2013-6-29 17:50
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-9-22 18:20

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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