简体   繁体   English

Linux 内核 0.11 中的进程 0 堆栈

[英]Stack of process 0 in Linux kernel 0.11

I'm currently learning linux kernel source code (v0.11).我目前正在学习 linux 内核源代码 (v0.11)。 The following is the main() function of init/main.c :以下是init/main.cmain()函数:

void main(void) 
{
    ...
    move_to_user_mode();
    if (!fork()) {      /* we count on this going ok */
        init();
    }

where in move_to_user_mode , process 0 goes to user mode by doing this:move_to_user_mode ,进程 0 通过执行以下操作进入用户模式:

#define move_to_user_mode() \
__asm__ ("movl %%esp,%%eax\n\t" \
    "pushl $0x17\n\t" \
    "pushl %%eax\n\t" \
    "pushfl\n\t" \
    "pushl $0x0f\n\t" \
    "pushl $1f\n\t" \
    "iret\n" \
    "1:\tmovl $0x17,%%eax\n\t" \
    "movw %%ax,%%ds\n\t" \
    "movw %%ax,%%es\n\t" \
    "movw %%ax,%%fs\n\t" \
    "movw %%ax,%%gs" \
    :::"ax")

After iret , it seems like that the user mode ss:esp points to the same stack as it is in kernel mode.iret之后,似乎用户模式ss:esp指向与内核模式相同的堆栈。 ie p0's user stack = p0's kernel stack.即 p0 的用户堆栈 = p0 的内核堆栈。 Is this true?这是真的?

When p0 calls fork , it calls copy_process , which copies its user mode ss:esp to p1's tss->ss and tss->esp .当 p0 调用fork ,它调用copy_process ,它将其用户模式ss:esp复制到 p1 的tss->sstss->esp So will p1 share the same user mode stack as p0?那么 p1 会与 p0 共享相同的用户模式堆栈吗? If so, p1's user stack = p0's user stack = p0's kernel stack.如果是这样,p1 的用户堆栈 = p0 的用户堆栈 = p0 的内核堆栈。 Will this cause any problem?这会导致任何问题吗?

The copy_process is as following: copy_process如下:

int copy_process(int nr,long ebp,long edi,long esi,long gs,long none,
        long ebx,long ecx,long edx,
        long fs,long es,long ds,
        long eip,long cs,long eflags,long esp,long ss)
{
    ...
    p->tss.esp = esp;
    ...
    p->tss.ss = ss & 0xffff;
    ...
}

PS p0's kernel stack is below LOW_MEMORY, which means it does not support COW. PS p0 的内核堆栈低于 LOW_MEMORY,这意味着它不支持 COW。

p0's user stack is the user_stack defined in kernel/sched.c , which is the same stack used before move_to_user_mode , and which is the value of the pushed esp in move_to_user_mode . P0的用户栈是user_stack中定义kernel/sched.c ,这是以前使用相同的堆栈move_to_user_mode ,并且其是被推动的值espmove_to_user_mode And after move_to_user_mode , p0 should not use this space (this is why the following fork and pause are inline function) since p1's user stack also points to this space when p0 calls fork to produce p1.而在move_to_user_mode之后,p0 不应该使用这个空间(这就是为什么下面的forkpause是内联函数的原因),因为当 p0 调用fork生成 p1 时,p1 的用户堆栈也指向这个空间。 This space is set to read-only in p1's page table.该空间在 p1 的页表中设置为只读。 When p1 wants to use this space, it will trigger a page fault, and then trigger COW for this space, ie the kernel will allocate a new page for p1's stack.当 p1 想要使用这个空间时,它会触发一个页面错误,然后为这个空间触发 COW,即内核会为 p1 的堆栈分配一个新的页面。

Conclusion:结论:

  1. p0's user stack = p1's user stack right after fork . p0 的用户堆栈 = 在fork之后 p1 的用户堆栈。

  2. p0 does not use its user stack. p0 不使用其用户堆栈。

  3. p1 will trigger COW on this stack space when it wants to write to the stack.当 p1 想要写入堆栈时,它会在这个堆栈空间上触发 COW。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM