Linux引导与初始化


1、知识准备

  •  磁盘结构
  •  BIOS
  •  MBR与GRUB

1.1磁盘结构


每张盘片由若干磁道和若干扇区组成,从外向内分别为0磁道,1磁道,2磁道……,不同盘片的同一磁道构成圆柱面称为柱面。柱面由外向内以此为0柱面,1柱面,2柱面……,磁盘将信息存入扇区,扇区大小一般为512Byte。

 

1.2 BIOS

1.2.1是什么?

BIOS的全称是Basic Input Output System,是操作系统与硬件间的一种桥梁。

1.2.2有哪些同类技术?

BIOS目前可分为两类,Legacy BIOS和EFI(是一种新接口,目前大部分是在服务器上出现)

1.2.3 BIOS的作用

1)POST

加电自检,检测CPU各寄存器、计时芯片、中断芯片、DMA控制器等

2)Initial

枚举设备,初始化寄存器,分配中断、IO端口、DMA资源等

3)Setup

进行系统设置,存于CMOS中。一般开机时按Del或者F2进入到BIOS的设置界面。

4)常驻程序

INT 10h、INT 13h、INT 15h等,提供给操作系统或应用程序调用。

5)启动自举程序

在POST过程结束后,将调用INT 19h,启动自举程序,自举程序将读取引导记录,装载操作系统。

 

1.3 MBR与GRUB

1.3.1 MBR(Master Boot Record),主引导记录是什么

MBR 是一个 512 字节大小的扇区,位于磁盘上的第一个扇区中(0 道 0 柱面 1 扇区)。当 MBR 被加载到 RAM 中之后,BIOS 就会将控制权交给 MBR。前 446 个字节是主引导加载程序,其中包含可执行代码和错误消息文本。接下来的 64个字节是分区表,其中包含 4个分区的记录(每个记录的大小是 16 个字节)。MBR 以两个特殊数字的字节(0xAA55)结束。这个数字会用来进行 MBR 的有效性检查。


GRUB是现在一种主流的引导装载程序,以前还有过LILO,现在又新出来一种spfdisk。

1.3.2 与MBR中bootloader同类技术

bootsector。比如说一台机器上同时装有windows和linux,而系统MBR只有一个,那么怎么使用引导程序加载属于不同的操作系统内核呢?

每个文件系统或者说每个Partition都会保留一块引导扇区提供操作系统安装管理程序GRUB,称之为bootsector。GRUB可以安装到bootloader中,也可安装bootsector中。


同时装有windows和linux的机器一定要先装windows,装windows时,MBR的bootloader区和C盘的bootsector区都会默认安装windows的loader程序,再装linux时,bootloader区会被linux的loader覆盖,但bootloader中是linux的loader时能够较好地将引导装载功能转交给windows的loader,但反过来效果却不好。bootloader将引导装载功能转交给其他loader的功能叫做加载扇区。

1.3.3 MBR中Bootloader的功能

主要功能有两个:

(1) 加载扇区:机器安装了多个操作系统时,开机进入系统选单,透过当前MBR中的GRUB去链接其他bootsector中的GRUB

(2)  指向Kernel:认识操作系统的文件格式,并加载内核到内存中去执行。

 

2、引导程序如何引导的?

延续上面一章,我们知道BIOS完成自己的工作后,跳转到0x7C00,将机器的控制权交给MBR中的引导程序,那么引导程序是如何将内核装入内存的呢?

引导程序分两部分:占一个扇区的引导程序(Bootsect)和紧随其后的设置程序(Setup)。如图所示:


2.1 BootSect

Bootsect(该程序在arch/i386/boot/bootsect.S)的主要任务是将操作系统内核从引导盘上读入到内存,并将它摆放在内存的适当位置。完成的主要工作为:

1、将自己移到0x90000处,从新位置开始执行。

2、将堆栈栈底设置在0x94000–12处

(ss=0x9000,sp=0x3FF4)。

3、将磁盘参数拷贝到0x94000-12处,修正该参数。

4、利用BIOS的int 13h读入setup到0x90200处。

5、读入操作系统内核。

小内核(<508KB):装入到0x10000处

大内核(>508KB):装入到0x100000处(int 15h,87h)

6、跳转到setup程序的第一条指令。

内存布局情况图:


2.2 Setup

接下来,该Setup程序发挥作用了,完成如下工作:

1、检查自己是否完整。如不完整,则从内核的前部将自己剩余的部分取回。

2、从BIOS中获取并记录内存大小的信息。int 0x15(0x88、0xe801、0xe820)

3、检测、设置键盘重复频率。

4、检测、设置显示器及其参数。

5、检测、获取硬盘信息。

6、检测、获取微通道、鼠标、APM BIOS等信息

7、准备切换到保护模式

  •   将小内核移到0x1000处。
  •   关中断。
  •   使A20线有效。
  •   重新设置8259控制器(32~46)。
  •   将IDT、GDT的位置装入IDTR、GDTR寄存器。
  •   把CR0的第0位置1,切换到保护模式。
  •   跳转到解压缩程序:
  •   小内核:0x1000。
  •   大内核:0x100000。

事实上,由于系统在引导阶段处理器工作在实模式下,它能访问的内存只有640KB,这限制了Linux内核的大小。为了适应这一限制,Linux通常将自己的内核镜像打包压缩,因此在内核前面必须附加一段没有压缩的解压缩代码,利用该段代码来展开压缩后的Linux内核镜像。


3、内核初始化

引导程序引导完成后,操作系统内核已读入内存,处理器已由实模式切换到保护模式,机器的控制权已交给操作系统内核。正如前面所说,内核真正接管机器控制权之前,需要由内核解压缩程序解压内核镜像。解压缩程序在arch/i386/boot/compressed/head.S,主要完成的工作为:

1、重新设置堆栈(SS、ESP),大小为4KB。

2、解压缩内核映像(decompress_kernel),解压后的结果最终都将放在0x100000处(不管大内核、小内核)。

3、转入内核:

       ljmp $(__KERNEL_CS), $0x100000

 

通过这些步骤之后,真正开始了内核初始化过程,包括:

  • 启动分页机制;
  • 让操作系统各组成部分(内存管理、进程管理等)分别完成自己的初始化,如建立各种管理用的数据结构等;
  • 完成外部设备的初始化;
  • 创建并启动用户进程;
  • 启动Shell或GUI,开始与用户交互

下面重点论述分页机制启动过程。

首先,回顾一下分页机制的一些基本概念。Intel体系结构按页目录和页表两级结构组织一个任务页。

  •  一个页目录大小为一页,4KB,每个页目录项为4字节,因此,一个页目录包含1024个页目录项,即能够描述1024个页表。
  •  一个页表大小为一页,4KB,每个页表项为4字节,因此,一个页表包含1024个页表项,即能够描述1024个页。

线性地址又页目录和页表和偏移量组成,而系统中只有一个页目录,那么线性地址空间能表示的最大范围为1024*1024个4KB页=4GB。进程的线性地址空间分为两部分,内核空间和用户空间:


缺省页目录的位置在物理地址[0x101000,0x101FFF]。

启动分页机制:

       movl $0x00101000,%eax

       movl %eax,%cr3           /* 装入页目录 */

       movl %cr0,%eax   

       orl $0x80000000,%eax

       movl %eax,%cr0           /* 将CR0的PG位置1 */

       jmp 1f                       /* 清除指令预取队列 */

1:

       movl $1f,%eax

       jmp *%eax                   /*确定eip已被重装入 */

1:                                    /* 分页机制就此启动 */

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值