你的位置: Kiyo'Space首页 系统配置 阅读文章 欢迎留下您的足迹

Grub4dos高级功能

[ 系统配置 ] 分享

Contents

[hide]

虚拟磁盘

GRUB4DOS中的虚拟磁盘是由map命令实现的。map命令的功能介绍如下:

磁盘交换

map命令在GRUB Legacy中的也存在,它是用作磁盘交换。

比如说,你有两只硬盘,但两只硬盘上均有可启动的系统。在第一只硬盘上启动时,不需要特殊的处理,直接用chainloader装载启动扇区就可以了。不过,如果要从第二只硬盘上启动,那么单单用chainloader是不够的,这是因为很多操作系统都缺省地从第一只硬盘上装载启动所需的文件,如果文件不在其上,系统便不能顺利地读取,从而导致启动失败。

一个原始的解决方法是在BIOS中修改启动顺序,把需要启动的硬盘放到最前面。那么,重启计算机后该硬盘便会成为第一只硬盘,从而可以正常启动。

GRUB中的map命令便是为了解决这个问题而设计的,它可以在运行时交换磁盘,而无需修改BIOS。例如:

<pre> title Boot First Partition on Second Disk map (hd0) (hd1) map (hd1) (hd0) chainloader (hd1,0)+1 boot </pre>

在该例子中,使用了map命令实现了(hd0)和(hd1)的交换。要注意的是,交换是在命令boot后才生效的。因此在chainloader命令中,读取的仍然是第二只硬盘。

建立虚拟磁盘

在GRUB4DOS中,大大地扩展了map命令的用法。利用该命令可以建立虚拟磁盘,例子:

把(hd0,0)根目录下的aa.dsk文件映射为第二只硬盘,并且使用原来硬盘上的系统启动: <pre> title Create Virtual Disk map (hd0,0)/aa.dsk (hd1) root (hd0,0) chainloader +1 boot </pre>

把(hd0,0)根目录下的aa.dsk文件映射为第一只硬盘,原来的第一只映射为第二只硬盘,并且从aa.dsk里虚拟出来的磁盘中启动: <pre> title Boot From Virtual Disk map (hd0,0)/aa.dsk (hd0) map (hd0) (hd1) map –hook root (hd0,0) chainloader +1 boot </pre> 在上面提到,map命令的映射不是马上起作用的。但是,要从虚拟磁盘中启动,就必须从中读取数据,因此需要使映射提前起效。在以上的例子中,map –hook的作用便是使前面map命令指定的映射立刻生效。

把(hd0,0)根目录下的aa.img文件映射为第一只虚拟软盘,并从中启动: <pre> title Boot From Virtual Floppy map (hd0,0)/aa.img (fd0) map –hook root (fd0) chainloader +1 boot </pre>

使用这种方式进行映射后,虚拟磁盘的内容和影像文件的内容是同步的,也就是说,如果你修改了虚拟磁盘的内容,影像文件也同样被更新。如果你重启了机器,该修改的效果仍然存在。

在使用这种方式进行映射时,影像文件在磁盘上的存放必须是连续的。

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里虚拟出来的磁盘中启动: <pre> title Boot From Virtual Disk map –mem (hd0,0)/aa.dsk (hd0) map (hd0) (hd1) map –hook root (hd0,0) chainloader +1 boot </pre>

把(hd0,0)根目录下的aa.img文件映射为第一只虚拟软盘,并从中启动: <pre> title Boot From Virtual Floppy map –mem (hd0,0)/aa.img (fd0) map –hook root (fd0) chainloader +1 boot </pre>

使用了该映射方式,影像文件的内容是装载到内存后才进行映射。这意味着,你必须有足够的内存来存放影像和启动系统。而且,虚拟磁盘和影像文件是分离的,对虚拟磁盘所作的修改不会被更新到影像文件中。

在这种映射方式中,影像文件在磁盘上的存放不需要是连续的。

自动生成MBR

影像文件有两种类型。一种是文件系统影像,它里面只包含某一个文件系统的数据。另一种是磁盘影像,它里面包含了类似于物理硬盘的结构,也就是,影像以MBR开始,然后才是文件系统的数据。对于虚拟内存盘,其结构是类似于真实硬盘的,因此在使用map命令进行映射时,应该使用磁盘影像。

