bao423 发表于 2010-7-27 10:32:59

Grub4dos典型菜单文件示范解读[转贴]

grub4dos是一个很强大的引导器, 想学习使用Grub4dos的朋友不要错过了,马上订阅本文章吧,目前只加了一部份注释. 欢迎有兴趣的朋友一起研究。

terminal console
color white/blue blue/yellow light-red/blue light-green/black
default 0
timeout 3
debug off
# save darddrives_orig:当前磁盘数量保存到 0x6000B
dd if=(md)2+1 of=(md)0x300+1 bs=1 count=1 skip=0x75 seek=0xb
clear
# 一些变量参数信息
# 0x8280    boot_drive
# 0x82A4    0:auto gunzip,1:no auto gunzip
# 0x60100   0:local,1:PXE,2:ISCSI,3:ERROR
# 0x60008   4:/OEM_SCSI.IMG,3:/MINIPE/OEM_SRS.ZIP,2:/OEM_SRS.ZIP
# 0x60000   2,READ /SYSTEM.WIM
# 0x60004   2,READ /NET.WIM
# 0x60110   8bit,save root
# 0x6000B   harddrives_orig
# 0x603FB   MICROPE.ISO文件大小
# 0x603FF   MICROPE.ISO所在分区号
################################
#一些常用语句介绍
#   write 0x60100 3             写内存命令使得内存0x60100的值为3
#   cat --length=0 (disk)/filecat --length=0 用于获取文件大小,也可以用于检测文件是否存在
#   fallback n如果后面的语句中有一句执行失败就跳到菜单n
#   kernel未加参数的kernel,这样扫许会出错,配合fallback n来实现转菜单。
#   fallback F同kernel也是一个固意出错的语句。
#   pause --wait=0 显示后面的信息,不等待,如果wait=2就是等待2秒,如果没有--wait参数就是一直等待。
#   checkrange xx command1 && command2    检测command1执行返回的值是否xx,如是是就执行command2
#   || 如果前面的命令返回了一个失败的值,就执行后面的语句。
#0
title Micro Windows PE (autocheck)\n\r\n\t Micro Windows PE by chenall
###########################################################
# GRUB4DOS 版本检测(通过一些新版的功能来检测),如果检测版本不符合就跳到第14个菜单。
fallback 14
# 关闭出错检测
errorcheck off
#(hd)是新版才有的功能,使用cat (hd)+1检测
cat (hd)+1
#如果返回值是23(Error while parsing number)就代表这个版本太低了,正常情况下应该返回21
checkrange 23 errnum && write 0x60100 3
#恢复
errorcheck on
#检测上面的结果,如果内存0x60100位置的值是3就说明版本不符合
#后面kernel不加参数,执行时会出错,配合前面的fall back(错误跳转)来实现菜单跳转
checkrange 3 read 0x60100 && kernel
###########################################################
###########################################################
#PXE启动检测
fallback 1
#判断启动磁盘号,如果是0X21代表它是从PXE启动的就跳。
checkrange 0x21 read 0x8280 && kernel
#
#iSCSI启动检测,在内存512K-1024K之间查找iSCSI启动标志
fallback 2
#\x69BFT=iBFT iBFT是ISCSI启动标志(并且按16字节对齐的)具体可以参考ISCSI启动规范。
cat --locate=\x69BFT --locate-align=16 (md)0x400+0x400 && kernel
#
fallback 3
#写一个值到内存位置0x60100
write 0x60100 0
pause --wait=0 Boot MicroPE From local by chenall 2009.11.11
#文件定位##############################
#检测当前root下是否有指定文件,有就跳到下一菜单
cat --length=0 /WXPE/WINPE.IMG && kernel
#如果上面没有找到就全盘查找,并设置为ROOT
find --set-root /WXPE/WINPE.IMG && kernel
#如果上面还是没有找到就找ISO文件
find --set-root /boot/MicroPE.ISO
#找到了ISO文件,加载这个ISO文件
pause --wait=0 Boot MicroPE With /boot/MicroPE.iso......
#先使用普通的方式映射(比较快),如果不行就加载到内存
map /BOOT/MICROPE.ISO (hd32) || map --mem /BOOT/MICROPE.ISO (hd32)
map --hook
#可选语句,保存ISO文件所在分区号(用于进入PE后确定使用的ISO文件磁盘,因为有可能有多处存在)
cat --length=0 /BOOT/MICROPE.ISO && dd if=(md) of=(md) bs=1 count=4 skip=0x8290 seek=0x603FB
root (hd32)
cat --length=0 /MINIPE/EXT.ZIP
dd if=(md) of=(md) bs=1 count=1 skip=0x829e seek=0x603FF
kernel
#1
title
pause --wait=0 Boot MicroPE From PXE by chenall 2009.11.11
pause --wait=0 Loading WINPE.IMG ......
#如果内存小于120MB,直接读取(需要读两次),否则只需要读一次
checkrange 0x1E000:-1 read 0x8298 && write 0x82a4 1
map --mem=0xB000 /WXPE/WINPE.IMG (rd) || map --mem=0xB000 /MicroPE_PXE.ISO (rd)
write 0x82a4 0
write 0x60100 1
map --mem (rd)/WINPE.IMG (hd0) || map --mem (rd)+1 (hd0)
fallback 3
fallback F
#2
title
pause --wait=0 Bootting MicroPE From iSCSI ......
write 0x60100 2
fallback 3
fallback F
#3
title
pause --wait=0 Loading WINPE.IMG and EXT.ZIP ......
checkrange 0,2 read 0x60100 && map --mem /WXPE/WINPE.IMG (hd0)
cat --length=0 /MINIPE/EXT.ZIP || map --unmap=0xa0
map (hd0) (hd1) && pause --wait=0
map (hd1) (hd) && pause --wait=0
map --hook
#定位外置程序路径/MINIPE/EXT.ZIP,如果没有找到就启动失败
cat --length=0 /MINIPE/EXT.ZIP || find --set-root --ignore-floppies /MINIPE/EXT.ZIP
#保存当前ROOT
dd if=(md) of=(md) bs=1 count=8 skip=0x829c seek=0x60110
#查找OEM_SCSI.IMG和OEM_SRS.ZIP
errorcheck off
find --set-root --ignore-floppies --ignore-cd /OEM_SRS.ZIP || find --set-root --ignore-floppies --ignore-cd /MINIPE/OEM_SRS.ZIP
checkrange 0 errnum || find --set-root --ignore-floppies --ignore-cd /OEM_SCSI.IMG
errorcheck on
cat --length=0 /OEM_SCSI.IMG && write 0x60008 4
cat --length=0 /MINIPE/OEM_SRS.ZIP && write 0x60008 3
cat --length=0 /OEM_SRS.ZIP && write 0x60008 2
checkrange 2,3 read 0x60008 && dd if=(md) of=(md) bs=1 count=4 skip=0x8290 seek=0x60010
checkrange 2 read 0x60008 && map --mem /OEM_SRS.ZIP (fd1)
checkrange 3 read 0x60008 && map --mem /MINIPE/OEM_SRS.ZIP (fd1)
checkrange 4 read 0x60008 && map --mem /OEM_SCSI.IMG (fd1)
#还原ROOT
dd if=(md) of=(md) bs=1 count=8 skip=0x60110 seek=0x829c && root ()/MINIPE
map --mem (hd0,0)/EXT.IMG (fd2)
##如果外置程序所在磁盘的BIOS号是0-3或0x80-0x90,就把这个磁盘映射为(hd1)备用.
##checkrange 0 read 0x82a0 && map ()+1 (hd)
##checkrange 2 read 0x60100 && map ()+1 (hd1)
map --hook
#准备EXT.ZIP
cat --length=0 /EXT.ZIP
dd if=(md)0x41+1 of=(fd2)/_EXT.ZIP bs=1 count=4 skip=0x90
map --mem=0xB000 /EXT.ZIP (rd)
dd if=(rd)+1 of=(fd2)/_EXT.ZIP bs=1 seek=4
pause --wait=0 Modify configuration information
#以下语句用于修改CONFIG.SYS让它加载UNDI_DRV.EXE.默认不加载,使用PXE启动时通过修改特定字符让它加载.
checkrange 1 read 0x60100 && write (fd2)/config.sys devi
#设置DOS变量(1.PXE;2.iSCSI;0.本地)
checkrange 2 read 0x60100 && write --offset=0x0 (hd0,0)/_SETENVI.BAT \r\nset boot=2\r\n
checkrange 1 read 0x60100 && write --offset=0x0 (hd0,0)/_SETENVI.BAT \r\nset boot=1\r\n
checkrange 0 read 0x60100 && write --offset=0x0 (hd0,0)/_SETENVI.BAT \r\nset boot=0\r\n
checkrange 4 read 0x60008 && write --offset=0x40 (hd0,0)/_SETENVI.BAT \r\nset srs=OEM1\r\n
#如果DEBUG开启显示DOS的启动菜单以方便错误处理
checkrange 2 debug && write --offset=0x14 (fd2)/msdos.sys 1
checkrange 2 debug && write --offset=0x10 (hd0,0)/_SETENVI.BAT \r\nset debug=1\r\n
checkrange 0 read 0x60100 && fallback 4
checkrange 0xa0:0xff read 0x82a0 && fallback 15
checkrange 0 read 0x60100 && kernel
#把PXE启动的IP地址信息传到DOS下
dd if=(md)0x41+1 of=(fd2)/IP.BIN bs=1 count=12 skip=0x84
cat --length=0 (hd0,0)/WXPE/SYSTEM/SYSTEM.WIM || write 0x60000 2
cat --length=0 (hd0,0)/WXPE/NET/NET.WIM|| write 0x60004 2
fallback 4
fallback F

