GRUB&MBR引导
(ubuntu下搜索gnome-disk可以打开磁盘管理)
简单开机过程 :
①按下电源后,计算机自检(POST),如果硬件设备(CPU、内存、硬盘、光驱、各种卡)都没有问题,BIOS会检查各个硬盘的MBR,看有没
有可以执行的代码,如果你把grub安装到第一个硬盘的MBR上,那BIOS就会找到它,然后把控制权交个这段代码(其实就是512字节大小的
stage1)。
②stage1根据安装时提供的信息,如stage2在什么地方,需不需要加载文件系统的对应的stage1_5文件等,找
到stage2文件,并把控制权交给stage2。
③stage2会需要特定位置的grub配置文件grub.cfg文件,如
果找到,就分析其中的内容,形成操作系统选择菜单(Grub管它叫Menu
Interface),如果没有找到或者这个文件的格式、内容有错误,那就显示grub的命令行提示符。
④当你选择了菜单中相应的条目,或者输入了相关的命令,就可以看是引导系统了。比如引导linux的话,stage2会负责将vmlinuz 和initrd(如果有的话)装载到内存,并把控制权交给vmlinuz。
⑤linux的内核完成对硬件的初始化,并把控制权交给init程序,完成后续的工作了。
grub引导
GRUB 不是 Linux 系统,它本身可以看作一个小型操作系统,内置了简单的文件系统,可以读取分区。所以 grub 启动之后首先就是加载它自己的一个简单的文件系统,然后读取自己的相关配置文件。总体上GRUB更像是一个mini os,只不过这个mini os的作用只是加载其他的操作系统,在GRUB中包括stage1、stage1.5(可选)和stage2,其中stage1和stage1.5属于boot loader,stage2属于mini os的内核部分。GRUB中stage1过程主要位于MBR的前446字节中(对于支持GPT分区的磁盘,同样有最开始的512字节作为保护MBR,保护MBR与正常的MBR区别不大,主要是分区表上的不同,在保护MBR中只要一个表示为0xEE的分区,以此来表示这块硬盘使用GPT分区表,不能识别GPT硬盘的操作系统通常会识别出一个未知类型的分区,并且拒绝对硬盘进行操作),之后的64字节为硬盘的分区表,最后两个字节为MBR结束标志位(0xAA55)。
grub stage 1
其中stage1要被安装(也就是写入)某个硬盘的主引导记录,或者某个活动分区(这个分区要用fdisk标记成可启动的)的启动扇区。 stage1的主要的也是唯一的作用就是找到你存放在硬盘上某个地方的stage2文件,来完成后续的工作。
MBR中前 446个字节,如果把这里面的内容损坏,那么系统会认为当前磁盘没有启动引导功能,会尝试从光盘或者网络启动系统
stage1部分占用了446字节,其代码文件是源码目录下stage1/stage1.S文件,汇编后生成一个512字节的boot.img,被写在硬盘的0面0道1扇区中,作为硬盘的MBR。stage1的工作很简单,就是加载0面0道2扇区上的512字节到0×8000,然后跳转到0×8000执行。在0面0道2扇区上的512字节内容为stage1/start.S
文件汇编后生成。该扇区上的内容的作用是加载stage1.5或是stage2过程,并将控制权转交。
grub stage 1.5
在stage1过程将控制权转交后,接下来就是GRUB的核心过程了。该过程之所以区分stage1.5和stage2,主要原因是GRUB和GRUB2的区别。在GRUB2中,将stage1.5过程集成到了stage2的过程中,所以stage1.5过程仅仅是针对GRUB的。下面将介绍GRUB。
Stage1.5过程很无辜,它的作用很单一,但是非常关键。它的主要功用就是构造一个boot分区系统对应的文件系统,这样可以通过文件系统的路径(/boot/grub/)寻找stage2过程需要的core.img,进而加载到内存中开始执行。
Stage1.5存在于0面0道3扇区开始的地方,并一直延续十几k字节的区域,具体的大小与相应的文件系统的大小有关(文中涉及到了0面0道1-3+x扇区,这部分扇区为保留扇区,BIOS不会放置任何数据。正因为如此如果转换到GPT分区形式,系统将不能被正确引导,MBR后面的扇区都被其他内容所占据)。Stage1.5过程被构建成多种不同类型,但是功能类似,下面简单介绍一下基本的stage1.5过程的文件系统。e2fs_stage1_5(针对ext2fs,可引导ext2和ext3文件系统)、fat_stage1_5(针对fat文件系统,可引导fat32和fat16)、ffs_stage1_5、jfs_stage1_5、minix_stage1_5、reiserfs_stage1_5、vstafs_stage1_5和xfs_stage1_5,这些文件被称为stage1.5过程,这些文件每个至少都在11k以上。除此之外还有两个比较特殊的文件,分别为nbgrub和pxegrub,这两个文件主要是在网络引导时使用,只是格式不同而已,他们很类似与stage2,只是需要建立网络来获取配置文件。
对于ext2fs文件系统,用于生成该文件系统的stage1.5过程文件(e2fs_stage1_5)的代码为stage2/fsys_ext2fs.c
文件。
在stage2/filesys.h
文件中定义了每个文件系统对外的接口,用于上层调用,作为stage2过程寻找核心代码使用,文件系统一般被定义的接口主要就是三个函数,分别是mount、read和dir函数。对应ext2fs,其定义的函数为:
#ifdef FSYS_EXT2FS
#define FSYS_EXT2FS_NUM 1
int ext2fs_mount (void);
int ext2fs_read (char *buf, int len);
int ext2fs_dir (char *dirname);
#else
#define FSYS_EXT2FS_NUM 0
#endi
https://blog.csdn.net/langeldep/article/details/8788119
针对ext2fs有如上的函数名称,每个函数将具体在stage2/fsys_ext2fs.c
文件中被定义,这里面没有包含任何的写的过程,对于bootloader而言仅仅读就可以完成任务了,没必要对其系统进行写操作。其中ext2fs_mount函数用于检查文件系统类型,并将superblock读入到内存中;ext2fs_read函数和ext2fs_dir函数用于对文件系统具体的操作。在stage2/fsys_ext2fs.c
文件中除了需要对这三个函数的定义之外,还需要文件系统的属性的数据结构(superblock、inode和group结构,这些结构最初被定义在include/linux/ext2_fs.h
文件中),通过这些数据结构描述一个文件系统。
如果读者有兴趣可以试着创建新的文件系统的支持,可以参照目前存在的一些文件系统的模板(实例)编写。
grub stage 2
GRUB中的核心过程也就是stage2过程了,该过程主要是在文件系统建立以后选择合适的操作系统进行加载并转交控制权,达到最后引导操作系统的目标。由于GRUB属于multi boot loader,因此在引导的时候要进行选择,选择哪种操作系统来运行。在GRUB内部主要包括两种方式,首先是从grub. cfg中读取显示到屏幕让用户选择,其次是通过grub-shell中定义的命令手动进行启动。本文将在后面介绍这两种方式如何运行,接下来先介绍一下stage2的具体的执行过程。
在上面一节中介绍过,stage1.5过程中将boot分区的文件系统加载了,之后又做了一件事情,就是将控制权转交给stage2,而stage2入口的地方就是stage2/asm.S
文件。Stage2/asm.S
文件属于汇编代码,主要作用是初始化C语言的运行环境,为下面执行C语言的函数做好准备,在准备好之后,将执行init_bios_info(stage2/common.c
)函数。init_bios_info函数的作用是执行一些底层的函数,然后跳转到cmain执行,cmain函数位于stage2/stage2.c
文件中。cmain函数内部进行一个死循环,在循环内部首先加载配置文件,显示给用户,在这同时循环一个内层循环,在内层循环中,获取配置文件中的命令,并解析执行。过程中如果没有可用的配置文件,那么进入命令行模式(enter_cmdline函数),如果找到可用的menu,那么开始执行menu的对应的内容(run_menu函数)。对于enter_cmdline(stage2/stage2.c
)函数,将调用find_command(stage2/cmdline.c
),进而执行相应命令的函数。对于run_menu(stage2/stage2.c
)函数,将调用stage2/cmdline.c
文件中的run_script函数,进而调用find_command,执行相应命令的函数。
这两种方式虽然经过了不同的过程,对用户输入的行为进行分析和处理,最终调用的函数为find_command,在该函数中顺序循环比较“输入”的命令是否与系统内部定义的相同,如果相同转到执行该函数。在这个比较的过程中包含了一个全局的数据结构为struct builtin(stage2/shared.h
),由该数据结构组成了一个table类型(stage2/builtins.c
),将命令与相对应的builtin结构对应一起并进行串联。下面描述一下builtin结构的定义:
struct builtin {
/* 命令名称,重要,是搜索命令时的依据*/
char *name;
/* 命令函数,重要,是搜索匹配后调用的函数*/
int (*func) (char *, int);
/* 功能标示,一般未用到. */
int flags;
/* 简短帮助信息*/
char *short_doc;
/* 完整帮助信息*/
char *long_doc;
};
struct builtin *builtin_table[];
有兴趣的读者可以对上面的内容进行扩展,形成自己的命令,主要在stage2/builtins.c
文件中按照预定的格式更新,并添加到builtin_table中即可。
在上面打开配置文件的过程中,主要是通过一些文件操作函数(被定义在stage2/disk_io.c
中)完成。这些文件操作函数主要包括:grub_open、grub_read、grub_seek和grub_close等,这些函数属于grub对外的上层接口,具体的函数内部将调用前文中提到的boot分区对应的文件系统的相应的函数完成,这个过程主要是通过回调函数来完成。该过程整体思路类似于面向对象过程,通过对象操作具体的函数。
只要看到内核的启动菜单,表示已经成功的进入了grub的stage 2阶段,因为启动菜单是在2 stage生成的.
“因为stage1的容量有限(主引导记录MBR和启动扇区的大小只能够是512字节),所以它对文件系统是无法识别的,那如果你把
stage2存放在ext2或者fat格式的文件系统上,它如何来找到这个文件呢?这就要用到上面提到的那些stage1_5的文件了,它们负责解释文件
系统。你的stage2放在什么格式的文件系统上,就要调用对应的那个stage1_5文件。比如,你把stage2存放在ext2格式的文件系统上,就
需要e2fs_stage1_5;stage2存放在fat格式的文件系统上,就需要fat_stage1_5了
grub的话,肯定是要在mbr里写东西的,但446字节的机器码也干不了太多东西,只是负责把后续的内容加载到内存在执行而已。这个写到mbr的是stage1,它加载的是写在mbr之后62个扇区中的stage1.5(因为过去磁盘是按磁道还划分分区的,一个碰道63个扇区,因为mbr占据了第一个磁道的第一个扇区,所以第一个分区只能从第二个磁道开始,这样在mbr和第一个分区之间就留下了62个扇区的空间,62*512byte=31KB)。mbr之前说了容量太小没法放下识别文件系统的代码,只能以计算扇区绝对偏移的方法加载stage1.5,但31KB的stage1.5就足够了(但基本也只够一种类型的文件系统,所以stage1.5是有好几个,分别对应ext4,xfs等等,在grub安装时根据需要写入,随便一提,正是因为GPT分区表占用了后62个扇区的相当一部分位置,导致空间不够写下stage1.5,所以需要额外分出一个非常小的分区来存放)。stage1.5可以识别文件系统,然后根据安装时硬写到里面的系统路径(hexdump可以看到)找到stage2,然后这个stage2才是真正负责干活的,它会读取grub.cfg并生成启动菜单,然后根据你的选择加载内核并把执行权限转过去,完成启动。”--------------------------来自知乎
grub命令
1.grub-install /dev/sda 修复grub1 1.5 2 所有阶段的数据 修复的时候不依赖于任何外部配置文件
2.grub中对应的/根分区不是操作系统的根分区,它代表的是/boot分区
3.(hd0,0) 表示第一块磁盘的第一个分区 即代表sda1
4.(hd0) 表示第一块磁盘 即表示sda
5.grub这个命令依赖于/boot/grub目录下的一些配置文件,如果这些文件被删除或者移动,那么使用grub命令无法正常修复
6.如果没有使用grub修复过系统,那么/boot/grub/目录下的文件只有两个文件影响系统启动(grub.conf 和 splash.xpm.gz)
如果使用过grub修复过系统,那么 /boot/grub 目录下的其它配置文件同样会影响到系统启动。
https://www.cnblogs.com/yxh168/p/9016667.html
http://www.iteedu.com/os/grub/grubdiary/11.php
GRUB&MBR引导的更多相关文章
- grub覆盖mbr引导系统
grub覆盖mbr引导系统 0.个人PC,WIN 7 + Kali,easybcd 不起作用,需要制作 kali 安装盘 PS:推荐使用 universal usb installer 制作. 方案一 ...
- 使用grub手动引导linux和windows
引导Linux 重启进入到grub菜单界面时,按“c”键进入grub命令模式.1.指定/boot所在的分区,比如分区是第一块硬盘第一分区,即hd0,0 grub> root (hd0,0) 2. ...
- windows7 ubuntu双系统采用windows7 mbr引导方法
在安装有Windows7系统上的机器,安装用Ubuntu后,开机会自动用grub2 引导.对于使用双系统的用户来说,用MBR和grub2都差不多,但是,我的机器上有三个系统,需要用MBR来引导变色龙, ...
- 实验六:通过grub程序引导本地磁盘内核启动系统(busybox)
实验名称: 通过grub程序引导本地磁盘内核启动系统(busybox) 实验环境: 理论上,该实验只需要配置好xen环境即可,但是,我们的xen环境安装在centOS7上,但是我们又是使用的kerne ...
- 如何配置Ubuntu 16.04 GRUB 2引导加载程序
正如你所知,GRUB 2 是大多数 Linux 操作系统的默认引导加载程序.GRUB 是 GRand Unified Bootloader 的缩写,它是 Linux 启动时首先要加载的一个程序,此后它 ...
- 虚拟机中Windows激活「很抱歉,程序无法在非MBR引导分区上进行激活」
虚拟机激活 Windows 出现如下错误提示: 很抱歉,程序无法在非MBR引导分区上进行激活 没错,是小马Oem7F7激活工具. 最后使用 KMS 激活成功,下载链接: 链接:https://pan. ...
- CentOS7 修复MBR引导
为了达到实验目的,首先破坏MBR引导bootloader 重启系统发现系统进不去了,这正是我们想要的 重启进入系统救援模式,输入以下命令重建MBR引导bootloader 重启,可以正常引导进入系统
- 双系统如何删除Linux,恢复Windows从MBR引导启动?
嗯,现在愿意尝试Linux的人越来越多了.通常,如果一台电脑里已经装有了Windows,再装Linux,安装时,Linux的grub引导程 序就会覆盖掉保存在MBR当中的原来的Windows引导程序. ...
- Windows启动过程(MBR引导过程分析)
catalogue . 电脑启动过程 . MBR分析(master boot record) - 位于整个硬盘的 扇区 . DBR(DOS boot record) - 位于柱面0,磁头1,扇区1,即 ...
随机推荐
- prepareBeanFactory方法源码跟踪
看这篇文章之前可以先了解之前的跟踪流程,https://www.jianshu.com/p/4934233f0ead 代码过宽,可以shift + 鼠标滚轮 左右滑动查看 AbstractApplic ...
- 关于Android 的内存泄露及分析(转)
一. Android的内存机制Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的释 ...
- java基础知识(1)
Java包 包主要用来对类和接口进行分类.当开发Java程序时,可能编写成百上千的类,因此很有必要对类和接口进行分类. Import语句 在Java中,如果给出一个完整的限定名,包括包名.类名,那么J ...
- Day6 - I - Sticks Problem POJ - 2452
Xuanxuan has n sticks of different length. One day, she puts all her sticks in a line, represented b ...
- QEMU 配置网络
背景 为了 实现 uboot 中连接上 QEMU-host 的网络. 非常奇怪,本人的 系统中 存在/dev/net/tun驱动,但是 lsmod | grep tun 却没有任何结果,所以实际上,这 ...
- js generator的两个实际应用
generator作为一个用来操作异步的状态机, 遇到yield停止, 通过调用next()来继续操作. 今天就用generator来举例两个实际开发中的应用. 1,抽奖 function draw ...
- jar包学习
jar: java的压缩包,主要用于存储类文件,或者配置文件等. 命令格式: jar -cf 包名.jar 包目录 解压缩: jar -xvf 包名.jar 将jar包目录列表重定向到一个文件中: j ...
- 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:测试SSH框架分层整合及验证事务是否有效
测试框架分层的整合 HibernateTemplate 和 HibernateDaoSupport,这两个类是 Spring 为整合 Hibernate3 提供的两个工具类. HibernateTem ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 基本的输入输出
C++ 的 I/O 发生在流中,流是字节序列.如果字节流是从设备(如键盘.磁盘驱动器.网络连接等)流向内存,这叫做输入操作.如果字节流是从内存流向设备(如显示屏.打印机.磁盘驱动器.网络连接等),这叫 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 日期 & 时间
C++ 标准库没有提供所谓的日期类型.C++ 继承了 C 语言用于日期和时间操作的结构和函数.为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 <ctime> 头文件. 有四 ...