实模式是什么?
实模式就是系统刚刚启动的时候,采用和8086相同的16位段和偏移量,最大寻址空间1MB,最大分段64KB的模式。在这个模式下,系统的资源还没有完全利用起来,主要是起过度作用。
BIOS
在主板上,有一个东西叫ROM(Read Only Memory,只读存储
器)。ROM 是只读的,买到电脑时,上面就固化了一些初始化的程序,也就是BIOS(Basic Input and Output System,基本输入输出系统)。BIOS就是工作在实模式的(严重怀疑现在很多bios已经不是实模式了,界面一个比一个炫,但是我没证据),在x86的系统里面,实模式能访问的空间是1M。Bios对于计算机的同学来说,都不陌生吧,大概就是长这样:
系统启动的时候,第一件事就是运行bios,电脑加电时CS寄存器设置为0xFFFF,IP设置为0x0000,所以电脑启动后执行的第一条指令就是0xFFFF0指向的指令,而这条指令正是BIOS的第一条指令。关于bios的具体实现笔者也不清楚了,大概要做以下几件:
1、开机自检,修电脑的师傅,往往都会插一个卡在主机里,电脑启动过程中这个卡上的数字不停的在变,这就是BIOS自检时向外界发出的信息。
2、构建一套工作在实模式的系统,包括中断处理等,因为bios至少需要相应键盘。
3、根据bios中的配置找到系统在哪个硬盘,然后执行硬盘上的命令。大家都有过在bios中调整硬盘启动顺序的经历否?这就是告诉bios,应该去哪个硬盘上找操作系统。
bootloader
bios在主板上,bootloader就在硬盘上了,下面先fdisk看下我的硬盘。
硬盘的分区第一个扇区是从2048开始的,0-2047扇区是不是没用?当然不是,这些扇区上面存的就是咱们的bootloader.
硬盘的第一个扇区叫MBR扇区,共计512字节。下面来看下MBR里面都有些什么:
[root@rhel64 tmp]# dd if=/dev/sda of=mbr.hex bs=512 count=1
[root@rhel64 tmp]# hexdump -C mbr.hex
引导代码实际所占用的空间大小为 446 字节,从1be 开始 是四个分区信息 (为什么一个硬盘只有4个主分区?因为MBR里面只能容纳4个主分区的信息,已经没有空地了),固定0xAA55结束。
第三列 对应的 83 8e 是分区类型,可以和下图对应起来。
MBR是由boot.S编译而成,可以通过grub2的命令安装到磁盘的第一个分区。BIOS 完成任务后,会将MBR 从硬盘加载到内存中的 0x7c00 来运行。Mbr只有512字节,能做的事很少,MBR紧接着读硬盘的后续扇区,后面的扇区存放的文件是core.img 文件。该文件大小为 25389 字节,core.img 由lzma_decompress.img、diskboot.img、kernel.img 和一系列的模块组成,功能比较丰富,能做很多事情。
MBR接下来执行diskboot.img,diskboot.img 的任务就是将 core.img 的其他
部分加载进来,先是解压缩程序 lzma_decompress.img,再往下是 kernel.img,最后是各个模块 module 对应的映像。这里需要注意,它不是 Linux 的内核,而是 grub 内核。
lzma_decompress.img 对应的代码是 startup_raw.S,本来 kernel.img 是压缩过的,现在执行的时候,需要解压缩。在这之前,我们所有遇到过的程序都非常非常小,完全可以在实模式下运行,但是随着我们加载的东西越来越大,实模式这 1M 的地址空间实在放不下了,所以在真正的解压缩kernel.img之前,lzma_decompress.img 做了一个重要的决定,就是调用 real_to_prot,切换到保护模式,这样就能在更大的寻址空间里面,加载更多的东西。
那么接下来就从实模式切换到保护模式了。实模式和保护模式最大的区别就是内存访问,当然切换模式最终要的就是启用MMU,分段,分页,让系统能访问到更多的内存。再后面就不是实模式了。