从BIOS到Bootloader

BIOS简介

BIOS 是英文"Basic Input Output System"的缩略词,直译过来后中文名称就是"基本输入输出系统"。在IBM PC兼容系统上,是一种业界标准的固件接口 [1] BIOS这个字眼是在1975年第一次由CP/M操作系统中出现。 BIOS是个人电脑启动时加载的第一个软件
BIOS是一组固化到计算机主板上一个ROM芯片上的程序它保存着计算机最重要的基本输入输出的程序、开机后自检程序和系统自启动程序,它可从CMOS中读写系统设置的具体信息。 其主要功能是为计算机提供最底层的、最直接的硬件设置和控制。
简单来说就是在主板上,有一个东西叫ROM(Read Only Memory,只读存储 器)。这和咱们平常说的内存RAM(Random Access Memory,随机存取存储器)不 同。
咱们平时买的内存条是可读可写的,这样才能保存计算结果。而 ROM 是只读的,上面早 就固化了一些初始化的程序,也就是BIOS。

如果你自己安装过操作系统,刚启动的时候,按某个组合键,显示器会弹出一个蓝色的界 面。能够调整启动顺序的系统,就是我说的 BIOS,然后我们就可以先执行它。


bios.png

BOIS空间利用

image.png

在 x86 系统中,将 1M 空间最上面的 0xF0000 到 0xFFFFF 这 64K 映射给 ROM,也就是 说,到这部分地址访问的时候,会访问 ROM。
当电脑刚加电的时候,会做一些重置的工作,将 CS 设置为 0xFFFF,将 IP 设置为 0x0000,所以第一条指令就会指向 0xFFFF0,正是在 ROM 的范围内。在这里,有一个 JMP 命令会跳到 ROM 中做初始化工作的代码,于是,BIOS 开始进行初始化的工作。

BIOS存在的目的

包括:检测硬件、初始化硬件、分配资源(如IO地址、IRQ号、DMA通道等)以及协助加载操作系统。

BIOS经历的三个阶段

从主机上电到加载bootloader这个过程中,系统BIOS主要经历了三个阶段:Power on ,POST ,加载bootloader .

Power On 阶段 这一阶段从上电开始到屏幕出现信息结束,也就是所谓的激活电源阶段。这一阶段的主要任务是校验CMOS中的内容是否正确、检查主机上某些硬件的状态以确定下一步的自检,因此,用户无法在屏幕上看到BIOS信息(要等硬件确认后才激活VGA) ,若这个阶段出现错误一般都是致命的(通常为黑屏),只能通过喇叭声来判断错误类型。这个阶段只是检查系统上都有哪些设备,并不初始化。

POST(power on self test)开机自检阶段, 检查一些关键设备如内存、显卡能否正常工作,并提供简易的内存测试,只要测试没问题,就在屏幕上显示该硬件的基本信息。这个阶段的基本过程如下:系统BIOS查找显卡的BIOS,存放显卡BIOS的ROM芯片的起始地址通常在C0000H处,然后调用其初始化代码,由显卡的BIOS完成显卡的初始化,然后屏幕就可以显示信息了,大多数的显卡会在这时显示显卡的一些信息,但是通常只是一闪而过。依次类推,系统BIOS调用在前一个阶段找到的设备的BIOS代码,以完成相应设备的初始化。查完其它所有设备后,BIOS将显示自己的启动画面,接着检查CPU的类型和工作频率、主机的内存容量,然后系统BIOS开始测试和配置系统中安装的一些标准硬件设备如硬盘、光驱、COM口、并口等,然后BIOS开始检查并配置系统中的即插即用设备。开机时和开机后所有需要用到的设备都是在这个阶段被激活的。

加载bootloader阶段 当所有的硬件都检测完毕并没有问题后,BIOS退居幕后的办法是将加载OS的主控权交给硬盘的主引导扇区MBR即硬盘的物理扇区0柱0面1扇区上的内容,让藏匿于此的开机管理程序(bootloader)将指针带到系统核心的地方。linux常见的开机管理程序为Grub2.全称 Grand Unified Bootloader Version 2。顾名思义,就是搞系统启动的。

综上,系统激活流程为:打开电源开关—CPU初始化—BIOS激活—读取并校验CMOS资料、检测硬件状态(此时BIOS代码在flash memo中运行)—生成SMBIOS表格—检测、配置并初始化各硬件—加载bootloader 。

Bootloader

引导加载程序是系统加电后运行的第一段软件代码,称之为Bootloader。BootLoader是Booter和Loader的合写:前者意味着要初始化嵌入式系统硬件使之运行起来,至少是部分运行起来,与PC机中的BIOS作用相似;后者意味着将嵌入式操作系统映像加载到内存中,并跳转过去运行。如PC机中MBR上的BootLoader(PC机中的引导加载程序由BIOS(其本质就是一段固件程序)和位于硬盘MBR中的OS BootLoader(比如,LILO和GRUB等)一起组成。BIOS在完成硬件检测和资源分配后,将硬盘MBR中的BootLoader读到系统的RAM中,然后将控制权交给OS BootLoader。BootLoader的主要运行任务就是将内核映象从硬盘上读到 RAM 中,然后跳转到内核的入口点去运行,也即开始启动操作系统。)

Grub2

开机管理程序Grub2,全称 Grand Unified Bootloader Version 2。顾名思义,就是搞系统启动的。
你可以通过 grub2-mkconfig -o /boot/grub2/grub.cfg 来配置系统启动的选项。你可以 看到里面有类似这样的配置。


image.png

这里面的选项会在系统启动的时候,成为一个列表,让你选择从哪个系统启动。最终显示出
来的结果就是下面这张图。至于上面选项的具体意思,我们后面再说。


image.png

使用 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 由 lzma_decompress.img、diskboot.img、kernel.img 和一系列的模块组成,功能比较丰 富,能做很多事情。


image.png

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,切换到保护模 式,这样就能在更大的寻址空间里面,加载更多的东西。

从实模式切换到保护模式

系统都有一个安全模式或者是保护模式,切换到保护模式要干很多工作,大部分工作都与内存的访问方式有关。
第一项是启用分段,就是在内存里面建立段描述符表,将寄存器里面的段寄存器变成段选择 子,指向某个段描述符,这样就能实现不同进程的切换了。第二项是启动分页。能够管理的 内存变大了,就需要将内存分成相等大小的块。
切换保护模式的函数 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) 才开始真正地启动内 核。




扩展阅读:
BIOS 工作流程解析
常见bootloader介绍
实模式和保护模式

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容