zoukankan      html  css  js  c++  java
  • 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,其定义的函数为:

    1 #ifdef FSYS_EXT2FS
    2 #define FSYS_EXT2FS_NUM 1
    3 int ext2fs_mount (void);
    4 int ext2fs_read (char *buf, int len);
    5 int ext2fs_dir (char *dirname);
    6 #else
    7 #define FSYS_EXT2FS_NUM 0
    8 #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结构的定义:

     1 struct builtin {
     2 /* 命令名称,重要,是搜索命令时的依据*/
     3 char *name;
     4 /* 命令函数,重要,是搜索匹配后调用的函数*/
     5 int (*func) (char *, int);
     6 /* 功能标示,一般未用到. */
     7 int flags;
     8 /* 简短帮助信息*/
     9 char *short_doc;
    10 /* 完整帮助信息*/
    11 char *long_doc;
    12 };
    13 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

  • 相关阅读:
    [Jweb] Servlet 生命周期, TestLifeCycleServlet extends HttpServlet
    [Java] Javadoc jdk 下载地址
    [Jweb] 在 servlet 中重写 service() 方法,不重写 doGet, doPost 方法,示例。
    [Jweb] Servlet / GenericServlet / HttpServlet 及其方法示意图
    [Jweb] 第一个通过 tomcat 配置,浏览器访问的 web 界面
    [Jweb] tomcat 知识点 (from bjsxt ZZY)
    [Jweb] HTTP 1.1与HTTP 1.0的比较 (from bjsxt 张志宇)
    post方式提交数据
    php页面获取数据库中的数据
    表单输入框样式
  • 原文地址:https://www.cnblogs.com/liuzhenbo/p/10806119.html
Copyright © 2011-2022 走看看