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)/file cat --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 [0] 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 [url=]/AUTORUNS/@0#NET.WIM[/url] (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 [9] 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 [10] 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 [04] 启动 自动安装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写入,
只要写入的长度不超过原文件长度就可以随意写入。