无忧启动论坛

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

grub菜单实现条件选择

[复制链接]
跳转到指定楼层
1#
发表于 2009-4-27 10:14:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人的U盘在笔记本上识别为FD0,在台式机上识别为HD0,0,在启动菜单上有一项是启动本机默认的WIN系统,那么这里能不能改写代码,让grub根据不同的情况来执行启动。

如果U盘被识别为FD0,那么就执行
title 启动 默认Microsoft Windows----启动盘识别为软盘
rootnoverify (hd0,0)
makeactive
chainloader +1

如果U盘识别为HD0,0,那么就执行
title 启动 默认Microsoft Windows----启动盘识别为硬盘
rootnoverify (hd1,0)
map (hd0) (hd1)
map (hd1) (hd0)
makeactive
chainloader +1

不知道上面的代码能合并吗?用条件语句来实现。类似下面的语法:

title 启动 默认Microsoft Windows
IF(...=(FD0))    DO(rootnoverify (hd0,0) makeactive chainloader +1)
ELSE               DO(rootnoverify (hd1,0) map (hd0) (hd1) map (hd1) (hd0) makeactive chainloader +1)
2#
发表于 2009-4-27 10:27:32 | 只看该作者
当然不能,至少目前不能
回复

使用道具 举报

3#
 楼主| 发表于 2009-4-28 10:26:37 | 只看该作者
谢谢一楼的回答

弄不明白,为什么U盘在不同的机器上被识别成不同的磁盘

有什么办法可以用让U盘固定识别为软盘吗?
回复

使用道具 举报

4#
发表于 2009-4-28 17:29:18 | 只看该作者
方法1,使用两个菜单.
default 0
timeout 5

title 启动 默认Microsoft Windows
#如果执行失败就跳到第1个菜单执行.(本菜单是第0个)
fallback 1
#检测启动磁盘,如果是0x80也就是(hd0)就说明是Hdd模式了,就执行kernel(让它执行失败跳到前面fallback 指定的菜单).
checkrange 0x80 read 0x8280 && kernel
#后面的就不用解释了.
rootnoverify (hd0,0)
makeactive
chainloader +1

title
map (hd0) (hd1)
map (hd1) (hd0)
map --hook
rootnoverify (hd0,0)
makeactive
#使用pause --wait=0 && chainloader +1 是为了让这个菜单不可选择(不能使用上下键来选择菜单)
pause --wait=0 && chainloader +1


方法2.只使用一个菜单.
default 0
timeout 5
title 启动 默认Microsoft Windows
#hd0
#检测启动磁盘如果是(hd0){HDD模式]就交换磁盘映射.
checkrange 0x80 read 0x8280 && map (hd0) (hd1)
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
checkrange 0x80 read 0x8280 && map --hook
rootnoverify (hd0,0)
makeactive
chainloader +1

[ 本帖最后由 chenall 于 2009-4-28 19:14 编辑 ]
回复

使用道具 举报

5#
发表于 2009-4-28 18:17:23 | 只看该作者

回复 #4 chenall 的帖子

学习了。。。还真没用过这样的方式。。。能具体独项解说一下么。。。
回复

使用道具 举报

6#
发表于 2009-4-28 19:14:01 | 只看该作者
把一些注释加到4楼的贴子里面去了.^_^.
回复

使用道具 举报

7#
发表于 2009-4-28 21:20:40 | 只看该作者
好方法。收藏先。多谢!

不知在没hd1的情况下hdd方式U盘
执行了
checkrange 0x80 read 0x8280 && map (hd0) (hd1)
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
checkrange 0x80 read 0x8280 && map --hook

将会是什么情况呢?

[ 本帖最后由 yjd 于 2009-4-28 21:33 编辑 ]
回复

使用道具 举报

8#
发表于 2009-4-28 22:35:02 | 只看该作者
当然是出错了.
执行到checkrange 0x80 read 0x8280 && map (hd1) (hd0)就会出错.

为了防止这种情况可以改成如下语句.

errorcheck off
checkrange 0x80 xxxx
checkrange 0x80 xxx..
checkrange 0x80 ...
errorcheck on
回复

使用道具 举报

9#
 楼主| 发表于 2009-4-28 22:41:47 | 只看该作者
看得出CHENALL对技术是有研究之人,本人佩服,也谢谢您的解答

对于方法2,本人还是有不理解的地方
default 0
timeout 5
title 启动 默认Microsoft Windows
#hd0
#检测启动磁盘如果是(hd0){HDD模式]就交换磁盘映射.
checkrange 0x80 read 0x8280 && map (hd0) (hd1)
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
checkrange 0x80 read 0x8280 && map --hook
rootnoverify (hd0,0)
makeactive
chainloader +1

那么如果是检测不是HDD模式,那执行什么代码呢,下面好想都是执行HDD模式的代码

