http://blog.csdn.net/arganzheng/article/details/6263517
补记:2010-04-21
时隔两年,会过头来重新看了一下,发现GRUB的启动问题还是经常遇到,所以又整理了一下:
Tip0: 如何使用Grub启动Linux系统:
假设你的Linux系统做了如下分区:
/ sda1 (hd0, 0)
/boot sda2 (hd0, 1)
那么可以通过如下命令启动:
grub>root (hd0,0) #指定/boot所在分区,因为kernel和initd镜像都放在那里
grub>kernel /vmlinuz root =/dev/sda2 #如果前面没有指定root,那么kernel (hd0, 0)/vmlinuz。 root=/dev/sda2指定的是根目录(/)所在分区。
grub>initrd /initrd.img #如果前面没有指定root,那么initd (hd0,0)/initd.img
grub>boot
对应在/boot/grub/menu.lst中的配置项如下:
title Ubuntu, kernel 2.2.17.14-ubuntu13.00
root (hd0, 0)
kernel /vmlinuz-2.6.17.14-ubuntu13.00 root=/dev/sda2 ro noapic
initrd /initrd.img-2.6.17.14-ubuntu13.00
savedefault
boot
说明:root命令告诉grub目录/boot位于哪一个设备分区。接下来kernel告诉grub要引导的内核镜像文件,并且grub会将内核镜像名后面的参数root=/dev/sda2 ro noapic传递给内核。参数root告诉内核根文件系统(/)挂载在哪一个分区。ro表示该分区初始化时通常以只读方式挂载,稍后(在执行检查之后)再以读写模式重新挂载。noapic是用来关闭高级可编程中断控制器的。initrd(init ramdisk)命令指定用来存放初始化RAM
磁盘映像文件的文件名。grub加载该映像文件,并将其挂载作为引导Linux过程中第一个阶段时的根文件系统。另外,可以看到上面的系统有一个独立的引导分区(/boot),所有的内核映像文件和initrd映像文件的路径都是相对于/boot的。
/***************************************************************************************************************************************/
昨天又重装了一下Windows系统,发现对于装有多个操作系统的人来说,BootLoader是一个必不可少的一个工具。之前有一段时间研究过BootLoader,特别是GRUB,现在有时间粗略整理一下。毕竟,温故而知新。
关于GRUB的背景知识和原理,这里就不详细介绍了,具体看我的GRUB目录中的文章。这里仅仅介绍他的使用,可以看做是关于GRUB的一些Tips。
Tip1:
How to use GRUB to find out if you aren't sure
How to use GRUB's Command Line to investigate a computer
GRUB is almost a miniature operating on it's own, it can take quite a few commands and perform some useful tricks. It's well worth a little of anyone's time to learn how to work with GRUB at the command line.
We'll see how to boot operating systems in a few minutes. First, here are a few useful tricks to help you learn to use GRUB interactively if your computer's BIOS supports that. This is how to use GRUB to take a look around inside a computer.
Tab completion is a very useful feature of GRUB. In the example shown below I want to use Tab completion to find out what hard disks and partitions ane in my computer,
grub> root (hd_ |
grub> root (hd Possible disks are: hd0 hd1 |
grub> root (hd0, Possible partitions are: Partition num: 0, Filesystem type is fat, partition type 0xc Partition num: 1, Filesystem type is ext2fs, partition type 0x83 Partition num: 3, Filesystem type is ext2fs, partition type 0x83 Partition num: 4, Filesystem type unknown, partition type 0x82 |
Find Hard Disks
Here's another way to get GRUB to list all hard disks and partitions and give information on what filesystems are in a computer,
grub> geometry (hd_ |
grub> geometry (hd Possible disks are: hd0 hd1 |
Find Partitions
Now I want to find out what partitions are in the first hard disk,
grub> geometry (hd0) |
grub> geometry (hd0) drive 0x80: C/H/S = 1023/255/63, The number of sectors = 156301488, LBA Partition num: 0, Filesystem type is fat, partition type 0x1b Partition num: 1, Filesystem type is ext2fs, partition type 0x83 Partition num: 3, Filesystem type unknown, partition type 0x7 Partition num: 4, Filesystem type unknown, partition type 0x82 Partition num: 5, Filesystem type is ext2fs, partition type 0x83 Partition num: 6, Filesystem type is ext2fs, partition type 0x83 Partition num: 7, Filesystem type is ext2fs, partition type 0x83 |
grub> geometry (hd1) drive 0x81: C/H/S = 1023/255/63, The number of sectors = 58605120, LBA Partition num: 2, Filesystem type is fat, partition type 0xb Partition num: 3, Filesystem type is ext2fs, partition type 0x83 |
I use these commands often to determine one hard disk from another before installing GRUB to a hard disk's MBR, to make sure I install the right GRUB to the right MBR.
Find out which partitions contain a Linux kernel
To find more information we can use the 'find' command, for example:
grub> find /vmlinuz |
The feedback from the above command should give you one or more answers like:
grub> find /vmlinuz (hd0,1) (hd0,5) (hd0,6) |
Well, really, to be accurate, they are partitions which contain a symlink to a Linux kernel.
These partitions could be /boot partitions if an installation has separate /boot and / (root) partitions.
Find out which partition is your '/' or 'root' partition
grub> find /sbin/init |
The results from the above command might appear as shown below,
grub> find /sbin/init (hd0,1) (hd0,5) (hd0,6) (hd0,7) |
There are ways to have GRUB find out even more interesting information for us if it might help. We can open plain text files in any of those partitions we may be interested in with the 'cat' command. For a few examples,
grub> cat (hd0,7)/boot/grub/menu.lst |
and,
grub> cat (hd0,7)/etc/fstab |
and also:
grub> cat (hd0,7)/boot/grub/device.map |
The device.map file might occasionally be interesting to be able to see.
By the time you have tried out some of those extra commands you will be getting the idea that you can find out almost anything about any computer with GRUB's CLI.
That's probably all the information we need for getting GRUB to boot any Linux system.
Tip2:How to boot Linux from GRUB's CLI (Command Line Interface)
1. Set the GRUB's root device to the same device as GUN/Linux's. Probably the command find /vmlinuxz or similar can help you (你也可以输入grub>root(hd0, ,然后按Tab键,会提示你各个分区的文件系统信息,一般ext3的都可以作为启动区):
grub>root (hd0,1) #The first command is 'root(hdx,y)' to set GRUB's root device to the partition that contains a linux kernel.
2. Load the kernel. Probably the command find /sbin/init or similar can help you to find out which partition is your '/' or 'root' partition.(假设返回(hd0,8),再利用cat去查看fstab,看(hd0,8)映射成什么设备名字:grub>cat (hd0,8)/etc/fstab),另一个有用的命令是grub>cat (hd0,8)/boot/grub/device.map,一般来说,(hd0,x)映射为hda[x+1]:
grub>kernel /vmlinux root=/dev/sda2 #Presuming /dev/sda2 is the partition of you root file system (containing /sbin/init).
3. If you use an initrd, execute the command initrd after kernel:
grub>initrd /initrd.img #The initrd command will be 'initrd'
4. Finally, run the command boot:
grub>boot
What You Absolutely Need to Know
In order to use grub to boot a computer, you need to know the following:
- The partition containing the kernel
- Within that partition, the directory path and filename of the kernel
- The partition containing /sbin/init (也就是你的root partition: the partition your '/' mounted to)
In addition, you might need the partition, path and filename of the initrd file, but usually this is not necessary with grub.
Now let's take a look at an example. Imagine a system in which /dev/hda1 is mounted as /boot, and /dev/hda9 is mounted as / (你的根目录). Within /boot the kernel filename is vmlinuz-i686-up-4GB. Now let's answer the four questions:
Now let's take a look at an example. Imagine a system in which /dev/hda1 is mounted as /boot, and /dev/hda9 is mounted as / (你的根目录). Within /boot the kernel filename is vmlinuz-i686-up-4GB. Now let's answer the four questions:
- The partition containing the kernel = /dev/hda1, or (hd0,0) in grub-speak
- Within that partition, the directory path and filename of the kernel = /vmlinuz-i686-up-4GB
(Remember, /dev/hda1 is mounted directly to /boot, so it contains the kernel directly) - The partition containing /sbin/init is /dev/hda9
In that case, here are the grub commands you would input to boot that system:
grub> root (hd0,0) grub> kernel /vmlinuz-i686-up-4GB root=/dev/hda9 grub> boot
The preceding is usually sufficient to boot a Linux box. The standalone
root statement tells the partition containing the kernel. The
kernel statement describes the path and filename, within the partition containing the kernel of the kernel. The argument to the
root= argument to the
kernel statement tells the partition containing
/sbin/init, which of course turns out to be the root partition in the booted system.
Be careful of these duelling root keywords. The standalone one is the root as seen from grub, and contains the kernel. The argument to the kernel statement is the root as seen from the fully booted system, and contains /sbin/init.
Be careful also of where you use grub partition notation and where you use Linux partition notation. You use grub partition notation ( (hd0,0)) everywhere except the root=argument to the kernel statement. In the root= argument you use the Linux partition notation. Note that in Linux notation, the drive starts with a for the first IDE port master, then b for the first IDE port slave, then c for the second IDE port master, and d for the second IDE port slave, on and on throughout your IDE ports. In Linux notation, the partition number within the drive starts with 1.
In grub partition notation, the first accessible hard drive is (hd0), the next accessible hard drive (even if it's on the 3rd, 4th or higher IDE port) is (hd1), and so forth. In grub partition notation, the partition number is zero based. Thus:
/dev/hda1 is the same partition as (hd0,0)
Occasionally you'll need to specify an initrd, although this is rare. If so, after the kernel statement and of course before the boot statement, insert the following:
Be careful of these duelling root keywords. The standalone one is the root as seen from grub, and contains the kernel. The argument to the kernel statement is the root as seen from the fully booted system, and contains /sbin/init.
Be careful also of where you use grub partition notation and where you use Linux partition notation. You use grub partition notation ( (hd0,0)) everywhere except the root=argument to the kernel statement. In the root= argument you use the Linux partition notation. Note that in Linux notation, the drive starts with a for the first IDE port master, then b for the first IDE port slave, then c for the second IDE port master, and d for the second IDE port slave, on and on throughout your IDE ports. In Linux notation, the partition number within the drive starts with 1.
In grub partition notation, the first accessible hard drive is (hd0), the next accessible hard drive (even if it's on the 3rd, 4th or higher IDE port) is (hd1), and so forth. In grub partition notation, the partition number is zero based. Thus:
/dev/hda1 is the same partition as (hd0,0)
Occasionally you'll need to specify an initrd, although this is rare. If so, after the kernel statement and of course before the boot statement, insert the following:
initrd /initrd-i686-up-4GB.img
It's absolutely essential that if you do use an
initrd statement, that the
initrd file you reference must match the kernel you referenced earlier.
NOTE I have seen cases in which a kernel would kernel panic without an initrd statement, and would boot with it. The interesting thing is, once I got it booting, I could remove the initrd statement, rerun grub's setup, and it would now boot without the initrdstatement. If you get kernel panics and it isn't obvious why, don't hesitate to insert an initrd statement. |
Another documented way to boot from grub is to put the grub-root in the kernel statement itself instead of as a separate entity:
grub> kernel (hd0,0)/vmlinuz-i686-up-4GB root=/dev/hda9 grub> boot
If you do that, you'll need to also specify the grub root (
(hd0,0)) on any
initrd statement.
Tip3:How to boot Windows from GRUB's CLI (Command Line Interface)
虽然GRUB一般用于启动Linux,但我们同样可以利用他来启动Windows:
假设你的Windows是在你硬盘的第一分区,亦即(hd0,0)
1. grub>root (hd0,0) #指定你的Windows系统所在分区
2. grub>makeactive #set the 'boot flag' to mark the partition as 'active'
3. grub>chainloader +1 #Point GRUB at the boot sector loader with the command 'chainloader +1' . Chainloading means it passes control to the other system's bootloader(NTLDR for example)
4. grub>boot
要理解这个Tip,需要理解系统的启动过程:
Control of GRUB:
BIOS [jump to]---->MBR [jump to(accoring to the 'boot flag')]---->Partition Boot Sector (Ubuntu) [chainloading to]---->NTLDR
now the control is chainloading to NTLDR
Control of NTLDR:
MBR[jump to(according to the 'boot flag')]---->Partition Boot Sector(Windows)--->boot
Tip4: How to reinstall your MBR or partition boot sector
这个Tip对于装有多个系统的同学来说特别实用,因为每次重装系统之后经常会发现原来的系统无法进入了,这是因为新的系统将你原来的MBR给覆盖了,这时候就需要用到GRUB来恢复原来的MBR。
如果是在原来已经装了Windows的基础下再安装Linux,则一般不需要做任何事情,GRUB为自动帮你找到Windows的启动项。
当如果是在Linux的基础上安装Windows(这种情况一般是重装Windows系统),则需要做一些操作以找回原来的Linux系统。
方法是使用GRUB for DOS。下载GRUB for DOS,将其中的grldr放在你的Windows系统分区根目录,如一般的C:/grldr。用记事本打开C:/boot.ini,在最后添加一行:
C:/grldr="GRUB for DOS"
重新启动,就可以看到这个选择,选择进来,GRUB会自动找到第一个Linux系统的menu.lst。如果这正是你想要的系统,那么一切就解决了。
如果你想要把某个Linux系统的BootLoader安装到MBR中,这样你一启动系统就可以就如你想要的系统,那么可以使用如下方式:
1. For Windows:使用FixMBR工具。
2. For Linux:使用setup命令或grub-install命令。
2.1 使用setup命令:这种情况下一般是原来的Linux系统已经无法进入,在GRUB for DOS的grub命令行下,输入如下命令:
1. grub>find /boot/grub/stage1 #stage1才是要装入MBR的引导程序,而不是整个GRUB
2. grub>root (hd0,x) #x为步骤1返回的结果之一
3. grub>setup (hd0) #for MBR
or
3. grub>setup(hd0,y) #for y partition boot sector
或更简洁的语法:
grub>setup (hd0) (hd0,x) #install the stage1 of (hd0,x) to MBR
注:你也可以使用LiveCD引导进入,在LiveCD中使用grub命令,不过如果已经进入LiveCD,一般就不这么做了,而是用下面的操作。
如果你原来的系统没有损坏,则可以先进入到原来的系统,再使用grub-install命令恢复其MBR:
1. 使用LiveCD:
使用LiveCD引导进入后,找到你的原有系统的根目录,执行chroot命令切换到原有系统的console模式。
然后使用grub-install /dev/hda[x] (or sda[x] for SCSI hardisk)
2. 使用GRUB for DOS:
这种方式需要使用Tip2介绍的方式,且前提是你能够进入你的Windows系统。不过一旦进入Linux系统后就不用使用chroot命令切换系统了,直接使用grub-install命令即可。
Tip:对于Tip4,你会发现sudo lshw命令十分有用,该命令用于查看硬件信息,如硬盘各个分区的映射。
类似的命令有lspci等。