linux内核smp启动,Linux SMP 启动过程学习笔记

Head.s部分代码:

ENTRY(startup_32_smp)

cld

movl $(__BOOT_DS),%eax

movl %eax,%ds

movl %eax,%es

movl %eax,%fs

movl %eax,%gs

xorl %ebx,%ebx

incl %ebx

如果是AP的话,将bx设置为1

movl $swapper_pg_dir-__PAGE_OFFSET,%eax

movl %eax,%cr3           /* set the page table pointer.. */

movl %cr0,%eax

orl $0x80000000,%eax

movl %eax,%cr0           /* ..and set paging (PG) bit */

ljmp $__BOOT_CS,$1f /* Clear prefetch and normalize %eip */

启用分页,

lss stack_start,%esp

使esp执行fork创建的进程内核堆栈部分,以便后续跳转到start_secondary

#ifdef CONFIG_SMP

movb ready, %cl

movb $1, ready

cmpb $0,%cl

je 1f               # the first CPU calls start_kernel

# all other CPUs call initialize_secondary

call initialize_secondary

jmp L6

1:

#endif /* CONFIG_SMP */

call start_kernel

如果是AP启动的话,就调用initialize_secondary函数。

void __devinit initialize_secondary(void)

{

/*

* We don't actually need to load the full TSS,

* basically just the stack pointer and the eip.

*/

asm volatile(

"movl %0,%%esp/n/t"

"jmp *%1"

:

:"r" (current->thread.esp),"r" (current->thread.eip));

}

设置堆栈为fork创建时的堆栈,ip为fork时的ip,这样就跳转的了start_secondary。

start_secondary函数中处理如下:

while (!cpu_isset(smp_processor_id(), smp_commenced_mask))

rep_nop();

进行smp_commenced_mask判断,是否启动AP运行。smp_commenced_mask 在smp_init()中设置。

cpu_idle();

如果启动了,调用cpu_idle进行任务调度。0b1331709591d260c1c78e86d0c51c18.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值