Linux内核引导过程解析:从电源启动到内核初始化

Linux内核引导过程解析:从电源启动到内核初始化

linux-insides-zh Linux 内核揭秘 linux-insides-zh 项目地址: https://gitcode.com/gh_mirrors/li/linux-insides-zh

计算机启动的底层原理

当按下电源按钮时,计算机开始了一段精密的启动过程。主板首先向电源发送信号,电源准备好后会向主板发送"电源正常"信号。收到这个信号后,主板开始初始化CPU,CPU将所有寄存器重置为预定值。

在x86架构中,CPU复位后的寄存器初始状态为:

  • IP(指令指针):0xfff0
  • CS(代码段选择器):0xf000
  • CS基址:0xffff0000

此时CPU运行在实模式(Real Mode)下,这是x86处理器为了兼容早期8086处理器而保留的工作模式。

实模式内存寻址机制

实模式采用段式内存管理,物理地址计算公式为:

物理地址 = 段寄存器值 × 16 + 偏移量

例如CS:IP为0x2000:0x0010时:

0x2000 × 16 + 0x0010 = 0x20010

这种模式下CPU只能访问1MB内存空间,通过A20地址线控制可以访问更多内存。

BIOS启动过程

CPU执行的第一条指令位于0xFFFFFFF0地址,这个地址被映射到主板ROM中。ROM中的代码是BIOS的入口点,BIOS会:

  1. 进行硬件自检(POST)
  2. 初始化硬件设备
  3. 按照配置顺序查找可启动设备
  4. 加载并执行启动设备的引导扇区代码

引导扇区与MBR结构

在硬盘设备上,BIOS会查找主引导记录(MBR),它位于第一个扇区(512字节)中:

  • 前446字节:引导代码
  • 随后64字节:分区表
  • 最后2字节:魔数0x55AA(标识有效引导扇区)

一个简单的引导扇区示例(汇编语言):

[BITS 16]
[ORG 0x7c00]

boot:
    mov al, '!'
    mov ah, 0x0e
    int 0x10
    jmp $

times 510-($-$$) db 0
db 0x55
db 0xaa

这段代码会在屏幕上显示一个感叹号,然后进入无限循环。

GRUB2引导加载程序

现代Linux系统通常使用GRUB2作为引导加载程序,它的工作流程是:

  1. BIOS加载并执行GRUB2的第一阶段代码(boot.img)
  2. boot.img加载并执行core image(diskboot.img)
  3. core image加载GRUB2内核和文件系统驱动
  4. GRUB2读取配置文件并显示启动菜单
  5. 用户选择后,GRUB2加载并启动选中的操作系统

内核启动协议

引导加载程序需要按照Linux内核启动协议准备内核运行环境,包括:

  1. 设置正确的段寄存器值
  2. 初始化堆栈
  3. 清零BSS段
  4. 填充内核头部的必要字段

内核头部定义(header.S)包含关键信息:

.globl hdr
hdr:
    setup_sects: .byte 0
    root_flags:  .word ROOT_RDONLY
    syssize:     .long 0
    vid_mode:    .word SVGA_MODE
    root_dev:    .word 0
    boot_flag:   .word 0xAA55

内核设置代码执行

内核设置代码从_start标签开始,主要完成以下工作:

  1. 统一所有段寄存器值
  2. 设置堆栈指针
  3. 检查魔数签名(0x5A5AAA55)
  4. 清零BSS段
  5. 跳转到main()函数(C代码入口)

堆栈设置需要考虑三种情况:

  1. SS寄存器已经是期望值(0x10000)
  2. SS不是期望值但可以使用堆栈(CAN_USE_HEAP标志置位)
  3. SS不是期望值且不能使用堆栈

进入C语言环境

完成所有准备工作后,通过call指令跳转到main()函数,这是内核中第一个执行的C代码,位于arch/x86/boot/main.c。

main()函数将进行更复杂的初始化工作,包括:

  • 内存检测
  • 设置视频模式
  • 初始化控制台
  • 检测CPU特性
  • 解压内核映像等

至此,计算机完成了从按下电源键到开始执行内核C代码的完整引导过程。这个过程涉及硬件初始化、固件操作、引导加载程序和内核设置代码的精密配合,为操作系统正常运行奠定了基础。

linux-insides-zh Linux 内核揭秘 linux-insides-zh 项目地址: https://gitcode.com/gh_mirrors/li/linux-insides-zh

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周琰策Scott

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值