欢迎光临散文网 会员登陆 & 注册

玩转Linux多核SMP系统的引导,从这几点入手!

2022-04-23 17:11 作者:补给站Linux内核  | 我要投稿

本篇文章基于Linux 2.6.32,x86体系结构

  • 系统的引导和初始化阶段是个特例,因为在这个阶段里系统中只有一个"上下文",只能由一个处理器来处理。在这个阶段里,也就是在系统刚加电或"总清(reset)"之后,系统中暂时只有一个处理器运行,这个处理器称之为"引导处理器"BP;其余的处理器则处于暂停状态,称为"应用处理器"AP。"引导处理器"完成整个系统的引导和初始化,并创建起多个进程,从而可以由多个处理器同时参与处理时,才启动所有的"应用处理器",让他们完成自身的初始化以后,投入运行。参考intel手册:

MP 初始化协议定义了两类处理器:引导处理器 (BSP) 和应用处理器 (AP)。在 MP 系统通电或重置后,系统硬件动态选择系统总线上的一个处理器作为 BSP。其余处理器被指定为 AP。

  • 我们在这里关心的是"引导处理器"怎样为各个"应用处理器"做好准备,然后启动其运行的过程。

  • 在初始化阶段,引导处理器先完成自身的初始化,进入保护模式并开启页式存储管理机制,再完成系统特别是内存的初始化,然后从 –> –> –> 进行SMP系统的初始化。由于此时APs处于暂停状态,所以BP需要通过 –> –> –> –> 发送IPI中断唤醒APs,这样APs就开始了正常的运行过程,拥有和BP一样的地位。详细过程我们后面分析。先来看总体大纲图:start_kernel()rest_init()kernel_init()smp_init()smp_init()cpu_up()native_cpu_up()do_boot_cpu()wakeup_secondary_cpu_via_init()


【文章福利】小编推荐自己的Linux内核技术交流群:【891587639】整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!!!前100名进群领取,额外赠送一份价值699的内核资料包(含视频教程、电子书、实战项目及代码) 


  • smp_init的代码在init/main.c:

native_cpu_up的注册:

native_cpu_up

  • 接下来看标号(1)处 native_cpu_up(unsigned int cpu) 。依次启动系统中各个CPU。

1、do_boot_cpu

  • 发送IPI中断唤醒APs,并且在IPI中断中,带有AP唤醒后要执行的代码地址(实际上只是一个vector,AP会把这个vector«12作为要执行的代码地址)。

2、wakeup_secondary_cpu_via_init发送IPI

  • 发送IPI中断,至于为什么这里apic_icr_write可以发送vector到AP,请参考intel文档。

  • AP接收到IPI,就开始激活执行了。

3、蹦床。S 这段代码就是前面do_boot_cpu()—>setup_trampoline()拷贝到trampoline_base的代码:

  • 在这段代码中,设置标识,以便BSP知道该AP已经运行到这段代码,加载GDT和LDT表基址。然后启动保护模式,更新CS段寄存器,跳转到startup_32_smp 处。

4、startup_32_smp

  • 这个函数的主要作用在于开启分页,更新EIP,ESP。重新设置GDT,更新所有的段寄存器,最后跳转到start_secondary执行。

5、start_secondary

  • 此时分页和保护模式都已经开启,且完全进入BP事先为我们fork好的idel线程的上下文。

  • 本函数主要是通知BP本AP启动完成,然后cpu_idle,参与到任务调度。

总结

  • 整理一下AP启动的整个过程:

  1. wakeup_secondary_cpu_via_init:BP发送IPI中断给AP

  2. 蹦床。S AP引导代码,为16进制代码,启用保护模式

  3. head.s 为AP创建分页管理

  4. start_secondary 通知BP启动成功。AP参与任务调度。

F&Q:

  • 每个AP自己的GDTR在哪里设置的?(每个AP的GDT都已经由BP处理器初始化完成,就等待设置到CPU上)

  • 发送IPI到AP后,CS:IP如何设置的?

CS 为 0x**00(**代表IPI中包含的vector),IP为0,CS:IP就可以引用trampoline.S中的代码


玩转Linux多核SMP系统的引导,从这几点入手!的评论 (共 条)

分享到微博请遵守国家法律