ARM Linux 进程调度(3)

王朝system·作者佚名  2006-01-09
宽屏版  字体: |||超大  

switch_mm中是进行页表的切换,即将下一个的pgd的开始物理地址放入CP15中的C2寄存器。进程的pgd的虚拟地址存放在task_struct结构中的pgd指针中,通过__virt_to_phys宏可以转变成成物理地址。

static inline void

switch_mm(struct mm_struct *prev, struct mm_struct *next,

struct task_struct *tsk, unsigned int cpu)

{

if (prev != next)

cpu_switch_mm(next->pgd, tsk);

}

#define cpu_switch_mm(pgd,tsk) cpu_set_pgd(__virt_to_phys((unsigned long)(pgd)))

#define cpu_get_pgd() ({ unsigned long pg; __asm__("mrc p15, 0, %0, c2, c0, 0" : "=r" (pg)); pg &= ~0x3fff; (pgd_t *)phys_to_virt(pg); })

switch_to()完成进程上下文的切换,通过调用汇编函数__switch_to完成,其实现比较简单,也就是保存prev进程的上下文信息,该上下文信息由context_save_struct结构描述,包括主要的寄存器,然后将next的上下文信息读出,信息保存在task_struct中的thread.save中TSS_SAVE标识了thread.save在task_struct中的位置。

/*

* Register switch for ARMv3 and ARMv4 processors

* r0 = previous, r1 = next, return previous.

* previous and next are guaranteed not to be the same.

*/

ENTRY(__switch_to)

stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack

mrs ip, cpsr

str ip, [sp, #-4]! @ Save cpsr_SVC

str sp, [r0, #TSS_SAVE] @ Save sp_SVC

ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC

ldr r2, [r1, #TSS_DOMAIN]

ldr ip, [sp], #4

mcr p15, 0, r2, c3, c0 @ Set domain register

msr spsr, ip @ Save tasks CPSR into SPSR for this return

ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously

struct context_save_struct {

unsigned long cpsr;

unsigned long r4;

unsigned long r5;

unsigned long r6;

unsigned long r7;

unsigned long r8;

unsigned long r9;

unsigned long sl;

unsigned long fp;

unsigned long pc;

};

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有