--- title: Kernel, Process creation date: 2023-11-26T07:44:51.449Z slug: kernel-process-creation description: "Linux Kernel #3" --- ```c static int init(void * unused) { lock_kernel(); do_basic_setup(); /* * Ok, we have completed the initial bootup, and * we're essentially up and running. Get rid of the * initmem segments and start the user-mode stuff.. */ free_initmem(); unlock_kernel(); if (open("/dev/console", O_RDWR, 0) < 0) printk("Warning: unable to open an initial console.\n"); (void) dup(0); (void) dup(0); /* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */ if (execute_command) execve(execute_command,argv_init,envp_init); execve("/sbin/init",argv_init,envp_init); execve("/etc/init",argv_init,envp_init); execve("/bin/init",argv_init,envp_init); execve("/bin/sh",argv_init,envp_init); panic("No init found. Try passing init= option to kernel."); } ``` In this `init/main.c`, after basic kernel initialization things, `open("/dev/console")` and two `dup(0)` opens three file descriptor 0, 1, 2 as stdin, stdout, stderr. Later when `execve()` or `fork()` happens, it simply copies calling process's `task_struct` as process context, so all file descriptors are also passed down as-is. All processes' file descriptor 0, 1, 2 originates to `init`'s file descriptor. If calling process opens PTY or TTY, which is common when we opens new terminal to run a process, it is also passed down to exec/forked process.