#4 模块化跳转
title
fallback 5
checkrange 2 read 0x60000 && kernel
fallback 6
checkrange 2 read 0x60004 && kernel
fallback 13
checkrange 4 read 0x60008 && kernel
fallback 12
checkrange 2,3 read 0x60008 && kernel
fallback 7
map --mem=0xB000 /SRS.ZIP (rd) && kernel
fallback 11
map --mem=0xB000 /F6.ZIP (rd) && kernel
fallback 13
fallback F
#5 system.wim部份
title
write 0x60000 0
pause --wait=0 Loading SYSTEM.WIM......
map --mem=0xB000 /SYSTEM.WIM (rd)
cat --length=0 (rd)+1
pause --wait=0 Writing SYSTEM.WIM to (hd0,0)/system.bin ......
#写system.wim的长度信息到(hd0,0)/system.bin
dd if=(md)0x41+1 of=(hd0,0)/system.bin bs=1 count=4 skip=0x90
#写SYSTEM.WIM文件内容到(hd0,0)/system.bin(从第4个字节开始写),如果写入成功就设置一个变量
dd if=(rd)+1 of=(hd0,0)/system.bin bs=1 seek=4 && write --offset=0x20 (hd0,0)/_SETENVI.BAT \r\nset system=1\r\n
fallback 4
fallback F
#6 net.wim部份,语句功能请参考上面
title
write 0x60004 0
pause --wait=0 Loading @0#net.wim......
map --mem=0xB000 /AUTORUNS/@0#NET.WIM (rd)
cat --length=0 (rd)+1
pause --wait=0 Writing @0#net.wim to (hd0,0)/net.bin......
dd if=(md)0x41+1 of=(hd0,0)/net.bin bs=1 count=4 skip=0x90
dd if=(rd)+1 of=(hd0,0)/net.bin bs=1 seek=4 && write --offset=0x30 (hd0,0)/_SETENVI.BAT \r\nset net=1\r\n
fallback 4
fallback F
#7 检查是否存在外置驱动包,如果有的话自动加载.(SRS.ZIP)
title
fallback 8
pause --wait=0 Loading SRS.ZIP......
cat --length=0 (rd)+1
dd if=(md)0x41+1 of=(fd2)/_SRS.ZIP bs=1 count=4 skip=0x90
dd if=(rd)+1 of=(fd2)/_SRS.ZIP bs=1 seek=4
write --offset=0x40 (hd0,0)/_SETENVI.BAT \r\nset srs=SRS\r\n
fallback F
#8
title
#如果内存大于500MB就设置一个变量(用于自动把镜像转到128MB).需开启高级功能才生效
checkrange 512 read 0x60108 && write --offset=0x50 (hd0,0)/_SETENVI.BAT \r\nset to128=1\r\n
dd if=(md)0x300+2 of=(hd0,0)/_SETENVI.BAT bs=1 count=5 skip=0x3FB seek=0x7FB && pause --wait=0
map (fd2) (fd0)
map --unmap=2
map --rehook
checkrange 2 debug && pause Press any key to continue . . .
pause --wait=0 Booting... && chainloader (fd0)/io.sys
#9
title SET DEBUG mode\n\r\n\tTrun on/off debug level
write 0x60104 0
checkrange 2 debug && write 0x60104 2
checkrange 2 read 0x60104 && debug off
checkrange 0 read 0x60104 && debug on
clear
checkrange 2 debug && pause Debug is now on ...
checkrange 0 debug && pause Debug is now off ...
#10
title Enable advanced mode (test)
write 0x6010c 888
checkrange 0x7d000:-1 read 0x8298 && write 0x60108 512
pause Advanced Mode is enabled
#11
title
fallback 8
pause --wait=0 Loading F6.ZIP......
cat --length=0 (rd)+1
dd if=(md)0x41+1 of=(fd2)/_SRS.ZIP bs=1 count=4 skip=0x90
dd if=(rd)+1 of=(fd2)/_SRS.ZIP bs=1 seek=4
write --offset=0x40 (hd0,0)/_SETENVI.BAT \r\nset srs=F6\r\n
map --mem (fd2)/bat/F6.gz (fd1)
map --hook
fallback F
#12
title
fallback 8
pause --wait=0 Loading OEM_SRS.ZIP......
dd if=(md)0x300+2 of=(fd2)/_SRS.ZIP bs=1 count=4 skip=0x10
dd if=(fd1) of=(fd2)/_SRS.ZIP bs=1 seek=4
write --offset=0x40 (hd0,0)/_SETENVI.BAT \r\nset srs=OEM\r\n
map --mem (fd2)/bat/F6.gz (fd1)
map --hook
fallback F
#13
title
fallback 8
checkrange 1,2 read 0x60100 && kernel
map (fd2) (fd0)
map --unmap=2
map --rehook && configfile (fd0)/menu.lst
fallback F
#14
title
pause --wait=0 Error!
pause GRUB4DOS Version mismatched!
#15
title
#如果虚拟光驱中,设置一个变量,使得启动时优先使用光驱或ISO上的外置程序.
fallback 4
write --offset=0x60 (hd0,0)/_SETENVI.BAT \r\nset CDROMEX_=1\r\n
read 0x603fb && kernel
#获取虚拟ISO文件的大小.
map () (hd30)
map --hook
cat --length=0 (hd30)+1
checkrange 0xfb0400 read 0x82b0 && kernel
dd if=(md) of=(md) bs=1 count=4 skip=0x82b0 seek=0x60110
dd if=(md) of=(md) bs=1 count=4 skip=0x8290 seek=0x60114
dd if=(md)0x300+2 of=(hd0,0)/_SETENVI.BAT bs=1 count=8 skip=0x110 seek=0x7F0
map (hd30) (hd30)
map --hook
fallback F

