在arm linux中,进程的运行处于两种模式之一,要么在用户空间运行(用户模式USR_MODE),要么在内核空间运行(SVC_MODE)。在内核空间时,处于特权模式,在用户空间时,处于普通模式。
用户空间运行时和内核空间运行时,所用的堆栈是不同的。
本文基于linux-3.11.1代码来学习这两种运行空间下,堆栈是如何运作的(切换)。
linux-3.11.1/kernel/fork.c
SYSCALL_DEFINE0(fork) -> do_fork() -> copy_process() -> copy_thread()
本文基于ARM来学习,这里copy_thread()定义在linux-3.11.1/arch/arm/kernel/process.c
367行设置task的内核空间的栈指针为childregs.
linux-3.11.1/arch/arm/include/asm/process.h
linux-3.11.1/arch/arm/include/asm/thread_info.h
linux-3.11.1/include/linux/sched.h
task->stack 为thread_info,在task_struct之后,故,内核态堆栈的位置如下:
注意这里,pt_regs中的所有寄存器,除了r0外的其他寄存器的值,对于非内核线程,全部拷贝自父进程,r0寄存器设为0,即子进程fork()的返回值(pid)为0.
copy_thread()除了设置了内核态栈的地方后,还设置了