进程创建时 Linux 进程内核堆栈状态是什么?
我在任何地方都找不到这个信息。在我到处寻找的地方,我发现了一些关于一旦你点击“main”(无论你的入口点是什么)堆栈看起来如何的东西,这将是程序参数和环境,但我正在寻找的是系统如何设置堆栈与 switch_to 宏配合。任务第一次切换到时,需要有 EFLAGS、EBP、GCC 保存的寄存器以及“tsk->thread->esp”指向的堆栈上的 Schedule() 函数的返回地址”,但我不明白的是内核如何设置这个堆栈,因为它让 GCC 保存通用寄存器(使用内联汇编的输出参数)。
我仅指 x86 PC。我正在研究我自己的小内核的 Linux 调度程序/进程系统,我正在(尝试)编写它,但我无法理解我所缺少的内容。我知道我错过了一些东西,因为 Slackware 在我的计算机上运行这一事实证明了调度程序的工作事实:P
编辑:我似乎措辞很糟糕。我正在寻找有关如何设置任务内核堆栈的信息,而不是如何设置任务用户任务的信息。更具体地说,tsk->thread->esp 指向的堆栈,以及“switch_to”切换到的堆栈。
I can't find this information anywhere. Everywhere I look, I find things referring to how the stack looks once you hit "main" (whatever your entry point is), which would be the program arguments, and environment, but what I'm looking for is how the system sets up the stack to cooperate with the switch_to macro. The first time the task gets switched to, it would need to have EFLAGS, EBP, the registers that GCC saves, and the return address from the schedule() function on the stack pointed to by "tsk->thread->esp", but what I can't figure out is how the kernel sets up this stack, since it lets GCC save the general purpose registers (using the output parameters for inline assembly).
I am referring to x86 PCs only. I am researching the Linux scheduler/process system for my own small kernel I am (attempting) to write, and I can't get my head around what I'm missing. I know I'm missing something since the fact that Slackware is running on my computer is a testament to the fact that the scheduler works :P
EDIT: I seem to have worded this badly. I am looking for information on how the tasks kernel stack is setup not how the tasks user task is setup. More specifically, the stack which tsk->thread->esp points to, and that "switch_to" switches to.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
新进程的初始内核堆栈在copy_thread() 中设置,这是一个特定于架构的函数。例如,x86 版本是这样开始的:
p->thread.sp
和p->thread.ip
是新线程的内核堆栈指针和指令分别为指针。请注意,它不会在那里放置已保存的
%eflags
、%ebp
等,因为当新创建的执行线程第一次切换到,它从ret_from_fork
开始执行(这是__switch_to()
返回新线程的位置),这意味着它不执行后半部分switch_to()
例程。The initial kernel stack for a new process is set in
copy_thread()
, which is an arch-specific function. The x86 version, for example, starts out like this:p->thread.sp
andp->thread.ip
are the new thread's kernel stack pointer and instruction pointer respectively.Note that it does not place a saved
%eflags
,%ebp
etc there, because when a newly-created thread of execution is first switched to, it starts out executing atret_from_fork
(this is where__switch_to()
returns to for a new thread), which means that it doesn't execute the second-half of theswitch_to()
routine.X86-64 SVR4 ABI 中描述了进程创建时的堆栈状态补充(对于 AMD64,即 x86-64 64 位机器)。 32 位 Intel 处理器的等效项可能是 ABI i386。我强烈建议您还阅读Assembly HOWTO。当然,您也许应该阅读相关的 Linux 内核文件。
The state of the stack at process creation is described in the X86-64 SVR4 ABI supplement (for AMD64, ie x86-64 64 bits machines). The equivalent for 32 bits Intel processor is probably ABI i386. I strongly recommend reading also Assembly HOWTO. And of course, you should perhaps read the relevant Linux kernel file.
Google 对于“Linux 堆栈布局进程启动”给出了 此 链接:“Linux 的启动状态/i386 ELF 二进制文件”,它描述了内核在将控制权转移到 libc 启动代码之前执行的设置。
Google for "linux stack layout process startup" gives this link: "Startup state of a Linux/i386 ELF binary", which describes the set up that the kernel performs just before transferring control to the libc startup code.