[英]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.c
的main()
函数:
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->ss
和tss->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
,并且其是被推动的值esp
中move_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 不应该使用这个空间(这就是为什么下面的fork
和pause
是内联函数的原因),因为当 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:结论:
p0's user stack = p1's user stack right after fork
. p0 的用户堆栈 = 在
fork
之后 p1 的用户堆栈。
p0 does not use its user stack. p0 不使用其用户堆栈。
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.