这是一个比较完善的Grub4Dos让系统从光驱启动的菜单,支持多光驱:
title 光驱启动通用菜单
cdrom --init || cdrom --stop
map --rehook
geometry (hd999) || pause --wait=0   
;本句访问一个不存在磁盘用以
;解决光驱驱动异常的问题
;|| pause 的目的是免去errorcheck
off
;的使用,避免退到命令行。
root (cd0)|| commandline            
;没有cdrom时,执行到此转入命令行,
;当然也可考虑用跳转命令执行其他
菜单
chainloader (cd0) && boot
chainloader (cd1) && boot
chainloader (cd2) && boot
chainloader (cd3) && boot
chainloader (cd4) && boot
chainloader (cd5) && boot
chainloader (cd6) && boot
chainloader (cd7) && boot
chainloader (cd8) && boot
chainloader (cd9) && boot

Grub4dos高级功能
虚拟磁盘
GRUB4DOS中的虚拟磁盘是由map命令实现的。map命令的功能介绍如下:
磁盘交换
map命令在GRUB Legacy中的也存在,它是用作磁盘交换。
比如说,你有两只硬盘,但两只硬盘上均有可启动的系统。在第一只硬盘上启动
时,不需要特殊的处理,直接用chainloader装载启动扇区就可以了。不过,如果
要从第二只硬盘上启动,那么单单用chainloader是不够的,这是因为很多操作系
统都缺省地从第一只硬盘上装载启动所需的文件,如果文件不在其上,系统便不
能顺利地读取,从而导致启动失败。
一个原始的解决方法是在BIOS中修改启动顺序,把需要启动的硬盘放到最前面。
那么,重启计算机后该硬盘便会成为第一只硬盘,从而可以正常启动。
GRUB中的map命令便是为了解决这个问题而设计的,它可以在运行时交换磁盘,而
无需修改BIOS。例如:
title Boot First Partition on Second Disk map (hd0) (hd1) map (hd1)
(hd0) chainloader (hd1,0)+1 boot   
在该例子中,使用了map命令实现了(hd0)和(hd1)的交换。要注意的是,交换是在
命令boot后才生效的。因此在chainloader命令中,读取的仍然是第二只硬盘。
建立虚拟磁盘
在GRUB4DOS中,大大地扩展了map命令的用法。利用该命令可以建立虚拟磁盘,例
子:
把(hd0,0)根目录下的aa.dsk文件映射为第二只硬盘,并且使用原来硬盘上的系统
启动:   title Create Virtual Disk map (hd0,0)/aa.dsk (hd1) root
(hd0,0) chainloader +1 boot   
把(hd0,0)根目录下的aa.dsk文件映射为第一只硬盘,原来的第一只映射为第二只
硬盘,并且从aa.dsk里虚拟出来的磁盘中启动:   title Boot From Virtual
Disk map (hd0,0)/aa.dsk (hd0) map (hd0) (hd1) map --hook root (hd0,0)
chainloader +1 boot   在上面提到,map命令的映射不是马上起作用的。但是,
要从虚拟磁盘中启动,就必须从中读取数据,因此需要使映射提前起效。在以上
的例子中,map --hook的作用便是使前面map命令指定的映射立刻生效。
把(hd0,0)根目录下的aa.img文件映射为第一只虚拟软盘,并从中启动:   title
Boot From Virtual Floppy map (hd0,0)/aa.img (fd0) map --hook root (fd0)
chainloader +1 boot   
使用这种方式进行映射后,虚拟磁盘的内容和影像文件的内容是同步的,也就是
说,如果你修改了虚拟磁盘的内容,影像文件也同样被更新。如果你重启了机器
,该修改的效果仍然存在。
在使用这种方式进行映射时,影像文件在磁盘上的存放必须是连续的。
GRUB4DOS中建立的虚拟磁盘,包括以下所说的内存盘,都是通过截取INT 13来实
现的。因此在启动了操作系统后,如果该系统是通过INT 13来访问磁盘的,例如
各类的DOS,那么在进入系统后仍然可以访问虚拟盘。如果系统是采用其它方式来
访问磁盘,例如Linux,各类Unix和Windows NT系列的操作系统,那么在进入系统
后便不能访问虚拟盘。Windows 9X系列的操作系统比较特殊,它通常是使用保护
模式的驱动来访问磁盘,但当它找不到合适的驱动时,会依旧使用INT 13来访问
磁盘,因此,在Windows 9X下也可以访问虚拟磁盘。
建立虚拟内存盘
用map也可以建立虚拟内存盘,其用法和以上的很相似,你只需要在map建立虚拟
盘的命令中加上--mem参数就行了。例子:
把(hd0,0)根目录下的aa.dsk文件映射为第一只硬盘,原来的第一只映射为第二只
硬盘,并且从aa.dsk里虚拟出来的磁盘中启动:   title Boot From Virtual
Disk map --mem (hd0,0)/aa.dsk (hd0) map (hd0) (hd1) map --hook root
(hd0,0) chainloader +1 boot   
把(hd0,0)根目录下的aa.img文件映射为第一只虚拟软盘,并从中启动:   title
Boot From Virtual Floppy map --mem (hd0,0)/aa.img (fd0) map --hook root
(fd0) chainloader +1 boot   
使用了该映射方式,影像文件的内容是装载到内存后才进行映射。这意味着,你
必须有足够的内存来存放影像和启动系统。而且,虚拟磁盘和影像文件是分离的
,对虚拟磁盘所作的修改不会被更新到影像文件中。
在这种映射方式中,影像文件在磁盘上的存放不需要是连续的。
自动生成MBR
影像文件有两种类型。一种是文件系统影像,它里面只包含某一个文件系统的数
据。另一种是磁盘影像,它里面包含了类似于物理硬盘的结构,也就是,影像以
MBR开始,然后才是文件系统的数据。对于虚拟内存盘,其结构是类似于真实硬盘
的,因此在使用map命令进行映射时,应该使用磁盘影像。
GRUB4DOS考虑到了这个问题。为了让用户使用更加方便,GRUB4DOS作了如下的改
进:当把磁盘影像读入内存时,程序会检测其结构,如果发现是文件系统影像,
那么在它前面自动生成MBR,把它变为磁盘影像。因此,无论用户选择使用文件系
统影像还是磁盘影像,装载到内存后都会变成正确的格式。
自动生成MBR还有一个应用,就是直接从硬盘上的装载分区,从而生成虚拟磁盘。
例如:
title Load Partition From Disk map --mem (hd0,0)+1 (hd0) map (hd0)
(hd1) map --hook root (hd0,0) chainloader +1 boot   
该菜单的功能是把硬盘上第一个分区的内容装载到内存,并且自动在其前面加上
MBR而生成虚拟磁盘。然后,把该虚拟磁盘映射为第一只硬盘,原来的硬盘映射为
第二只硬盘。最后,从虚拟磁盘中启动。
在使用该菜单启动后,系统分区的内容和好像和原来一样,但这时实际是使用在
内存里的虚拟磁盘。对分区的修改在重启机器后便会消失。
该菜单是把整个分区的内容装载到内存,要确定内存足够大,否则命令不会成功

