查看“GRUB”的源代码
←
GRUB
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{TutorialTone}} '''GRUB''' 是GNU项目的bootloader。(译者注:以后计划不再翻译Bootloader,英文来看是一个很明确的名词,但是翻译成“引导加载程序”以后像一个动词开头,译者的脑子经常要额外反应一下。) 当前版本2系列具有比 [[GRUB Legacy|GRUB 0.97]] (通常称为 “GRUB Legacy”) 更完整的功能集。 == 历史 == GRUB版本2以 [http://www.nongnu.org/pupa/ PUPA] (PUPA也有蛹的意思) 研究项目开始了它的生命,并从头开始重写。 从那时起,GRUB 2 (实际上在更新1.97时) 已经变得更加稳定,甚至是业余操作系统更多使用新的bootloader而不是GRUB Legacy。 == 特性 == * 基本脚本支持 * 图形用户界面 (更好的bootsplash支持,自定义颜色,自定义主题,...) * 内存管理 * 更清洁的设计 * 更好的便携性 * 国际化 * 救援模式 完整的功能列表可以在GNU邮件列表中找到 [https://lists.gnu.org/archive/html/grub-devel/2012-06/msg00093.html] == 使用GRUB引导你的操作系统 == 使用GRUB引导操作系统的完整示例代码可以在 [[Bare_Bones#Booting_the_Operating_System|Bare Bones tutorial]]中找到。 一般的想法是,你要创建一个具有multiboot标头的文件,GRUB可以将该文件程序标识为内核并引导它。 == 从GRUB Legacy升级 == ''警告: 这些步骤还没有经过很好的测试。 使用风险自负!'' 由于现代GRUB 2与GRUB Legacy非常不同,因此启动和运行内核的方式不同。 现代GRUB与GRUB Legacy的不同之处在于,要实现除最基本功能外的所有功能,用户必须加载所谓的 “模块(modules)”: 通过少量代码添加组件(例如,不同的文件系统或VGA字体)。 本节概述了要让GRUB 2加载内核时需要经历的过程。 创建一个GRUB 2映像 (假设你已经构建或安装了GRUB 2) 实际上相当简单: === ISO 指导 === 已经有很多尝试想要使GRUB2与ISO配合良好,但大多数都失败了。 唯一似乎有效的命令组合如下。 首先创建一个名为 “iso” 的目录树,在那里你把你的内核 (以及任何其他需要的文件) 放在这里。 然后在boot/grub子目录中创建grub.cfg文件,这是你的配置。 现在运行: grub-mkrescue -o bootable.iso iso 确保你的grub.cfg在语法上是正确的。 一个常见的错误是将menuentry括号放在换行符上。 它'''必须'''像这样: menuentry "Place your os name here" { } grub-mkrescue 依赖版本为 “0.5.6或更高” 的 “xorriso” 程序。 如果你无法将其作为二进制文件获取 (可能来自名为 “libisoburn” 的软件包) 可以从 [http://www.gnu.org/software/xorriso/#download GNU xorriso主页] 获取all-in-one源tar包。 GNU xorriso可以在原构建位置使用,无需进一步安装: grub-mkrescue --xorriso=/...full.path.../xorriso/xorriso -o bootable.iso iso === 软盘指导 === <source lang="bash"> mkdir tmp grub-mkimage -p /boot -o tmp/core.img multiboot sh fat # 我希望这应该行得通... :D </source> ==== 解释 ==== 让我们来看看这些 <tt>grub-mkimage</tt> 选项: {| {{wikitable}} |- | '''-p''' | 默认情况下,GRUB 2在 <tt>/boot/grub</tt> 中查找其配置文件。'''-p''' 更改此选项。 |- | '''-o''' | 与许多其他GNU工具一样,<tt>grub-mkimage</tt> 使用 '''-o''' 设置输出文件。默认情况下,它是 <tt>stdout</tt>。 |- | '''multiboot''' | 需要此模块来加载兼容多重引导(multiboot-compliant)的内核。 |- | '''biosdisk''' | GRUB 2需要此模块才能从LiveCD引导。 |- | '''iso9660/fat''' | 允许GRUB 2在映像上查找不同的文件。 |- |'''sh''' | 该模块允许GRUB解析配置文件。 |} GRUB 2和GRUB Legacy一样,需要一个配置文件来找到你的内核。 在GRUB Legacy中,它被称为 '''menu.lst' '',但在GRUB2中,它被称为 '''grub.cfg'''。 配置文件的语法也有点不同。 这是一个示例配置文件 (注意: 此文件应放置在磁盘映像的 <tt>/boot/grub</tt> 文件夹中,并命名为 '''grub.cfg' ''): <source lang="bash"> set timeout=15 set default=0 # 设置默认菜单项 menuentry "OS Name" { multiboot /boot/kernel-file # multiboot命令取代了内核命令 boot } </source> 基本上就是这样。 将这些文件复制到磁盘映像中,将其放入模拟器,你就完成了! 仔细检查是否将花括号放在 “menuentry” 的同一行上。 它不可以在新的一行上。 这不是C。 === USB 指导 === 如今,拥有软盘控制器的系统越来越少,但是在所有系统上都可以找到USB端口。 现代BIOS可以从USB设备启动,还通常需要在启动时按下一些特殊的键。 将GRUB 2放在可启动的USB存储设备上是在不同计算机上尝试操作系统的好方法。 下面是你如何设置 (使用Linux): 1. 创建一个不带多个分区的FAT32格式U盘: '''警告: 以下命令使用超级用户权限 (sudo)。 仅键入错误的X字符可能会给你当前的系统带来严重的麻烦''' <pre>sudo mkfs.vfat -F 32-n YourLabel -I /dev/sdX</pre> (其中sdX是你的USB设备) 需要 “-I” 选项,因为我们的目标是无分区设备 2. 卸下USB设备,然后重新插入。 操作系统上的自动安装程序现在应该检测到它。 3. 调用grub-install (在某些系统上,此命令被称为grub2-install,位于/usr/sbin或/usr/local/sbin下) <pre>sudo grub-install --root-directory=/media/YourLabel --no-floppy --recheck --force /dev/sdX</pre> 重要的是要以root (或sudo) 的身份执行此操作,否则生成的device.map列出可用的引导设备可能为空。 /media/YourLabel 是Fedora 16下的挂载点,其他发行版可能有所不同。 4.为你的内核创建一个grub.cfg (请参见上文),并将其复制到新的可启动USB磁盘中 === 磁盘映像指导 === 有关更详细的教程,请参见[[Bootable_Disk|可引导磁盘]]来创建。 爱好者操作系统在虚拟机上运行时不必使用真实设备 (尽管可以,而且通常速度更快)。 创建可引导的GRUB磁盘映像类似于将其安装在USB设备上,但是在这里,你可以立即使用映像本身和分区设备。 1. 创建新的磁盘映像文件 <pre>$ dd if=/dev/zero of=disk.img bs=512 count=131072 131072+0 records in 131072+0 records out 67108864 bytes (67 MB) copied, 0.349436 s, 192 MB/s </pre> 2. 为你的文件系统创建带有可引导项的新DOS分区表 <pre>$ fdisk disk.img</pre> 添加新分区,从1MB (第2048个扇区) 开始。 这比GRUB实际需要的空间更大。 <pre> Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1): 1 First sector (2048-131071, default 2048): Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-131071, default 131071): Using default value 131071 </pre> 使其可引导启动 <pre> Command (m for help): a Partition number (1-4): 1 </pre> 将新的分区表写入磁盘 <pre> Command (m for help): w The partition table has been altered! Syncing disks. </pre> 3. 设置两个回环(loop)设备。 一个将用于将GRUB及其附加代码写入MBR,第二个将用于安装操作系统的文件系统。 <pre> $ sudo losetup /dev/loop0 disk.img $ sudo losetup /dev/loop1 disk.img -o 1048576 </pre> ''-o'' 选项定义从文件开始的偏移量。数字 “1048576” 实际上是 “1024 ^ 2 = 1MB”,这是分区的开始。 4. 格式化分区 你可以简单地使用 [[http://www.gnu.org/software/grub/manual/grub.html#Features 任何受支持的文件系统]],如ext2或FAT32。 <pre>$ sudo mke2fs /dev/loop1</pre> <pre>$ sudo mkdosfs -F32 -f 2 /dev/loop1</pre> 5. 挂载你新格式化的分区 <pre>$ sudo mount /dev/loop1 /mnt</pre> 请注意,如果你试图挂载没有任何偏移设置的首个回环设备,你将被要求指定文件系统,即使你这样做了,你也不会得到预期的结果。 7. 使用 “grub-install” 安装grub <pre>sudo grub-install --root-directory=/mnt --no-floppy --modules="normal part_msdos ext2 multiboot biosdev" /dev/loop0</pre> 如果你错误地使用了 “/dev/loop1” (指向你的分区) 而不是 “/dev/loop0” (指向你的MBR),你将收到 “grub-install” 不能使用 'embedding' 的消息 (因为它没有空间),并且它希望使用 'block lists',不推荐这么做。 处理挂载磁盘映像上的文件时,不要忘记刷新文件系统缓冲区。 在类Unix的系统上,这可以简单地通过在你的shell中执行 <tt>sync</tt> 程序来完成。 == OS X用户的硬盘映像指导 == 为HDD创建映像文件可能会很有用; 以下说明可帮助你使用MBR分区映射创建HDD。 根据#osdev上的<palk>信息,创建HDD映像比你预期的要稍微复杂一些。 此信息可能不适用于Linux用户,他们很可能更想使用loopback设备。 这是针对OS X上的开发人员的,它没有loopback设备,并且具有挑剔的映像安装程序。 1. 首先,用DD创建一个空白的原始映像,大小符合要求。 在这里,我将制作一个80MB的图像 --163840个扇区,每个大小为512字节。 <source lang="bash"> dd if=/dev/zero of=disk.img count=163840 bs=512 </source> 2. 有关从LBA/大小计算CHS值的解释,请参见 [[Floppy_Disk_Controller#CHS]] 由于我们有一个80MB的磁盘,CHS值分别为78、32和63。 3. 启动FDISK(或你选择的工具) -- 我在这里使用的是OS X版本,所以命令可能有所不同。 概念基本上是相同的。 屏幕上显示的内容(指OSX中)在左侧,你输入的内容在右侧。 <source lang="bash"> fdisk -e disk.img The signature for this MBR is invalid. Would you like to initialize the partition table? [y] Yes fdisk:*1> disk Disk: disk.img geometry: 650/4/63 [16340 sectors] Change disk geometry? [n] No fdisk:*1> edit 1 Partition id ('0' to disable) [0 - FF]: [B] (? for help) 0B Do you wish to edit in CHS mode? [n] No Partition offset [0 - 163840]: [63] 2047 Partition size [1 - 161793]: [161793] <Enter> fdisk:*1> write fdisk:*1> quit </source> 4.现在已经初始化了MBR分区表,你将需要在磁盘上创建一个文件系统。但首先。 这里,我们分离MBR位和实际的FS位。 <source lang="bash"> dd if=disk.img of=mbr.img bs=512 count=2047 dd if=disk.img of=fs.img bs=512 skip=2047 </source> 5.因为我们使用的是OS X,所以需要先附加(attach)磁盘镜像,而不是实际挂载(mounting)。 <source lang="bash"> hdiutil attach -nomount fs.img </source> 6.使用 “diskutil list” 找出你的映像是哪个设备,请使用下面的设备。 7. 现在,在FS.img磁盘上创建一个FAT12/16/32文件系统。记住,使用FS.img——不是disk.img <source lang="bash"> newfs_msdos -F 32 /dev/diskX </source> 8.现在你需要卸载(unmount)它,然后重新组合两个映像,然后安装GRUB。 <source lang="bash"> hdiutil detach /dev/diskX cat mbr.img fs.img > disk.img hdiutil attach disk.img # note the mount point here (/Volumes/NO NAME, probably) grub-install --modules="part_msdos biosdisk fat multiboot configfile" --root-directory="/Volumes/NO NAME" disk.img Installation finished. No error reported. </source> 就到这里! 你知道我有一个disk.img,这将安装GRUB2,准备就绪。 只需双击(或使用mount命令),就可以在OS X中挂载它。 玩的开心! ===其他有用的选项=== 无论你使用的是哪种设备,你都可能希望有一个PC分区表,并在GRUB支持的文件系统之一中创建格式化的分区。如果这样做,请确保在GRUB-INSTALL参数中添加以下选项: --modules="part_msdos" 一般来说,如果GRUB 2恰好无法完成你想要的任务,并且你怀疑它需要一些缺少的功能,那么只需尝试在--modules参数中添加一个你认为具有所需功能的模块名。 模块文件通常位于/boot/GRUB/i386-pc/。 == 多重引导(Multiboot) == 与GRUB-legacy将它们加载到低内存(low memory,译者注:指内存地址值大小)相比,GRUB 2的某些版本喜欢将multipot模块放在相对较高的物理内存地址中。 在让内核使用GRUB2时要小心,它没有对多多重引导模块将出现在哪里做出任何假设。 当你的内核获得控制权时,机器状态定义如下:[http://www.gnu.org/software/grub/manual/multiboot/html_node/Machine-state.html 多重引导机器状态]。 你的代码应该对该初始状态具有最小的依赖性; 例如,定义你自己的GDT,而不是依赖GRUB的GDT设置。 === 标头 === 正如GRUB 2手册所说: {{quote|GRUB的主要要求是它符合 “多重引导规范(Multiboot Specification)”。}} 但是旧版本的GRUB2使用的多重引导标头(字段出现在GRUB1.99和更新版本中)'''不'''包括[http://nongnu.askapache.com/grub/phcoder/multiboot.pdf 多重引导1.6规范] 中指定的''header_length''字段。 GRUB2还支持旧的[https://www.gnu.org/software/grub/manual/multiboot/multiboot.html Multiboot0.6.96规范]。 可以同时包含两个标头。 == 在OS X上安装GRUB 2 == 在OS X上安装GRUB 2有点棘手。 最新发布的2.00版本(截至2014年10月7日)似乎不支持任何配置。 开发人员团队在较新的修订版本中修复了此问题。 '''重要提醒:''' 要构建GRUB2,以便它可以为你的输出目标生成bootloader,你需要有一个用于该目标的编译器。 因此,例如,如果你想要i386-elf的bootloader (如在裸机中建议的那样),则需要Binutils该目标的编译器。 这在OS X上是必需的,因为内置LLVM不知道如何生成i386-elf二进制文件。 因此,你可以针对你的目标平台[[GCC_Cross-Compiler|构建交叉编译器]]或[[OS Specific Toolchain|创建特定于操作系统的工具链]](推荐)。 '''在步骤4中,你将需要GCC,objcopy,strip,nm和ranlib的交叉版本。''' ''' 1.''' 复制开发人员版本的源代码: <source lang="bash">git clone git://git.savannah.gnu.org/grub.git</source> (该测试版本为:77063f4cb672f423272db7e21ca448cf3de98dcf) '''2.'''需要名为'''objconv'''的工具,请从以下位置获取: https://github.com/vertis/objconv 下载源代码,编译 (有关详细信息,请参见网站) 并在你的路径中提供。 '''3.''' 在GRUB sources文件夹中运行“autogen.sh” '''4.''' 创建一个单独的构建目录,切换到该目录,然后运行GRUB的配置脚本 ''(insert your target-specific tools!)'': ../grub/configure --disable-werror TARGET_CC=i386-elf-gcc TARGET_OBJCOPY=i386-elf-objcopy \ TARGET_STRIP=i386-elf-strip TARGET_NM=i386-elf-nm TARGET_RANLIB=i386-elf-ranlib --target=i386-elf '''5.''' 运行 “make” 和 “make install” 现在,你已经有了一个正在工作的GRUB 2,它具有构建在i386平台上启动的映像所需的文件。 == UEFI的GRUB == === 编译GRUB === 较老的GRUB版本充满了令人讨厌的BUG。 这些版本可能还存在在你的包管理器中,因此你应该从源代码编译GRUB。 在为UEFI编译时,你应该传递适当的标志以进行配置。 示例调用可能如下所示: <source lang="text"> ../grub-2.02~rc2/configure --prefix="$HOME/opt/grub" --target=x86_64 --with-platform=efi </source> 完成构建后,GRUB拒绝执行任何操作,因为它缺少字体文件。 要解决这个问题,请运行 <source lang="text"> bin/grub-mkfont -o share/grub/unicode.pf2 /usr/share/fonts/truetype/unifont/unifont.ttf </source> GRUB可能会警告你有关share/locale/丢失的信息。 解决方案是创建缺少的目录。 ===构建GRUB UEFI二进制文件(BOOTX64.EFI)=== 此方法构建一个独立的GRUB二进制文件,你可以将其复制到FAT分区。 然而,请注意,一些UEFI实现假定它位于 <code>/EFI/BOOT/BOOTX64.EFI</code> 针对x86_64平台。 通常,所有编译的模块都包含在此二进制文件中; 如果要缩小其大小,则可以指定要包含的模块。 此方法使用两个单独的配置文件; 这是必需的,因为所有GRUB数据都位于该二进制文件中,但我们将围绕这个二进制文件工作。 二进制文件包含一个memdisk,它也用作前缀。 据我所知,没有办法直接解决这个问题。 但是,我们可以使用memdisk grub.cfg从磁盘加载配置文件。 这样,我们就不必为每次配置更改重新创建二进制文件。 从创建memdisk grub.cfg开始。 我将其保存在build/grub.cfg(我们稍后需要此路径): <source lang="text"> insmod part_msdos configfile (hd0,msdos1)/boot/grub/grub.cfg </source> 所有这些就是加载用于读取磁盘分区的模块 (第1行),并从磁盘加载配置文件 (第2行)。 注意,它不必位于/boot/grub/grub.cfg;你可以将磁盘上的此路径更改为任何你喜欢的路径,只需记住将更改应用于memdisk grub.cfg。 第二个grub.cfg(磁盘上的那个)基本上由你决定,只是你必须加载part_msdos模块并设置根目录(默认情况下是memdisk): <source lang="text"> insmod part_msdos set root=(hd0,msdos1) </source> 在 <code>set root</code> 行下方添加常规GRUB2配置。 最后,剩下的就是创建二进制文件。 请注意,你必须指定要在Memdisk中的路径下包含哪个文件: <source lang="text"> bin/grub-mkstandalone -O x86_64-efi -o BOOTX64.EFI "boot/grub/grub.cfg=build/grub.cfg" </source> === Blessing macOS上的二进制文件 === Mac要求可引导的二进制文件由'blesse'工具处理: <source lang="text"> bless --verbose --folder=/Volumes/EFI --file=/Volumes/EFI/EFI/BOOT/BOOTX64.EFI --setBoot </source> == 另见 == === 文章 === * [[GRUB Legacy]] * [[Bootable El-Torito CD with GRUB Legacy]] * [[Multiboot]] * [[BOOTBOOT]] an alternative boot loader with exactly the opposite philosophy as GRUB's === 外部链接 === * [http://www.gnu.org/software/grub/ GRUB 2 Homepage] * [http://grub.enbug.org/ GRUB 2 Wiki] [[Category:Bootloaders]] [[Category:GRUB]] [[Category:UEFI]] [[de:Grand_Unified_Bootloader]]
本页使用的模板:
模板:EditThis
(
查看源代码
)
模板:Quote
(
查看源代码
)
模板:TutorialTone
(
查看源代码
)
模板:Wikitable
(
查看源代码
)
返回至“
GRUB
”。
导航菜单
个人工具
登录
命名空间
页面
讨论
变体
已展开
已折叠
查看
阅读
查看源代码
查看历史
更多
已展开
已折叠
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息