Linux 시스템에서 새 프로세스 생성(하)
도 봐봐.fork /linux-3.18.6/kernel/fork.c#do_fork
1651 p = copy_process(clone_flags, stack_start, stack_size, //
1652 child_tidptr, NULL, trace);
코피 한번...process /linux-3.18.6/kernel/fork.c#copy_process
1240 p = dup_task_struct(current); // PCB
dup 한번 봅시다.task_struct /linux-3.18.6/kernel/fork.c#dup_task_struct
320 err = arch_dup_task_struct(tsk, orig); // ,orig
316 ti = alloc_thread_info_node(tsk, node); // alloc
324 tsk->stack = ti; // alloc stack
archdup_task_struct /linux-3.18.6/kernel/fork.c#arch_dup_task_struct
290int __weak arch_dup_task_struct(struct task_struct *dst,
291 struct task_struct *src)
292{
293 *dst = *src; // *, , *,
294 return 0;
295}
alloc 보세요.thread_info_node /linux-3.18.6/kernel/fork.c#alloc_thread_info_node
150static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,
151 int node)
152{
153 struct page *page = alloc_kmem_pages_node(node, THREADINFO_GFP,
154 THREAD_SIZE_ORDER);
155
156 return page ? page_address(page) : NULL;
157}
실제 내부 핵 창고 공간을 분배하는 효과를 냈는데, 실제 코드는allockmem_pages_de, 일정한 크기의 페이지를 만들었습니다. 페이지의 일부분은thread 를 저장하는 데 사용됩니다.info, 다른 부분은 높은 주소에서 낮은 주소로 핵 창고입니다
dup으로 돌아가기task_struct, 현재 부모 프로세스의 PCB, 즉task 를struct 데이터 구조가 복사되었습니다. 즉 p가 가리키는 하위 프로세스의 PCB (프로세스 설명자)
1240 p = dup_task_struct(current); // PCB
이후의 코드는 서브프로세스 내용을 대량으로 수정한 코드가 있는데, 초기화하면 이것들은 모두 추상화할 수 있다
1375 retval = copy_files(clone_flags, p);
1378 retval = copy_fs(clone_flags, p); //
1381 retval = copy_sighand(clone_flags, p);
1384 retval = copy_signal(clone_flags, p); //
1387 retval = copy_mm(clone_flags, p); //
1390 retval = copy_namespaces(clone_flags, p);
1393 retval = copy_io(clone_flags, p); // IO
1396 retval = copy_thread(clone_flags, stack_start, stack_size, p); //
코피 한번...thread /linux-3.18.6/arch/x86/kernel/process_32.c#132
135 struct pt_regs *childregs = task_pt_regs(p);
여기에서 볼 수 있듯이 하위 프로세스의pid, 즉 내부 창고의 위치에서 창고 공간을 찾았습니다.SAVEALL의 일부 내용, SAVEAll 주소
139 p->thread.sp = (unsigned long) childregs; //
창고의 밑천을 물다
커널 스택 데이터 복사 및 새 프로세스의 첫 번째 명령 주소 지정
159 *childregs = *current_pt_regs(); //
현재 프로세스, 즉 아버지 프로세스입니다. 왜냐하면 이 실행 프로세스는 아버지 프로세스의 실행 상하문에 있기 때문입니다.상위 프로세스의 커널 스택, 즉 SAVEAll의 내용을 복사해 오너라. 이곳은 실제적으로 내부 핵 창고에 이미 있는 데이터를 복사하는 것이다
주의해야 할 점: 코어 스택을 복제할 때 SAVE와만 복제됨ALL과 관련된 부분은 struct pt 만 복사됩니다.regs
한번 struct ptregs 데이터 구조의 내용/linux-3.18.6/arch/x86/include/asm/ptrace.h
9#ifdef __i386__
10
11struct pt_regs {
// SAVE_ALL
12 unsigned long bx;
13 unsigned long cx;
14 unsigned long dx;
15 unsigned long si;
16 unsigned long di;
17 unsigned long bp;
18 unsigned long ax; //
19 unsigned long ds;
20 unsigned long es;
21 unsigned long fs;
22 unsigned long gs;
23 unsigned long orig_ax; // eax
// int 0x80 ,CPU
24 unsigned long ip;
25 unsigned long cs;
26 unsigned long flags;
27 unsigned long sp;
28 unsigned long ss;
29};
30
31#else /* __i386__ */
내부 핵 창고를 복제할 때 i386은 내부 핵 창고의 가장 창고 밑의 일부분만 복제했다. 즉, 시스템이 창고를 압축하는 과정, int 0x80 명령어(CPU 자동)와 SAVEAll이 커널 스택에 깔린 내용
160 childregs->ax = 0; // fork 0, !
되돌아오는 값은 eax에 저장되고 pid=0은 이 값에 저장됩니다.하위 프로세스의 반환 값이 0이기 때문에 복사가 끝나면 내장 창고에 눌린 반환 값을 수정해야 합니다
161 if (sp)
162 childregs->sp = sp; // sp copy_thread stack_start
스택 베이스 데이터 포함
164 p->thread.ip = (unsigned long) ret_from_fork; //
할당 thread.ip의 내용은retfrom_fork, 하위 프로세스가 프로세스 스케줄링을 받고 CPU를 받을 때 이 위치에서 실행됩니다
엔리 봐봐요.32.S /linux-3.18.6/arch/x86/kernel/entry_32.S
시스템 호출 총 제어 프로그램,ret 찾기from_fork
290ENTRY(ret_from_fork)
291 CFI_STARTPROC
292 pushl_cfi %eax
293 call schedule_tail
294 GET_THREAD_INFO(%ebp)
295 popl_cfi %eax
296 pushl_cfi $0x0202 # Reset kernel eflags
297 popfl_cfi
298 jmp syscall_exit // syscall_exit
299 CFI_ENDPROC
300END(ret_from_fork)
syscall_exit는 어디에 있습니까?
490ENTRY(system_call)
493 pushl_cfi %eax # save orig_eax
494 SAVE_ALL // SAVE_ALL
501syscall_call: // system_call
502 call *sys_call_table(,%eax,4)
503syscall_after_call: // call ,
// ,
504 movl %eax,PT_EAX(%esp) # store the return value
505syscall_exit:
call 되돌아오기, 내부 창고로 되돌아오기, 즉 내부 창고가 어떻게 창고에 쌓이면 어떻게 나오는지,syscallexit 때, 실제로sys콜하기 전에 얘가 쌓인 상태가 똑같아요.
그래서retfrom_forksyscall 로 건너뛰기exit 오면 계속 아래로 실행할 수 있고 사용자 상태로 정상적으로 되돌아갈 수 있습니다
즉, 하위 프로세스가 CPU 제어권을 얻고 실행을 시작할 때 그의retfrom_kk는 뒤에 있는 창고를 창고에서 내보낼 수 있습니다.iret에서 사용자 상태로 되돌려줍니다. 이때 사용자 상태로 되돌려줍니다. 원래 아버지 프로세스의 프로세스 공간이 아니라 하위 프로세스의 프로세스 공간입니다.
(다음 편 끝)
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.