在map命令中,(hd0,0)+1是指整个(hd0,0)分区,而不是(hd0,0)的第一个扇区。
这种表示只是在map命令中适用,在其它的地方,(hd0,0)+1 还是原来的意义。
虚拟设备(md)
在GRUB4DOS中,你可以用设备(md)来访问整个内存,就和用(nd)访问网络设备,
用(cd)来访问光盘类似。
GRUB4DOS也扩展了cat命令,它可以用--hex来以十六进制输出,也可以用--
locate=STRING来在文件中搜索字符串。
例子:
cat --hex (hd0)+1   以十六进制形式显示第一只硬盘的MBR。
cat --hex (hd0,0)+1   以十六进制形式显示第一只硬盘第一个分区的启动扇区
cat --hex (md)+2   以十六进制形式显示内存开始1K的内容,这里其实是中断向
量表。
cat --hex (md)0x800+1   以十六进制形式显示内存从0x800 * 512 = 1M 开始
512字节的内容,也就是从扩展内存开始的512字节。
虚拟设备(rd)
用虚拟设备(md)可以访问从地址0开始的物理内存,而使用(rd)则可以访问从某一
地址开始的内存。
map --rd-base=ADDR   用来设置(rd)内存设备的开始地址(以字节为单位)。
map --rd-size=SIZE   用来设置(rd)内存设备的长度(以字节为单位)。
当把grub.exe作为linux内核启动时,可以用指定初始盘。进入grub后,(rd)设备
的开始地址和长度自动设置为初始盘的地址和长度。因此,可以在grub中用(rd)
设备来访问初始盘。
map --ram-drive=RD   
用来设定访问(rd)内存设备的BIOS设备名。缺省值是0x7F,表示(rd)对应的虚拟
盘是软盘设备。如果(rd)对应的虚拟盘是硬盘设备,那么需要设置RD, 使得
0x80< RD < 0xFF。
map的其他参数
* --status
用于显示当前的磁盘映射。   map --status   
* --floppies=M, --harddrives=N
指定软盘/硬盘的数目。   map --harddrvies=2   使用该命令后,本地硬盘的数
目设为2。
* --memdisk-raw=RAW
RAW取值0或1(缺省是1)。RAW=0时,使用int15/ah=87h读扩展内存。RAW=1时,使
用内部的函数来读扩展内存。   map --memdisk-raw=0   
* --safe-mbr-hook=SMH ,--int13-scheme=SCH
这两个参数是为了在Windows 9X下能正常使用虚拟盘而设的。
SMH取值0或1(缺省是1),当你在Windows 9X下使用虚拟盘时出现问题时,可以试
试使用以下的命令:   map --safe-mbr-hook=0   
SCH取值也是0或1(缺省是1),当你在Windows 9X下使用虚拟盘时出现问题时,也
可以试试使用以下的命令:   map --int13-scheme=0   
* --read-only
使用了该参数后,当前进行映射的磁盘被设为只读模式。   map --mem --read-
only (hd0,0)/aa.dsk (hd1)   
* --fake-write
使用了该参数后,当前进行映射的磁盘看似可写,但写入的内容均被丢弃。   
map --mem --fake-write (hd0,0)/aa.dsk (hd1)   
* --heads=H, --sectors-per-track=S
一般来说,map命令可以正确地计算出影像文件中使用的磁盘参数。如果你想手动
设置,那么可以使用这两个选项。   map --mem --heads=63 --sectors-per-
track=255 (hd0,0)/aa.dsk (hd1)   
利用memdisk生成虚拟内存盘
memdisk是syslinux中的一个工具,利用它也可以生成虚拟内存盘:
title Create virtual disk using memdisk kernel (hd0,0)/memdisk initrd
(hd0,0)/aa.dsk boot   
该命令把aa.dsk装入内存生成虚拟内存盘,该虚拟盘作为第一只硬盘,原来硬盘
的序号向后移动。最后,从虚拟盘中启动。这一系列的操作都是在memdisk内完成
的,GRUB的任务只是把aa.dsk装入内存,然后把装载的地址传递给memdisk。
如果只有一只硬盘,那么以上的操作可以用以下的命令完成:
title Create virtual disk using map map --mem (hd0,0)/aa.dsk (hd0) map
(hd0) (hd1) map --hook root (hd0,0) chainloader +1 boot   
map和memdisk的区别:
* map是GRUB4DOS内置的功能,而memdisk是一个外部的程序
* map可以直接映射磁盘上的文件,而memdisk必须要把文件装载到内存里。
* map可以把影像文件映射为第二只硬盘,而而memdisk只能映射为第一只硬盘。
* map有自动生成MBR的功能,而memdisk没有。因此memdisk只能使用磁盘影像,
不能使用文件系统影像。
光驱相关
在GRUB4DOS中使用光驱
用以下的命令可以初始化光驱:   cdrom --init   初始化后,接着使用map --
hook,那么就可以用(cd0),(cd1)等来访问光驱。
GRUB中支持的光驱设备是(cd),它代表用可启动光盘启动GRUB时(光盘的制作方法
在下一节介绍),用于启动的光驱设备。该设备可直接使用,而不需要使用以上的
命令来初始化。
用以下的命令可以停止化光驱:   cdrom --stop   在停止光驱后,还需要用map
--unhook来取消map --hook的效果。
用以下的命令可以指定搜索的端口:   cdrom --add-io-ports=0x03F601F0   
以下是缺省的搜索端口:0x03F601F0, 0x03760170, 0x02F600F0, 0x03860180,
0x6F006B00, 0x77007300。
在初始化光驱后,可以用blocklist的方式来访问其内容:
cat --hex (cd0)16+2   光驱中使用的扇区大小是2048。
另外,iso9660文件系统驱动程序支持Rock-Ridge扩展,但不支持Joliet扩展,在
读取Joliet扩展的光盘是可能会出现问题。
另外,你可以以用chainloader命令来从光驱中启动:
chainloader (cd0) boot   
一个完整的从第一只光驱启动的例子:
title Boot From First CDROM cdrom --init map --hook chainloader (cd0)
boot   
利用GRUB4DOS制作可启动光盘
在GRUB中,可以利用 stage2_eltorito 来制作启动光盘:
mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4
-boot-info-table -o grub.iso iso
stage2_eltorito和menu.lst应该放在光盘的/boot/grub目录里。
在GRUB4DOS中,可以利用 grldr 来制作启动光盘。制作方法有两种:
mkisofs -R -b grldr -no-emul-boot -boot-load-seg 0x1000 -o bootable.iso
iso_root
mkisofs -R -b grldr -no-emul-boot -boot-load-size 4 -o grldr.iso
iso_root
grldr和menu.lst应该放在光盘的根目录里。
第一种方法告诉 BIOS,希望它能够装入整个 GRLDR 文件到内存。装入内存后,
BIOS 还应该正确设置堆栈,使得不至于把堆栈设置到 GRLDR 的程序体内,造成
冲突。一般情况下,BIOS 做到这一点很容易,因为它可以设置堆栈指针为装入的
起始地址。但也不排除存在 BUGGY BIOS 的可能性。
有些 BIOS 不完全符合可启动的 CDROM 规范,比如 VirtualPC 的就是的。这类
BIOS 只是装入了一部分 GRLDR 扇区到内存,典型的可能只装入了一个扇区
(2048 字节的大扇区)到内存。不过我们的代码已经替这些 BUGGY BIOS 打了补
丁。只要这些 BIOS 能够设置正确的堆栈,不至于和装入内存中的 GRLDR 扇区数
据产生冲突就 OK 了。
也就是说,上述第一种制作光盘的方法,应该没有多大问题了。这种方法很有可
能适应于所有的 BIOS。
第二种方法本身就只要求 BIOS 装入一个 CDROM 扇区到内存(等同于 4 个 512
字节的小扇区)。这种方法是最保守的,没有理由会失败了。微软的 win2000 启
动光盘就是这么做的,isolinux 和 stage2_eltorito 也都是这么做的。如果这
种方法失败了,那么 win2000,isolinux 和 stage2_eltorito 应该都会失败的