GRUB4DOS考虑到了这个问题。为了让用户使用更加方便,GRUB4DOS作了如下的改进:当把磁盘影像读入内存时,程序会检测其结构,如果发现是文件系统影像,那么在它前面自动生成MBR,把它变为磁盘影像。因此,无论用户选择使用文件系统影像还是磁盘影像,装载到内存后都会变成正确的格式。

自动生成MBR还有一个应用,就是直接从硬盘上的装载分区,从而生成虚拟磁盘。例如:

<pre> title Load Partition From Disk map –mem (hd0,0)+1 (hd0) map (hd0) (hd1) map –hook root (hd0,0) chainloader +1 boot </pre>

该菜单的功能是把硬盘上第一个分区的内容装载到内存,并且自动在其前面加上MBR而生成虚拟磁盘。然后,把该虚拟磁盘映射为第一只硬盘,原来的硬盘映射为第二只硬盘。最后,从虚拟磁盘中启动。

在使用该菜单启动后,系统分区的内容和好像和原来一样,但这时实际是使用在内存里的虚拟磁盘。对分区的修改在重启机器后便会消失。

该菜单是把整个分区的内容装载到内存,要确定内存足够大,否则命令不会成功。

在map命令中,(hd0,0)+1是指整个(hd0,0)分区,而不是(hd0,0)的第一个扇区。这种表示只是在map命令中适用,在其它的地方,(hd0,0)+1 还是原来的意义。

虚拟设备(md)

在GRUB4DOS中,你可以用设备(md)来访问整个内存,就和用(nd)访问网络设备,用(cd)来访问光盘类似。

GRUB4DOS也扩展了cat命令,它可以用–hex来以十六进制输出,也可以用–locate=STRING来在文件中搜索字符串。

例子:

<pre> cat –hex (hd0)+1 </pre> 以十六进制形式显示第一只硬盘的MBR。

<pre> cat –hex (hd0,0)+1 </pre> 以十六进制形式显示第一只硬盘第一个分区的启动扇区

<pre> cat –hex (md)+2 </pre> 以十六进制形式显示内存开始1K的内容,这里其实是中断向量表。

<pre> cat –hex (md)0×800+1 </pre> 以十六进制形式显示内存从0×800 * 512 = 1M 开始512字节的内容,也就是从扩展内存开始的512字节。

虚拟设备(rd)

用虚拟设备(md)可以访问从地址0开始的物理内存,而使用(rd)则可以访问从某一地址开始的内存。

<pre> map –rd-base=ADDR </pre> 用来设置(rd)内存设备的开始地址(以字节为单位)。

<pre> map –rd-size=SIZE </pre> 用来设置(rd)内存设备的长度(以字节为单位)。

当把grub.exe作为linux内核启动时,可以用指定初始盘。进入grub后,(rd)设备的开始地址和长度自动设置为初始盘的地址和长度。因此,可以在grub中用(rd)设备来访问初始盘。

<pre> map –ram-drive=RD </pre>

用来设定访问(rd)内存设备的BIOS设备名。缺省值是0x7F,表示(rd)对应的虚拟盘是软盘设备。如果(rd)对应的虚拟盘是硬盘设备,那么需要设置RD, 使得 0×80< RD < 0xFF。

map的其他参数

  • –status

用于显示当前的磁盘映射。 <pre> map –status </pre>

  • –floppies=M, –harddrives=N

指定软盘/硬盘的数目。 <pre> map –harddrvies=2 </pre> 使用该命令后,本地硬盘的数目设为2。

  • –memdisk-raw=RAW

RAW取值0或1(缺省是1)。RAW=0时,使用int15/ah=87h读扩展内存。RAW=1时,使用内部的函数来读扩展内存。 <pre> map –memdisk-raw=0 </pre>

  • –safe-mbr-hook=SMH ,–int13-scheme=SCH

这两个参数是为了在Windows 9X下能正常使用虚拟盘而设的。

SMH取值0或1(缺省是1),当你在Windows 9X下使用虚拟盘时出现问题时,可以试试使用以下的命令: <pre> map –safe-mbr-hook=0 </pre>

SCH取值也是0或1(缺省是1),当你在Windows 9X下使用虚拟盘时出现问题时,也可以试试使用以下的命令: <pre> map –int13-scheme=0 </pre>

  • –read-only

使用了该参数后,当前进行映射的磁盘被设为只读模式。 <pre> map –mem –read-only (hd0,0)/aa.dsk (hd1) </pre>

  • –fake-write

