07 | 从BIOS到bootloader

本文仅作为学习记录,非商业用途,侵删,如需转载需作者同意。

x86 有两种模式:

  • 实模式:只能寻址1M,每个段最多64K
  • 保护模式:32位系统能够寻址4G

一、BIOS时期

当按下开机键,主板就加上电了。
这个时候CPU就开始执行指令了,只是没有项目执行计划书(程序)还没有事情可干,CPU(外包公司老板)也不知道干啥。

所有BIOS 相当于是刚开始的指导手册,只读的,告诉你一开始的该做一些准备工作。

在这里插入图片描述

计算机系统也早有计划,在主板上有个叫ROM(read only Memory 只读存储器),这个和内存RAM(Random Access Memory 随机存取存储器)不同,RAM是可读可写的,才能保存计算结果。

ROM 是只读的,上面固化了一些初始化的程序,也就是BIOS(Basic Input and output system 基本输入输出系统)

就是电脑启动时候,按组合键进入,蓝色界面,可以调整启动顺序的 就是 BIOS。
在这里插入图片描述

x86系统内存结构图:

在这里插入图片描述

如上图:
1M空间最上面的 0xF0000 到0xFFFFF这64k 映射给ROM,也就是说到这部分地址访问的时候,会访问ROM。

当电脑加电的时候会做一些重置工作:
将CS(code segment register)代码段寄存器设置为0xFFFF,将IP(指令指针寄存器(Instruction Pointer Register) ) 设置为 0x0000,所以第一条指令就会指向0xFFFF0,正是在ROM的范围内。
在这里有个JMP 中跳到 ROM中做初始化的代码,然后BIOS 开始做初始化的工作。

创业指导手册内容

第一条:BIOS要检查下硬件是否都正常

第二条:要有个办事大厅,提供服务,这个时候自己就是办事员,提供的服务也很简单,也有零星的客户来提要求。
需要建立一个中断向量表和中断服务程序,因为还需要用鼠标和键盘,这些需要中断进行的。

这期间也需要给客户输出一些结果,做了什么事情,做到什么程度,要显示给客户。 就是内存空间映射显存的空间,在显示器上显示一些字符。

在这里插入图片描述

二、bootloader时期

BIOS(创业指导手册)只能保障公司成立起来,如何做大做强需要另外一个经营方法。

操作系统很重要,操作系统放在硬盘上,BIOS的界面上看到一个启动盘的选项。
启动盘:一般在第一个扇区,占512字节,而且以0xAA55结束。
这是一个约定,当满足这个条件就说明是个启动盘,在512字节以内会启动相关代码。

这些代码是谁放的呢?
Linux里面有一个工具,叫Grub2 ,全称是 Grand Unified Bootloader Version 2 就是搞系统启动的。

你可以通过grub2-mkconfig -o /boot/grub2/grub.cfg 来配置系统的启动项,


menuentry 'CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-862.el7.x86_64-advanced-b1aceb95-6b9e-464a-a589-bed66220ebee' {
  load_video
  set gfxpayload=keep
  insmod gzio
  insmod part_msdos
  insmod ext2
  set root='hd0,msdos1'
  if [ x$feature_platform_search_hint = xy ]; then
    search --no-floppy --fs-uuid --set=root --hint='hd0,msdos1'  b1aceb95-6b9e-464a-a589-bed66220ebee
  else
    search --no-floppy --fs-uuid --set=root b1aceb95-6b9e-464a-a589-bed66220ebee
  fi
  linux16 /boot/vmlinuz-3.10.0-862.el7.x86_64 root=UUID=b1aceb95-6b9e-464a-a589-bed66220ebee ro console=tty0 console=ttyS0,115200 crashkernel=auto net.ifnames=0 biosdevname=0 rhgb quiet 
  initrd16 /boot/initramfs-3.10.0-862.el7.x86_64.img
}

这里面的选项会在系统启动时候,成为一个列表,让你选择从哪个系统启动:
在这里插入图片描述

使用grub2-install /dev/sda 可以将启动程序安装到相应的位置。

grub2 第一个要安装的就是boot.img。它由boot.S编译而成,一共512字节,正式安装到启动盘的第一个扇区。这个扇区称为MBR(Master Boot Record 主引导记录扇区)

BIOS 完成任务后,会将boot.img从硬盘加载到内存中的0x7c00来运行。