对于第二种方法,我们不需要 -boot-info-table 这个参数。但是允许你用这个
参数(用了和没用是一样的,我们的引导代码将忽略由这个参数所传递的数据结
构)。
对于第一种方法也一样,不需要 -boot-info-table 这个参数,同时也是允许你
用这个参数(用了和没用是一样的,我们的引导代码将忽略由这个参数所传递的
数据结构)。
这样,stage2_eltorito 就可以完全用 grldr 来代替了。
脚本支持
GRUB4DOS中有实现了简单的脚本支持。目前实现了 && 和 || 两种操作:
command1 && command2   只有当 command1 的返回值是真时,command2 才被执

command1 || command2   只有当 command1 的返回值是假时,command2 才被执

目前不支持操作符的嵌入使用。
例子:
is64bit && default 0 is64bit || default 1   
如果is64bit命令返回值是真,那么缺省的菜单项是0,否则,缺省的菜单项是1。

[分享]GRUB4DOS一个比较变态的用法.利用GRUB4DOS的map功能来中转文件.使得DOS下可以访问
例子:

map --mem /minipe/system.wim (hd1)
map --hook

说明:把/MINIPE.SYSTEM.WIM文件映射为(hd1)硬盘.
GRUB4DOS会把这个文件的内容作为一个磁盘分区(hd1,0).

