gpt4 book ai didi

c - Linux 内核 0.11 中的进程 0 堆栈

转载 作者:行者123 更新时间:2023-12-01 01:39:49 26 4
gpt4 key购买 nike

我目前正在学习 linux 内核源代码 (v0.11)。以下是 main()init/main.c 函数:

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

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")

iret 之后,似乎用户模式 ​​ ss:esp 指向与内核模式相同的堆栈。即 p0 的用户堆栈 = p0 的内核堆栈。这是真的?

当 p0 调用 fork 时,它​​会调用 copy_process ,它将其用户模式 ​​ ss:esp 复制到 p1 的 tss->sstss->esp 。那么 p1 会与 p0 共享相同的用户模式堆栈吗?如果是这样,p1 的用户堆栈 = p0 的用户堆栈 = p0 的内核堆栈。这会导致任何问题吗?
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;
...
}

附言p0 的内核堆栈低于 LOW_MEMORY,这意味着它不支持 COW。

最佳答案

p0 的用户栈是 user_stack 中定义的 kernel/sched.c ,与 move_to_user_mode 之前使用的栈相同,是 esp 中压入的 move_to_user_mode 的值。在 move_to_user_mode 之后,p0 不应该使用这个空间(这就是为什么下面的 forkpause 是内联函数的原因),因为当 p0 调用 fork 生成 p1 时,p1 的用户堆栈也指向这个空间。该空间在 p1 的页表中设置为只读。当 p1 要使用这个空间时,它会触发一个页面错误,然后为这个空间触发 COW,即内核将为 p1 的堆栈分配一个新页面。

结论:

  • p0 的用户堆栈 = p1 的用户堆栈紧跟在 fork 之后。
  • p0 不使用其用户堆栈。
  • p1 想要写入堆栈时,它会在这个堆栈空间上触发 COW。
  • 关于c - Linux 内核 0.11 中的进程 0 堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59613963/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com