我无法在任何地方找到这些信息。无论我到哪里,我都会发现,一旦你点击“主要”(无论你的入口点是什么),这可能是程序参数和环境,看看堆栈的外观,但我正在寻找的是系统如何设置堆栈与switch_to宏配合。第一次切换到任务时,需要有EFLAGS,EBP,GCC保存的寄存器,以及来自“tsk-> thread-> esp”指向的堆栈上schedule()函数的返回地址“,但我无法弄清楚内核是如何设置这个堆栈的,因为它允许GCC保存通用寄存器(使用内联汇编的输出参数)。
我指的是x86个人电脑。我正在为我自己的(尝试)编写的小内核研究Linux调度程序/进程系统,而我无法理解我所缺少的内容。我知道我遗漏了一些东西,因为Slackware在我的计算机上运行这一事实证明了调度程序的工作原理:P
编辑:我似乎措辞严厉。我正在寻找有关如何设置任务内核堆栈的信息,而不是如何设置任务用户任务的信息。更具体地说,tsk-> thread-> esp指向的堆栈,以及“switch_to”切换到的堆栈。答案 0 :(得分:6)
新进程的初始内核堆栈在copy_thread()
中设置,这是一个特定于arch的函数。例如,x86版本就像这样开始:
int copy_thread(unsigned long clone_flags, unsigned long sp,
unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
struct pt_regs *childregs;
struct task_struct *tsk;
int err;
childregs = task_pt_regs(p);
*childregs = *regs;
childregs->ax = 0;
childregs->sp = sp;
p->thread.sp = (unsigned long) childregs;
p->thread.sp0 = (unsigned long) (childregs+1);
p->thread.ip = (unsigned long) ret_from_fork;
p->thread.sp
和p->thread.ip
分别是新线程的内核堆栈指针和指令指针。
请注意,不将保存的%eflags
,%ebp
等放在那里,因为当新创建的执行线程首次切换到时,它会开始执行在ret_from_fork
(这是__switch_to()
返回新线程的地方),这意味着它不执行switch_to()
例程的后半部分
答案 1 :(得分:2)
在X86-64 SVR4 ABI补充中描述了进程创建时的堆栈状态(对于AMD64,即x86-64 64位计算机)。 32位Intel处理器的等效值可能为ABI i386。我强烈建议您阅读Assembly HOWTO。当然,您应该阅读相关的Linux内核文件。
答案 2 :(得分:2)
Google for“linux stack layout process startup”给出了this链接:“Linux / i386 ELF二进制文件的启动状态”,它描述了在将控制转移到libc启动代码之前内核执行的设置