也就是把一个文件虚拟成一个分区.

然后进到入DOS后,利用一个磁盘工具把上面的(hd1,0)分区保存为一个文件.
例子:用todisk
todisk 2:1=q to (c:\system.wim)
把第二磁盘的第一分区保存为system.wim(即还原过程).

这个方法在某些情况下有用处.
另,由于1个磁盘扇区是512字节,所以最后得到的文件会是512字节的倍数(不足补00),所以只适用于对文件内容要求不是很严格的地方.

关于&&用法
使用grub4dos 2008.8.10版,不用加errorcheck off和errorcheck on就能正常运行.发现菜单可以循环选择了.

用u盘启动,不论识别为A:或者C:,以下命令都可以启动winxp.
title 启动 Windows NT/2K/XP/2K3
root && map (hd0) (hd1)
root && map (hd1) (hd0)
root && map --hook
find --set-root /ntldr
chainloader /ntldr

grubhere.id 是u盘上的1个空文件.

GRUB4DOS高级用法
2010-02-04 21:41

title 【 02 】恢复系统
map --mem /boot/backup.img (fd0)
map --hook
#硬盘上查找/sowind/warning.sys
find --ignore-cd --ignore-floppies /sowind/warning.sys (bd)/boot/ghostid
dd if=(md) of=(fd0)/bd.bat bs=1 count=5 skip=0x4FF00 seek=0x11
find --ignore-cd --ignore-floppies /boot/WTool.lst (bd)/boot/ghostid
dd if=(md) of=(fd0)/sd.bat bs=1 count=5 skip=0x4FF00 seek=0x11
chainloader (fd0)+1
rootnoverify (fd0)
─────────────────
autoexec.bat的内容
@echo off
call rst.bat
─────────────────
sd.bat的内容
@ECHO OFF
set S=+::--
─────────────────
bd.bat的内容
@ECHO OFF
set B=+::--
─────────────────
rst.bat的内容
@ECHO OFF
CALL SD.BAT
CALL BD.BAT
GHOST -clone,mode=pload,src=%B%:\Sowind\sowind.wzs:1,dst=%S% -fro -nousb -noide -crcignore -sure -rb
CLS
func -r
::恢复系统
─────────────────
title (3) 克隆安装 Windows XP 到硬盘第一分区
map --mem /ntdos.ud (fd0)
map --hook
checkrange 0x80 read 0x8280 && dd if=(fd0)/autoexec.bat of=(fd0)/autoexec.bat bs=1 count=1 skip=14 seek=26
checkrange 0x80 read 0x8280 || dd if=(fd0)/autoexec.bat of=(fd0)/autoexec.bat bs=1 count=1 skip=15 seek=26
chainloader (fd0)+1
rootnoverify (fd0)
read读取内存数值。
0x8280 内存位置 ,这个位置是存放了当前的启动设备的磁盘号码
0x80第一个硬盘。
─────────────────
title 启动 自动安装XP
map --mem (ud)/img/ghostxp.img (fd0)
map --hook
checkrange 0x80 read 0x8280 && dd if=(fd0)/autoexec.bat of=(fd0)/autoexec.bat bs=1 count=1 skip=19 seek=31
checkrange 0x80 read 0x8280 || dd if=(fd0)/autoexec.bat of=(fd0)/autoexec.bat bs=1 count=1 skip=20 seek=31
chainloader (fd0)+1
rootnoverify (fd0)
我的autoexec.bat:
@echo off
set abc=12
call resx.bat
我的res1.bat:
ghost -clone,mode=pload,src=1:1\ghost\axiangxp.gho:1,dst=2:1 -sure -rb
我的res2.bat:
ghost -clone,mode=pload,src=2:1\ghost\axiangxp.gho:1,dst=1:1 -sure -rb
─────────────────
很奇怪,非要用DD。。。
直接用write不是更简单吗?想写入什么内容都可以。
write --offset=12 (fd0)/autoexec.bat res1.bat\r\n
write --offset=12 (fd0)/autoexec.bat res2.bat\r\n
autoexec.bat内容只要如下
@echo off
:::::::::::::::::::::::::::::::::::::::::::::::

