Я сейчас изучаю 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's tss->ss
и tss->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;
...
}
Стек ядра PS p0 находится ниже LOW_MEMORY, что означает, что он не поддерживает COW.