请CHENALL指教


对于YJD的问题,我是怎么理解的:

如果U盘被是被为HDD,那么那么应该就有HD1,因为U盘已经是HD0,除非你的电脑里没有硬盘,这种情况就是U盘启动后只存在一个U盘并被识别为HD0,不知道我的理解适合你的问题吗
回复

使用道具 举报

10#
 楼主| 发表于 2009-4-28 22:55:15 | 只看该作者
再认真的看了CHENALL的技术答贴,感觉是自己没有完全理解

当U盘被识别为硬盘,那么通过磁盘交换后,原硬盘(HD1就变成HD0),然后执行rootnoverify (hd0,0)

如果U盘被识别为软盘,那么就直接执行下面的rootnoverify (hd0,0)

看来CHENALL真是高手,高手一般是孤独的,很多东西不用心看还不能理解

再次谢谢CHENALL
回复

使用道具 举报

11#
发表于 2009-4-29 00:36:11 | 只看该作者
你上面的理解是正确的.

还好你能理解否则我也说不清楚.^_^,因为我的贴子很多人看不懂.郁闷..
回复

使用道具 举报

12#
 楼主| 发表于 2009-4-29 09:06:43 | 只看该作者
经过本人的实践,CHENALL给出的代码在笔记本和虚拟机中测试成功

笔记本把U盘识别为软盘,而虚拟机中U盘被识别为硬盘

我是用CHENALL第二种方法测试测,第一种方法没有测试,但是看代码就知道和我最初菜单中分两种情况的代码比较相似,所以我想应该没有什么问题吧

一直以来比较欣赏严谨,简洁的逻辑,CHENALL给出的答案恰恰是这一逻辑的具体表达

谢谢CHENALL
回复

使用道具 举报

13#
发表于 2009-4-29 09:31:43 | 只看该作者
嘿嘿,看来楼主是有所不知,chenall可是对grub的发展做出了莫大贡献之人。
回复

使用道具 举报

14#
 楼主| 发表于 2009-4-29 09:48:53 | 只看该作者
对事物的了解是有一个过程的,我是最近在弄U盘PE的时候才知道无忧论坛的,所以对无忧论坛的前辈们不是很熟悉,但是通过这个帖子,意识到CHENALL是一个相当具有功力的人,并且有些孤独,通过不才兄弟的介绍,才知道CHENALL对GRUB有专攻。谢谢不才兄弟,让我认识一个“GRUB大碗”。

刚才看到另外的一个帖子,基于CHENALL的回贴我都认真看了,有一处问题,还想请CHENALL指点下:

CHENALL发表于 2006-8-28 13:19  资料  主页 短消息  加为好友      

还有.

[Copy to clipboard] [ - ]CODE:
# 从本地磁盘的主分区启动
title 返回系统启动菜单
rootnoverify (hd0,0)
makeactive
chainloader  +1
建议不要这样使用,因为每启动一次就写一次硬盘.久了硬盘容易出问题的.

[Copy to clipboard] [ - ]CODE:
# 从本地磁盘的主分区启动
title 返回系统启动菜单
chainloader (hd0)+1
使用硬盘启动,或者你需要启动(hd0,0)下的WINNT系统也可以这样使用

[Copy to clipboard] [ - ]CODE:
title 返回系统启动菜单
chainloader (hd0,0)/ntldr
#or chainloader (hd0,0)+1


这里说到:建议不要这样使用,因为每启动一次就写一次硬盘.久了硬盘容易出问题的.

请问是不是我的启动菜单也要修改成下面的启动代码呢?
title 启动 默认Microsoft Windows
chainloader (hd0)+1

或者
title 启动 默认Microsoft Windows
chainloader (hd0,0)/ntldr
#or chainloader (hd0,0)+1

请CHENALL给予建设性的指导
回复

使用道具 举报

15#
 楼主| 发表于 2009-4-29 09:51:55 | 只看该作者
我完整的启动代码是不是需要修改成下面的样式

title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd0) (hd1)
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
checkrange 0x80 read 0x8280 && map --hook
chainloader (hd0)+1

或者
title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd0) (hd1)
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
checkrange 0x80 read 0x8280 && map --hook
chainloader (hd0,0)/ntldr
#or chainloader (hd0,0)+1

麻烦CHENALL
回复

使用道具 举报

16#
 楼主| 发表于 2009-4-29 10:49:39 | 只看该作者
修改启动代码如下:

title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd0) (hd1)
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
chainloader (hd0)+1

在笔记本(U盘被识别为软盘)和虚拟机(U盘被识别为硬盘)双环境下启动圆满成功
回复

使用道具 举报

