ARM Linux的进程调度(2)

.typesa110_processor_functions, #object
ENTRY(sa110_processor_functions)
.wordv4_early_abort
.wordpabort_noifar
.wordcpu_sa110_proc_init
.wordcpu_sa110_proc_fin
.wordcpu_sa110_reset
.wordcpu_sa110_do_idle
.wordcpu_sa110_dcache_clean_area
.wordcpu_sa110_switch_mm
.wordcpu_sa110_set_pte_ext

对应的有

ENTRY(cpu_sa110_switch_mm)
#ifdef CONFIG_MMU
strlr, [sp, #-4]!
blv4wb_flush_kern_cache_all@ clears IP
mcrp15, 0, r0, c2, c0, 0@ load page table pointer

将指向新进程的首层映射表的指针写入MMU中的寄存器c2,即地址转化表基地址寄存器,
mcrp15, 0, ip, c8, c7, 0@ invalidate I & D TLBs

丢掉高速缓存中原有的地址映射表
ldrpc, [sp], #4
#else
movpc, lr
#endif

这样,CPU的用户空间映射就改变了,但是对当前程序的运行没影响,因为现在CPU运行在系统空间中。

注:进程的调度、切换只能在系统空间中进行。



if (cache_is_vivt())
cpu_clear(cpu, prev->cpu_vm_mask);
}
#endif
}switch_mm函数源码到此结束。



if (unlikely(!prev->mm)) {
prev->active_mm = NULL;
rq->prev_mm = oldmm;
}
/*
* Since the runqueue lock will be released by the next
* task (which is an invalid locking op but in the case
* of the scheduler it's an obvious special-case), so we
* do an early lockdep release here:
*/
#ifndef __ARCH_WANT_UNLOCKED_CTXSW
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
#endif


/* Here we just switch the register state and the stack. */
switch_to(prev, next, prev);


barrier();
/*
* this_rq must be evaluated again because prev may have moved
* CPUs since it called schedule(), thus the 'rq' on its stack
* frame will be invalid.
*/
finish_task_switch(this_rq(), prev);

这一部分,下篇再说。
}context_switch到此结束。

/*
* the context switch might have flipped the stack from under
* us, hence refresh the local variables.
*/
cpu = smp_processor_id();
rq = cpu_rq(cpu);
} else
spin_unlock_irq(&rq->lock);


..........

preempt_enable_no_resched();
if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
goto need_resched;

}schedule函数到此结束

这篇写到这里,也就结束了,我们主要讲述的就是已经找到下一个要运行的进程,现在进行切换,这一篇说的主要是内存管理的切换,即mm_struct结构体。其实,它的切换就是页面目录的切换,当然,不同的处理其会不同。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/wyyyjz.html