main函数之startothers
1. startothers函数
startothers函数用来启动其他从核运行,大致的思想就是:首先设置好从核需要运行的代码的地址,然后使用核间中断IPI通知从核启动,从核启动后就从设置的代码地址处开始运行。
在xv6中的具体代码如下:
2. 从核启动
从核的入口代码在entryother.S中,从核运行的代码地址必须在4KB对齐的地方,xv6中这个地址是0x7000。entryothers在生成二进制文件时指定入口点为start以及加载地址和链接地址都为0x7000,如下:
2.1 从核启动代码重定位
从注释中可以看出_binary_entryother_start和_binary_entryother_size分别表示entryothers文件在内存中的起始虚拟地址和大小。由于entryothers起始地址和链接地址在0x7000,所以需要将entryothers代码复制到0x7000位置处,这就是通过下面代码实现的:
2.2 从核启动条件准备
对每一个从核cpu调用lapicstartap来启动从核运行:
在启动每个从核之前,还做了一下三件事:
这个函数z只接受两个参数,要启动的cpu,要启动的cpu运行代码的地址。根据MP规范手册,启动从核总体分三个步骤。
2.3.1 设置从核启动地址
设置CMOS的shutdown code寄存器,设置从核运行的code地址:
- 首先必须将CMOS的shutdown code寄存器设置为0x0A,这通过操作CMOS的端口实现。
- 然后设置warm reset vector,warm reset vector表示从核启动的地址,warm reset vector本身所在的物理地址是0x467。
2.3.2 发送INIT IPI信息
发送INIT类型的IPI给相应的从核:
2.3.3 发送STARTUP IPI信息
发送STARTUP IPI给相应的从核,当IPI类型为STARTUP时,ICR寄存器的vector位表示的是从核启动时运行的物理地址,有图中的代码可知,这个物理地址一定要是4KB对齐的,所以addr右移了12位。
2.4 主核等待从核启动
当主核执行完lapicstartap后,相应的从核就从entryothers开始运行了,然后主核通过检查从核cpu结构中的started来判断从核是否启动完毕,如果启动完毕,就接着去启动下一个从核:
评论