17#
发表于 2009-4-29 11:24:03 | 只看该作者
觉得上面这个比较简洁。我一直觉得,那个激活分区和不校验的命令,好象没有什么必要,因为一般电脑里的硬盘分区,应该都是已经激活了的。

不过楼上的MAP了之后,没有map --hook命令,MAP应该不起作用的吧?

[ 本帖最后由 xianglang 于 2009-4-29 11:27 编辑 ]
回复

使用道具 举报

18#
发表于 2009-4-29 11:31:59 | 只看该作者
原帖由 zxw 于 2009-4-27 10:27 发表
当然不能,至少目前不能

汗,是自己学识浅薄了
回复

使用道具 举报

19#
 楼主| 发表于 2009-4-29 11:37:29 | 只看该作者
title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd0) (hd1)
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
chainloader (hd0)+1

这段代码,没有map --hook命令,测试十分彻底成功

但是在下面的启动项目中缺一不可

title 启动 MS-DOS 7.10
map --mem /boot/dos.ima (fd0)
map --hook
chainloader (fd0)+1
rootnoverify (fd0)
回复

使用道具 举报

20#
 楼主| 发表于 2009-4-29 11:53:22 | 只看该作者
最终精简代码

title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
chainloader (hd0)+1

测试结果:出色的成功!

请CHENALL看到此代码后,给予技术上的解释,并说明下这样的代码有那些不足及其不安全的地方,谢谢。
回复

使用道具 举报

21#
发表于 2009-4-29 12:08:15 | 只看该作者
是不是你的主板,没将U盘作为第一硬盘启动?试试注释checkrange 0x80 read 0x8280 && map (hd1) (hd0)这一项,看能不能从硬盘启动?
回复

使用道具 举报

22#
 楼主| 发表于 2009-4-29 13:11:02 | 只看该作者
xianglang 误会了

我的问题是U盘在笔记本上识别为软盘,在台式机上识别为硬盘,我原本两种情况都能启动

我需要解决的是:不管U盘被识别为什么盘,在GRUB启动菜单里只需一个选项就可以实现启动电脑默认的操作系统

这个问题CHENALL已经很好的帮我解决了。
回复

使用道具 举报

23#
发表于 2009-4-29 13:22:43 | 只看该作者
#14,15
只要把原来的代码里面的
makeactive去掉就可以了,这个没有必要.

使用chainloader /NTLDR可能成功率比较高(因为这个不需要该分区上有引导代码,即使引导代码坏了也可以启动).

#16,17
代码可以启动成功,是因为grub4dos最后是默认执行map --hook命令,
而且你的U盘上刚好有引导扇区.否则就会失败.

xiyaxi 懂得举一反三,很不错,这就是学好电脑的基础了.^_^
(很多时候别人给你的答案并不是最好的,也不一定是对的,因为别人一般都是在你原来的基础上进行修改的,只要你理解了这里面的内容
通过举一反三自己可以再次修改达到理想的状态,并且加深了印像.)

20楼的代码很简练,
为了保证不出问题,
map --hook最好还是加上.

title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
checkrange 0x80 read 0x8280 && map --hook
chainloader (hd0)+1

[ 本帖最后由 chenall 于 2009-4-29 13:27 编辑 ]
回复

使用道具 举报

24#
发表于 2009-4-29 13:59:33 | 只看该作者
原帖由 chenall 于 2009-4-28 22:35 发表
当然是出错了.
执行到checkrange 0x80 read 0x8280 && map (hd1) (hd0)就会出错.

为了防止这种情况可以改成如下语句.

errorcheck off
checkrange 0x80 xxxx
checkrange 0x80 xxx..
checkrange 0x80 . ...

^_^。多谢chenall大解答。昨天就把你的方法用到我的U盘上了。
感谢
回复

使用道具 举报

25#
发表于 2009-4-29 14:08:49 | 只看该作者
grub4dos功能强大。借助它,PE可以做到:
1、一个菜单项,不分USB-ZIP、USB-HDD,USB-CDROM,统一处理。
2、一个ISO映像。不分U盘、光盘、量产、移动盘、硬盘版,发布时只提供一个版本(一个iso映像文件)。
3、ISO映像可不解开。ISO映像可以解开来用,也可以整体使用(盘上只看到iso文件),解开与不解开之间无需修改任何配置。不担心找不到外置程序。
4、pxe启动与本地启动统一。无需结构调整、无需配置即可直接用于pxe启动,拷贝式安装。支持本地加远程混合快速启动。
5、随意增删。PE被分解为多个组件(包括“内核”也被分解),组件可以随意增删(“内核”也可删,最小可只剩3M),不用修改配置。
6、位置灵活。组件可以分散放置到各分区,典型地:U盘量产区放一些,非量产区放一点,硬盘C区放一点,D区放一点,pxe服务器端放一点。
7、目录清爽。因为努力遵循了这样的原则:用于启动的文件尽量少,可以只有一个;几乎每个用户看到的文件都是组件,一个文件没有与其它文件合并打包,往往意味着它是可以删除的,所以才独立出来作为组件。