使用了该参数后,当前进行映射的磁盘看似可写,但写入的内容均被丢弃。 <pre> map –mem –fake-write (hd0,0)/aa.dsk (hd1) </pre>

  • –heads=H, –sectors-per-track=S

一般来说,map命令可以正确地计算出影像文件中使用的磁盘参数。如果你想手动设置,那么可以使用这两个选项。 <pre> map –mem –heads=63 –sectors-per-track=255 (hd0,0)/aa.dsk (hd1) </pre>

利用memdisk生成虚拟内存盘

memdisk是syslinux中的一个工具,利用它也可以生成虚拟内存盘:

<pre> title Create virtual disk using memdisk kernel (hd0,0)/memdisk initrd (hd0,0)/aa.dsk boot </pre>

该命令把aa.dsk装入内存生成虚拟内存盘,该虚拟盘作为第一只硬盘,原来硬盘的序号向后移动。最后,从虚拟盘中启动。这一系列的操作都是在memdisk内完成的,GRUB的任务只是把aa.dsk装入内存,然后把装载的地址传递给memdisk。

如果只有一只硬盘,那么以上的操作可以用以下的命令完成:

<pre> title Create virtual disk using map map –mem (hd0,0)/aa.dsk (hd0) map (hd0) (hd1) map –hook root (hd0,0) chainloader +1 boot </pre>

map和memdisk的区别:

  • map是GRUB4DOS内置的功能,而memdisk是一个外部的程序
  • map可以直接映射磁盘上的文件,而memdisk必须要把文件装载到内存里。
  • map可以把影像文件映射为第二只硬盘,而而memdisk只能映射为第一只硬盘。
  • map有自动生成MBR的功能,而memdisk没有。因此memdisk只能使用磁盘影像,不能使用文件系统影像。

光驱相关

在GRUB4DOS中使用光驱

用以下的命令可以初始化光驱: <pre> cdrom –init </pre> 初始化后,接着使用map –hook,那么就可以用(cd0),(cd1)等来访问光驱。

GRUB中支持的光驱设备是(cd),它代表用可启动光盘启动GRUB时(光盘的制作方法在下一节介绍),用于启动的光驱设备。该设备可直接使用,而不需要使用以上的命令来初始化。

用以下的命令可以停止化光驱: <pre> cdrom –stop </pre> 在停止光驱后,还需要用map –unhook来取消map –hook的效果。

用以下的命令可以指定搜索的端口: <pre> cdrom –add-io-ports=0x03F601F0 </pre>

以下是缺省的搜索端口:0x03F601F0, 0×03760170, 0x02F600F0, 0×03860180, 0x6F006B00, 0×77007300。

在初始化光驱后,可以用blocklist的方式来访问其内容:

<pre> cat –hex (cd0)16+2 </pre> 光驱中使用的扇区大小是2048。

另外,iso9660文件系统驱动程序支持Rock-Ridge扩展,但不支持Joliet扩展,在读取Joliet扩展的光盘是可能会出现问题。

另外,你可以以用chainloader命令来从光驱中启动:

<pre> chainloader (cd0) boot </pre>

一个完整的从第一只光驱启动的例子:

<pre> title Boot From First CDROM cdrom –init map –hook chainloader (cd0) boot </pre>

利用GRUB4DOS制作可启动光盘

在GRUB中,可以利用 stage2_eltorito 来制作启动光盘:

<pre>mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o grub.iso iso</pre>

stage2_eltorito和menu.lst应该放在光盘的/boot/grub目录里。

在GRUB4DOS中,可以利用 grldr 来制作启动光盘。制作方法有两种:

<pre>mkisofs -R -b grldr -no-emul-boot -boot-load-seg 0×1000 -o bootable.iso iso_root</pre>

<pre>mkisofs -R -b grldr -no-emul-boot -boot-load-size 4 -o grldr.iso iso_root</pre>

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中有实现了简单的脚本支持。目前实现了 && 和 || 两种操作:

<pre> command1 && command2 </pre> 只有当 command1 的返回值是真时,command2 才被执行

<pre> command1 || command2 </pre> 只有当 command1 的返回值是假时,command2 才被执行

目前不支持操作符的嵌入使用。

例子:

<pre> is64bit && default 0 is64bit || default 1 </pre>

如果is64bit命令返回值是真,那么缺省的菜单项是0,否则,缺省的菜单项是1。

没有评论

  • (Required)
  • (Required, will not be published)