The code runs in the Start_kernel function at the end of the Rest_init () function
1:rest_init () function analysis
(1) Call Kernel_thread function in Rest_init to start 2 kernel threads, respectively: Kernel_init and Kthreadd
(2) Call the Schedule function to open the kernel of the dispatch system, from the Linux system began to spin up.
(3) Rest_init finally calls the Cpu_idle function to end the entire kernel startup. This means that the Linux kernel eventually ends up with a function cpu_idle. This function must be a dead loop.
(4) To put it simply, the Linux kernel's final state is: when something is done to perform meaningful work (performing individual process tasks), the cycle of dying is really not working (actually a dead loop can also be considered a task).
(5) The kernel scheduling system has been started before, the dispatch system will be responsible for evaluating all the processes in the system, which only need to be run, the dispatch system will terminate the Cpu_idle dead loop process (idle process) to perform a meaningful work process. So the operating system will turn up.
2.1: What is a kernel thread
(1) Processes and threads. Simply to understand that a running program is a process. So the process is the task, the process is a separate program.
Independence means that the program is separate from other programs, and the program can be executed or paused by the kernel alone.
(2) in a Linux system, threads and processes are very similar and can be seen as almost identical. In fact, the concept of the process and thread we are currently lecturing on IS
The same.
(3) The process/thread is a separate program. The application layer runs a program that forms a user process/thread, then the kernel runs
A function (a function is actually a program) makes up a kernel process/thread.
(4) so we kernel_thead function to run a function, in fact, it turns this function into a kernel thread to run, and then he can be dispatched by the kernel dispatch system. Plainly is to go to the dispatcher register a bit, in the future when people dispatch will consider you.
2.2: Process 0, Process 1, Process 2
(1) The operating system uses a number to represent/record a process/thread, and this number is called the process number of the process. This number is assigned starting from 0. So the three processes involved in this process are the processes of Linux system 0, Process 1, and process 2, respectively.
(2) Under the Linux command line, use the PS command to view the processes running on the current Linux system.
(4) We can see all the processes that are running in the current system under Ubuntu Ps-aux, and we can tell that the process number starts from 1. Why not start with 0 because process 0 is not a user process but belongs to the kernel process.
Process 0: Process 0 is actually the idle process that was just talked about, called a free process, that is, a dead loop.
The process 1:kernel_init function is process 1, a process known as the init process.
The process 2:kthreadd function is process 2, which is the daemon of the Linux kernel. Its role is to manage the scheduling of other kernel processes this process is used to ensure that the Linux kernel itself can work properly.
3:init Process Analysis
One thing to be aware of is that the process has just started to run as a kernel state, which is a kernel process, and then it runs a user too under the program to force itself into a user state, because the INIT process itself completes the transition from the kernel state to the user state, so the subsequent processes can work under the user state
What does the 3.1:init process do in the kernel state?
The important point is to mount the root filesystem and try to find the INIT program under the user's condition, because the INIT process has to run a user-state application from the kernel state to the user state, and the kernel source code program is in the kernel state, so this application must not belong to the kernel source code, This will ensure that you are user-state, so this application is provided by another file, the root filesystem
What the 3.2:init process does in the user state
Most of the significant work in the INIT process is done in the user state, because all processes in the user state are generated directly or indirectly by the INIT process.
3.3: How to jump from kernel state to user state? Can you come back?
When the init process is under the kernel state, the application that calls the KERNEL_EXECVE function to execute a user-space-compiled link jumps to the user-State, noting that the process number of the jump does not change or process 1, and that the jump is one-way, From the user state back to the kernel after the path of the API only go
The KERNEL_EXECVE function is called by the path Start_kernel->rest_init->kernel_thread->kernel_init->init_post->run_init_ Process->kernel_execve
4:init process Analysis in kernel state (i.e. Kernel_init function)
4.1: Open the console with the following code:
/* Open The/dev/console on the Rootfs, this should never fail */if (Sys_open ((const char __user *) "/dev/console", O_rdwr , 0) < 0) PRINTK (kern_warning "warning:unable to open an initial console.\n");(void) sys_dup (0);(void) sys_dup (0);
(1) Each process in a Linux system has its own file descriptor table, which stores the files opened by this process.
(2) The Linux system has a design concept: all sessions are documents. So the device is also accessed in a file way. To access a device, we have to open the corresponding file descriptor for this device. For example/dev/fb0 This device file represents an LCD display device,/dev/buzzer represents a buzzer device, and/dev/console represents a console device. Open a device's file will get the device's file descriptor (or the file descriptor number), this number represents the device, and later operation of the device will use this file descriptor to manipulate it
(3) Here we open the/dev/console file, and copy the file descriptor 2 times, a total of 3 file descriptors. These three file descriptors are 0, 1, 2, respectively. These three file descriptors are called: standard input, standard output, standard error.
(4) Process 1 opens three standard output error files, so all processes derived from the subsequent process 1 have these 3 three-piece descriptors by default
4.2: Mount the root file system, the code is as follows
if (sys_access (const char __user *) Ramdisk_execute_command, 0)! = 0) {Ramdisk_execute_command = Null;prepare_namespace ( );}
(1) Mount the root file system in the Prepare_namespace function
(2) Where is the root file system? What is the file system type of the root file system? The uboot tells the kernel this information by passing the arguments. The Root=/dev/mmcblk0p2 RW in the uboot is to tell the kernel where the root filesystem is uboot the rootfstype=ext3 of the argument is to tell the kernel the type of rootfs.
(3) If the kernel mounts the root file system successfully, it will print: vfs:mounted root (ext3 filesystem) on device 179:2. If mounting the root file system fails, it will print: No filesystem could mount Roo T, TRIED:YAFFS2
(4) If Mount Rootfs fails when the kernel is booting, it must not be executed later. The kernel is set to start the failure of the break 5s automatic restart mechanism, so this will be automatically restarted, so sometimes you will see a repeated restart.
(5) If the Mount Rootfs fails, there are possible reasons: the most common error is that the Uboot Bootargs settings are incorrect. Rootfs Burn failure (fastboot burning is not prone to error, the previous manual burning is prone to error) Rootfs itself failed to make. (especially the rootfs you do, or the first time someone else gives it)
5: Execute Process 1 program under User state
(1) Once Mount Rootfs is successful, enter ROOTFS to find the application's init program,
This program is the process of user space 1. Find and use run_init_process (the KERNEL_EXECVE function inside) to execute him.
(2) If we determine who the INIT program is? The method is: first from the Uboot cmdline see if there is no specified, if there is a specified first execute the program specified in CmdLine. The INIT=/LINUXRC in CmdLine is the one that specifies which program in ROOTFS is the INIT program. The designation here means that we have a program named LINUXRC under the root directory of our rootfs, which is the INIT program. If there is no init=xx in the Uboot cmdline or the xx specified in the cmdline fails, there is a fallback scheme.
First standby:/sbin/init, second standby:/etc/init, third standby:/bin/init, fourth standby:/bin/sh.
If none of the above is successful, the kernel start fails
Linux kernel porting (vii)--REST_INIT function analysis