由于512个字节实在有限,boot.img 做不了太多的事情。它能做的最重要的一个事情就是加载grub2的另一个镜像 core.img。

引导扇区就是你找的门卫,虽然它看着档案库的大门,但是知道的事情很少,它不知道你的宝典在哪里,它把你领导档案管理员哪里,档案管理员知道。

core.img 就是管理员,知道和能做的事情就多一些了。core.img 由lzma_decompress.img,di’s’kboot.img,kernel.imgh和一系列模块组成,功能比较丰富能做很多事情。

在这里插入图片描述

boot.img 先加载的是core.img 的第一个扇区,如果从硬盘启动的话,这个扇区里面是diskboot.img,对应的代码是diskboot.S。

boot.img 将控制权交给diskboot.img 后,diskboot.img 的任务就是将core.img 的其他部分加载进来:先是解压缩程序lzma_decompress.img 再往下是kernel.img,最后是各个模块module 对应的映像。 这个不是 Linux 内核,是grub的内核。

lzma_decompress.img 对应的代码是 startup_raw.S ,本来kernel.img 是压缩过的,现在执行的时候,需要解压缩。

在这之前,我们遇到的程序都非常小,在实模式下就可以运行了,随着加载的东西越来越大,实模式这1M的地址空间实在放不下了。

在真正解压缩之前,lzma_decompress.img 做了一个重要的决定,就是调用real_to_prot 切换到保护模式下,这样能在更大的寻址空间里面,加载更多的东西。

三、从实模式切换到保护模式

管理处听说要找宝典,知道你是要做老板的人,既然是老板,就要雇人干活,不是个体户小打小闹。所以需要切换到老板角色进入保护模式,把哪些是你的权限,哪些是可以授权给别人的都分得清清楚楚。

切换到保护模式要干很多工作,大多数和内存的访问方式有关。

第一项:启用分段

在内存里建立段描述符表,将寄存器里面的段寄存器变成段选择子,指向某个d段描述符,这样就能实现不同的进程的切换了。

第二项:启动分页

能够管理的内存变大了,就需要将内存分成相等大小的块。这些放在内存那一节详细再讲。

切换到老板角色,也是为了招聘很多人,同时接多个项目,这个时候就需要划清界限,懂的集权与授权。

当了老板,眼界就要宽多了,同理保护模式下需要做一项工作,打开Gate A20,就是第21根地址线的控制线。在实模式8086下面,一共就20个地址总线,可以访问1M的地址空间。
如果超过了怎么办,只能是绕回来。在保护模式下,第21根要起作用了,我们就需要打开Gate A20 。

切换保护模式的函数 DATA32 call real_to_prot 会打开Gate A20,也就是第21根地址线的控制线。

现在好了,有的是空间了,接下来要对压缩过的kernel.img 进行解压缩,然后跳转到kernel.img 开始运行。

切换到老板的角色,就可以正大光明的进入档案馆,寻找你的那本宝典。

kernel.img 对应的代码是 startup.S 以及一堆c文件,在startup.S 中会调用grub_main,这是grub kernel 的主函数。

在这个函数里面,grub_load_config() 开始解析,我们上面写的那个grub.conf 文件里面的配置信息。

如果是正常启动,grub_main 最后会调用grub_command_execute(“normal”,0,0),最终会调用grub_normal_execute()函数。 在这个函数里面,grub_show_menu() 会显示出让你选择的那个操作系统的列表。

同理,作为老板,你发现这类的宝典不止一本,经营企业的方式也有很多种,到底是人性化的还是强纪律的,需要选择一种。

一旦,你选定了某个宝典,启动某个操作系统,就要开始调用grub_menu_execute_entry() ,开始解析并执行你选择的那一项,接下来你的经营企业之路就此打开了。

例如里面的linux16命令,表示装载指定的内核文件,并传递内核启动参数,于是grub_cmd_linux() 函数会被调用,它会首先读取Linux内核镜像头部的一些数据结构,放到内存中的数据结构来,进行检查,如果检查通过,则会读取整个Linux内核镜像到内存中。

如果配置文件里面还有initrd命令,用于为即将启动的内核传递 init ramdisk 路径,于是 grub_cmd_initrd() 函数会被调用,将 initramfs 加载到内存中来。

当这些事情做完以后,grub_command_execute(“boot”,0,0) 才开始真正的启动内核。

四、总结时刻

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值