无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站广告联系 微信:wuyouceo QQ:184822951
12
返回列表 发新帖
楼主: sratlf

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

  [复制链接]
发表于 2013-6-30 18:36:50 | 显示全部楼层
感觉 有关 0.4.6 的 grldr 格式问题,最好由 yaya 来解决。yaya 原来都解决过一次了,这次又出问题,需要再次解决。正如 bootlace64 需要重新解决那样,grldr 格式问题应该也需要重新解决。

回复

使用道具 举报

 楼主| 发表于 2013-7-2 00:27:18 | 显示全部楼层
chenall 发表于 2013-6-30 17:47
刚上传的版本应该解决了,,眼花没有注意看,.

貌似还是有点bug  看截图

1.PNG
2.PNG

点评

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

使用道具 举报

发表于 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
回复

使用道具 举报

 楼主| 发表于 2013-7-2 09:20:01 | 显示全部楼层
2011yaya2007777 发表于 2013-7-2 08:49
关于 0.4.6a 的 grldr 格式识别问题已经解决。

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

使用道具 举报

发表于 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
回复

使用道具 举报

发表于 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 加载。除非根本做不到这一点。

回复

使用道具 举报

发表于 2013-7-2 10:03:26 | 显示全部楼层
本帖最后由 chenall 于 2013-7-2 10:10 编辑
sratlf 发表于 2013-7-2 00:27
貌似还是有点bug  看截图


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

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

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

使用道具 举报

 楼主| 发表于 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
回复

使用道具 举报

发表于 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” 的范畴吧。
回复

使用道具 举报

发表于 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
回复

使用道具 举报

发表于 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
回复

使用道具 举报

 楼主| 发表于 2013-7-2 10:27:50 | 显示全部楼层
chenall 发表于 2013-7-2 10:15
先用这个试试吧,取消了批处理call的参数长度限制..

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

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

使用道具 举报

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

@不点

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

回复

使用道具 举报

发表于 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 之多!我感到很疑惑:怎么会呢?这下子终于可以猜到原因了:内核头部被挪动造成的。
回复

使用道具 举报

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

点评

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

使用道具 举报

发表于 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程序.
回复

使用道具 举报

发表于 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 的核心主程序。
回复

使用道具 举报

发表于 2013-7-3 10:07:23 | 显示全部楼层
比如在 asm.S 中有一 grub_usb 函数,如何知道函数的地址?
回复

使用道具 举报

发表于 2013-7-3 10:19:41 | 显示全部楼层
不知情者,不为过

好吧,我试一试
回复

使用道具 举报

发表于 2013-7-4 16:45:48 | 显示全部楼层
已经把 usb 驱动放在 asm.S 中。使用方法依旧。
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-4-18 18:25

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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