注::::::::::::::::::::::::::::::::::::::::::::::::是预留的空位,供write写入,
只要写入的长度不超过原文件长度就可以随意写入。

[转载自:chenall's blog http://chenall.net/post/tag/scsi/]

[ 本帖最后由 bao423 于 2010-8-3 17:32 编辑 ]

天涯海角1216 发表于 2010-7-27 10:54:55

这个很不错,支持!
特别是grub的一些特殊用法,请楼主详细贴上,谢谢!

pseudo 发表于 2010-7-27 11:46:17

建议楼主给出原帖地址。

这个是MicroPE的菜单,现在有了外置命令,许多写法可以大为简化了。
新的写法参见0PE、CSPE的菜单。

liuzhaoyzz 发表于 2010-7-27 12:25:40

说到程序菜单,pseudo就笑了,能把g4d用的出神入化炉火纯青的就是他了,甚至超过了不点和chenall。哈哈。

renchmin 发表于 2010-7-27 13:59:34

很好的教程啊,支持了啊。

lzy157 发表于 2010-7-27 14:02:35

很想学,可是很复杂,一时难已消化,现先收藏后学习。

念青 发表于 2010-8-3 07:54:35

未提及mem --top参数。

pseudo的菜单示例可以在哪里找到?

33445566 发表于 2010-8-3 08:05:40

G4D越来越复杂,收藏慢慢学

mmkkqq_123 发表于 2010-8-3 09:00:43

收起来,慢慢学习。

爱琴海的忧郁 发表于 2010-8-3 10:19:08

好文章啊,写的非常深入,慢慢研究

oneuu 发表于 2010-8-3 15:32:13

这么好的文章才这几个人回帖,有会的吧。。。谢楼主。。。如能补充更加完整的话。。
我建议此帖加入精华帖。。。。谢谢斑主。。。呵呵

molingjian 发表于 2010-8-3 16:22:55

值得学习!! 很详细啊

eyinhe 发表于 2010-8-4 10:22:15

正好来学习一下,谢谢!

2010蓝天白云l 发表于 2010-8-4 15:33:16

多谢楼主,学习了,收藏后慢慢消化

lsp19880301 发表于 2010-8-5 20:17:09

呵呵。看了楼主的教程。又有所收获了。。谢谢

Hcrty 发表于 2010-8-5 21:55:02

呵呵...谢谢楼主了
这个教程很不错

lsp19880301 发表于 2010-8-14 10:01:52

楼主,我想问问(md)这个用法。。我在看人家的menu.lst的时候老是被这个 (md)困住了。。能不能详细说说怎么用,并要注意些什么?
如:从http://bbs.wuyou.net/forum.php?mod=viewthread&tid=164614&extra=page%3D3 贴子11楼看到的 ,下面的菜单我意思我大致知道。
grub4dos的menu.lst
default 2                                                默认第3个菜单
timeout 10                                             延时10
root (hd0,1)                                          指定根目录第二个主分区

gfxmenu /boot/grub4dos/message                        用gfxmenu加载message
configfile (md)4+8                                    ??????不是明白。不知道配置什么
#configfile /boot/grub4dos/menu_gfx.lst

title Microsoft windows XP                         菜单条
chainloader /boot/xor_winxp.bin                        装载 /boot/xor_winxp.bin

title Microsoft windows vista                      同上类似
chainloader /boot/xor_vista.bin
::::
::::

bao423 发表于 2010-8-14 12:55:11

回复 #17 lsp19880301 的帖子

它表示了(md) 设备上,跳过4个扇区(即从第5个扇区起始的),且,连续8个扇区大的扇区块所组成的文件。
显然,其中(md)表示的即是文件所在的设备为grub4dos全内存设备(md),而后面的数字 4 代表了文件在此设备上的起始扇区位置(起始扇区都从零计数,取零时可省略,如(hd0,0)+1   ),而 8则代表此文件的大小为8个扇区大。

由于grub4dos的内置菜单固定大小为4 K (即相当于8 个扇区大)。在启动后,又会被固定加载于内存物理地址 0x800处。【0x800 转换为十进制是2048(相当于4个扇区)。】
因此,(md)4+8通常也就表示了加载到内存0x800处的4k大的内置菜单文件。
(默认内置菜单的数据是小于512字节的,因此对于默认内置菜单,逻辑上一般情况下(md)4+1也可引用它)
configfile (md)4+8 可用于从menu.lst菜单返回grldr内置菜单,具体命令如下:
title 启动内置菜单
errorcheck off
configfile (md)4+8
errorcheck on
commandline

[ 本帖最后由 bao423 于 2010-8-14 13:11 编辑 ]

小施 发表于 2010-11-5 13:48:43

才发现有这么好的帖子

一地鸡毛 发表于 2010-11-6 20:52:23

好贴,我顶,我再顶。

银翼天涯 发表于 2010-11-16 23:01:09

不错 可惜我现在还看不懂

wlq127 发表于 2010-11-17 14:14:54

好文章啊,写的非常深入,慢慢。学习。。

虾子丙 发表于 2010-11-25 16:57:41

先顶再看!

想了解下!

green 发表于 2010-11-30 17:20:52

收藏起来慢慢学习,谢谢。

fjxplsy 发表于 2010-12-3 21:02:32

要是P大能出手写写,大家就更有福啦!

leafeg 发表于 2010-12-7 11:57:46

支持楼主,我现在有一点纠结的是,g4d 能不能不加载内置菜单直接加载外置的。我的grub4dos菜单还要经过内置菜单加载,纠结啊!!!
修改外置菜单默认指向没用,还是会先加载内置的!!

sht123960585 发表于 2010-12-25 00:53:46

回复 #26 leafeg 的帖子

先加载内置,内置中直接指向外置,这样也没什么不好啊,内置菜单简单点,直接指向就行了
参考最版的 grldr 的内置菜单:

pxe detect
configfile
default 0
timeout 1

title find /menu.lst, /boot/grub/menu.lst, /grub/menu.lst
        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
        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
        errorcheck on
        commandline

title commandline
        commandline

title reboot
        reboot

title halt
        halt

sht123960585 发表于 2010-12-25 00:55:22

回复 #18 bao423 的帖子

说得太好了,通俗易懂

moondust 发表于 2011-1-20 17:17:01

解释太简单了,不大看得懂。

2010yuhongxi 发表于 2011-2-14 06:23:36

回复 #1 bao423 的帖子

这个很不错,支持支持!
页: [1] 2
查看完整版本: Grub4dos典型菜单文件示范解读[转贴]