进程创建时 Linux 进程内核堆栈状态是什么?

发布于 2024-12-14 01:06:01 字数 529 浏览 1 评论 0原文

我在任何地方都找不到这个信息。在我到处寻找的地方,我发现了一些关于一旦你点击“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盗琴音 2024-12-21 01:06:01

新进程的初始内核堆栈在copy_thread() 中设置,这是一个特定于架构的函数。例如,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.spp->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:

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 and p->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 at ret_from_fork (this is where __switch_to() returns to for a new thread), which means that it doesn't execute the second-half of the switch_to() routine.

你的背包 2024-12-21 01:06:01

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.

虚拟世界 2024-12-21 01:06:01

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文