Xv6内核分析(三.11)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2020年12月20日16:43:12 评论 475

main函数之startothers

1. startothers函数

startothers函数用来启动其他从核运行,大致的思想就是:首先设置好从核需要运行的代码的地址,然后使用核间中断IPI通知从核启动,从核启动后就从设置的代码地址处开始运行。

Xv6内核分析(三.11)

在xv6中的具体代码如下:

Xv6内核分析(三.11)

2. 从核启动

从核的入口代码在entryother.S中,从核运行的代码地址必须在4KB对齐的地方,xv6中这个地址是0x7000。entryothers在生成二进制文件时指定入口点为start以及加载地址和链接地址都为0x7000,如下:

Xv6内核分析(三.11)

2.1 从核启动代码重定位

从注释中可以看出_binary_entryother_start和_binary_entryother_size分别表示entryothers文件在内存中的起始虚拟地址和大小。由于entryothers起始地址和链接地址在0x7000,所以需要将entryothers代码复制到0x7000位置处,这就是通过下面代码实现的:

Xv6内核分析(三.11)

2.2 从核启动条件准备

对每一个从核cpu调用lapicstartap来启动从核运行:

Xv6内核分析(三.11)

在启动每个从核之前,还做了一下三件事:

  • 为每个从核分配内核栈,并记录栈地址。
  • 记录从核C语言运行函数地址。
  • 记录启动用的页目录基址。

Xv6内核分析(三.11)

2.3 lapicstartup函数

Xv6内核分析(三.11)

这个函数z只接受两个参数,要启动的cpu,要启动的cpu运行代码的地址。根据MP规范手册,启动从核总体分三个步骤。

2.3.1 设置从核启动地址

设置CMOS的shutdown code寄存器,设置从核运行的code地址:

Xv6内核分析(三.11)

  • 首先必须将CMOS的shutdown code寄存器设置为0x0A,这通过操作CMOS的端口实现。
  • 然后设置warm reset vector,warm reset vector表示从核启动的地址,warm reset vector本身所在的物理地址是0x467。
2.3.2 发送INIT IPI信息

发送INIT类型的IPI给相应的从核:

Xv6内核分析(三.11)

2.3.3 发送STARTUP IPI信息

发送STARTUP IPI给相应的从核,当IPI类型为STARTUP时,ICR寄存器的vector位表示的是从核启动时运行的物理地址,有图中的代码可知,这个物理地址一定要是4KB对齐的,所以addr右移了12位。

Xv6内核分析(三.11)

2.4 主核等待从核启动

当主核执行完lapicstartap后,相应的从核就从entryothers开始运行了,然后主核通过检查从核cpu结构中的started来判断从核是否启动完毕,如果启动完毕,就接着去启动下一个从核:

Xv6内核分析(三.11)

gewenbin
  • 本文由 发表于 2020年12月20日16:43:12
  • 转载请务必保留本文链接:http://www.databusworld.cn/9392.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: