/** Linux/kernel/fork. C * // -- fork () is used to create a sub-process * (c) 1991 Linus Torvalds * // ** 'fork. c 'ins ins the help-routines for the 'fork' system call * (see also system_call.s), and some MISC functions ('verify _ Region '). * fork is rather simple, once you get the hang of it, but the memory * management can be a bitch. see 'Mm/mm. c': 'Copy _ page_tables () '*/# include <errno. h> # include <Linux/sched. h> # include <Lin UX/kernel. h> # include <ASM/segment. h> # include <ASM/system. h> // -- write page verification. If the page cannot be written, copy the extern void write_verify (unsigned Long Address); long last_pid = 0; // -- void verify_area (void * ADDR, int size) {unsigned long start; Start = (unsigned long) ADDR; size + = Start & 0 xfff; Start & = 0xfffff000; Start + = get_base (current-> LDT [2]); // -- Logical Address to linear address conversion while (size> 0) {size-= 4096; write_verify (start ); Start + = 4096 ;}} int copy_mem (int nr, struct task_struct * P) // -- copy the memory page table {// -- because of the write-time replication technology, here, only directory and page table items are copied, and the memory unsigned long old_data_base, new_data_base, data_limit; unsigned long old_code_base, new_code_base, code_limit; code_limit = get_limit (0x0f ); // -- get the segment length: data_limit = get_limit (0x17); old_code_base = get_base (current-> LDT [1]); old_data_base = get_base (current-> LDT [2]); If (old_data_base! = Old_code_base) panic ("we don't support separate I & D"); If (data_limit <code_limit) panic ("Bad data_limit"); new_data_base = new_code_base = nR * task_size; p-> start_code = new_code_base; set_base (p-> LDT [1], new_code_base); set_base (p-> LDT [2], new_data_base); If (copy_page_tables (old_data_base, new_data_base, data_limit) {// -- copy the page table free_page_tables (new_data_base, data_limit); Return-enomem;} return 0;}/** OK, this is the main fork-routine. it copies the system process * Information (task [Nr]) and sets up the necessary registers. it * Also copies the data segment in it's entirety. * // -- fork () subprogram, which copies system process information, sets registers, and copies data segments (code segments) int copy_process (int nr, long EBP, long EDI, long ESI, long Gs, long none, long EBX, long ECx, long edX, long orig_eax, long FS, long es, long ds, long EIP, long CS, long eflags, lon G ESP, long SS) // -- Copy process {struct task_struct * P; int I; struct file * F; P = (struct task_struct *) get_free_page (); // -- allocate the memory if (! P) Return-eagain; task [Nr] = P; * P = * Current;/* Note! This doesn't copy the supervisor stack */p-> state = task_uninterruptible; P-> pid = last_pid; P-> counter = p-> priority; p-> signal = 0; P-> alarm = 0; P-> leader = 0; /* process leadership doesn' t inherit */p-> utime = p-> stime = 0; P-> cutime = p-> cstime = 0; p-> start_time = jiffies; P-> TSS. back_link = 0; P-> TSS. esp0 = page_size + (long) P; P-> TSS. ss0 = 0x10; P-> TSS. EIP = EIP; P-> TSS. eflags = eflags; P-> TSS. eax = 0; P-> TSS. ECX = ECx; P-> TSS. edX = edX; P-> TSS. EBX = EBX; P-> TSS. ESP = ESP; P-> TSS. EBP = EBP; P-> TSS. ESI = ESI; P-> TSS. EDI = EDI; P-> TSS. es = ES & 0 xFFFF; P-> TSS. cs = cs & 0 xFFFF; P-> TSS. ss = SS & 0 xFFFF; P-> TSS. DS = DS & 0 xFFFF; P-> TSS. FS = FS & 0 xFFFF; P-> TSS. GS = GS & 0 xFFFF; P-> TSS. LDT = _ LDT (NR); P-> TSS. trace_bitmap = 0x80000000; If (last_task_used_math = Current) _ ASM _ ("clts; Fnsave % 0; frstor % 0 ":" M "(p-> TSS. i387); If (copy_mem (NR, p) {task [Nr] = NULL; free_page (long) P); Return-eagain;} for (I = 0; I <nr_open; I ++) // -- if a file in the parent process is opened, increase the number of times the corresponding file is opened by 1 If (F = p-> filp [I]) F-> f_count ++; If (current-> pwd) current-> pwd-> I _count ++; If (current-> root) Current-> root-> I _count ++; If (current-> executable) current-> executable-> I _count ++; If (current-> Library) Current-> library-> I _ Count ++; set_tss_desc (gdt + (NR <1) + first_tss_entry, & (p-> TSS )); // -- set tss and LDT set_ldt_desc (gdt + (NR <1) + first_ldt_entry, & (p-> LDT) of the new task in the gdt table )); p-> p_pptr = current; P-> p_cptr = 0; P-> p_ysptr = 0; P-> p_osptr = Current-> p_cptr; If (p-> p_osptr) p-> p_osptr-> p_ysptr = P; Current-> p_cptr = P; P-> state = task_running;/* do this last, just in case */return last_pid ;} int find_empty_process (void) // -- unique for the new process Process No. last_pid {int I; repeat: If (++ last_pid) <0) last_pid = 1; for (I = 0; I <nr_tasks; I ++) if (task [I] & (task [I]-> pid = last_pid) | (task [I]-> pgrp = last_pid) goto repeat; for (I = 1; I <nr_tasks; I ++) if (! Task [I]) return I; Return-eagain;} | xgv00 | fcc8d4de8197f69fde70263fb4d52380
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.