参考0PE和chenall的PE。
另外,这里有些实现技术的参考资料http://bbs.wuyou.net/forum.php?m ... 7686&highlight=
回复

使用道具 举报

26#
发表于 2009-4-29 14:12:16 | 只看该作者
map (hd1) (hd0)
map --hook
我原来U盘上写启动硬盘的windows也是用到这2句。

到现在对这个也有点迷糊
1,
map (hd1) (hd0)    //把hd1换为hd0
map --hook           //生效
2,
map (hd1) (hd0)    //把hd1换为hd0
map (hd0) (hd1)    //把hd0换为hd1
map --hook           //生效

1的hd0将会不见还是?比如进入pe或dos
2是2个互换位置。这个理解。
回复

使用道具 举报

27#
发表于 2009-4-29 14:17:58 | 只看该作者

回复 #26 yjd 的帖子

1的hd0将会不见还是?比如进入pe或dos

dos下不见,pe下可见。
回复

使用道具 举报

28#
发表于 2009-4-29 14:28:22 | 只看该作者
原帖由 pseudo 于 2009-4-29 14:17 发表
1的hd0将会不见还是?比如进入pe或dos

dos下不见,pe下可见。

多谢pseudo 大解答。
看来加载dos工具箱还是要2条都用上,现在上班时间,有点偷懒直接就发问没动手实践^_^
回复

使用道具 举报

29#
 楼主| 发表于 2009-4-29 18:28:44 | 只看该作者
再次请教

有些人喜欢实践,有些人喜欢理论,就好比是工科与理科一样,侧重点不一样

本人也不是在研究什么,只是把问题摆出来,就想问题搞得更清楚,或者是追求一种思想上的愉悦。

CHENALL指出:
代码可以启动成功,是因为grub4dos最后是默认执行map --hook命令,
而且你的U盘上刚好有引导扇区.否则就会失败.

第一句好理解,第二句对于我这样的菜鸟有些困惑
而且你的U盘上刚好有引导扇区.否则就会失败,怎么说不管有没有执行map --hook,只要U盘上没有引导扇区,就必然启动失败。或者说执行map --hook后,程序还要去引导扇区做点什么事情?(请允许我这么不专业的描述)

不知道CHENALL能不能形象的描述下这个启动详细过程,好让我更加清楚这个启动的原理。在此先说声谢谢。

我对下面代码的理解(不对的地方还请指正)

title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
checkrange 0x80 read 0x8280 && map --hook
chainloader (hd0,0)/ntldr

在启动菜单中选择这个选项后,首先GRUB程序去检查BIOS(抑或是磁盘引导区)0x80位置的代码,如果是0x8280,那么就执行后面的map (hd1) (hd0),也就是进行磁盘虚拟交换,接着再次重复检查,并执行map --hook,将虚拟的(hd0)挂载即让磁盘虚拟交换生效,最后执行chainloader (hd0,0)/ntldr,就是把ntldr载入内存并运行它。

我上面的理解里并没有与CHENALL所说的“U盘上刚好有引导扇区”相关联,显然是不对的,请CHENALL清理下我的思路并指正这个启动的基本原理。谢谢
回复

使用道具 举报

30#
发表于 2009-4-29 18:47:09 | 只看该作者
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
#读取内存0x8280位置的值(GRUB4DOS内置变量,启动磁盘号,具体请看GRUB4DOS说明).如果是0x80(也就是hd0)就执行后面的语句.


另外我前面说的"U盘刚好的引导扇区"是因为你之前使用的菜单.

title 启动 默认Microsoft Windows
checkrange 0x80 read 0x8280 && map (hd1) (hd0)
因为这时上面的映射还没有生效,执行chainloader实际上是加载了U盘上的mbr的内容.
chainloader (hd0)+1
到后面默认map --hook生效后U盘原来的位置被硬盘取代了,所以就启动成功了.

你可以尝试使用GRUBINST之类的工具把GRUB4DOS引导写到U盘上再试试使用这样的菜单,或许就会发现这其中的问题了.(我自己没有试过.^_^,只是理论)

http://bbs.wuyou.net/forum.php?mod=viewthread&tid=139062&extra=page%3D2
这里就有一个这样的工具.

你可以测试下具体的结果.


另外一点.
chainloader (hd0,0)/ntldr

建议还是使用chainloader (hd0)+1

因为系统不一定是装在(hd0,0)上的,也有可能是(hd0,1).
总之只要chainloader (hd0)+1让它自己去找就OK了.

[ 本帖最后由 chenall 于 2009-4-29 18:58 编辑 ]
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2024-4-19 18:14

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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