Linux Initialization and Startup Process
We only need to click the application icon to run the program, but before that, we must start our system. Before everything is done, we must have some programs to guide the kernel of our system. These programs are kernel Boot programs, such as LILO, GRUB, U-Boot, and RedBoot. These guiding programs also need to be loaded and run by other programs. In this case, where is the end of life? You can think of hardware! This long process is complex and rugged! Everything is difficult at the beginning, but we are not afraid. Let's go over together!
X86 Boot Process
Initialization of the cpu itself: This is the first step of guidance. If you are on a multi-processor system, each cpu must be initialized by itself. After cpu initialization, the cpu is directed from a fixed position (should be 0Xfffffff0). This command is a jump command, and the destination is the first BIOS code, but the cpu does not care whether the BIOS exists, it is just a command to execute this address!
BIOS: the BIOS is read-only memory (ROM) and is solidified on the motherboard. There are two main jobs: power-on self-check: POST on self test and kernel boot program loading.
So what exactly do they do?
1) power-on self-check: completes system hardware detection, including memory detection and system bus detection.
2) load the kernel boot program: After the POST is complete, the kernel boot program will be loaded. Where will it be stored? Disk! Haha, the BIOS will read 512 bytes of a single sector with a 0 head and a 0 track. This sector is called MBR (Master Boot Record), and the MBR stores the starting part of the kernel boot program, the BIOS loads it into the memory for execution. What about the MBR with 512 bytes? It is necessary to talk about MBR here! The MBR Partition Table starts with 80 and ends with 55AA, with a total of 64 bytes. Specific MBR knowledge Baidu!
MBR: 1) 446 bytes of Bootstrap code
2) How many partitions are there in a 64-byte partition table ..? I really don't know! It can be divided into four partition tables, one start partition and three non-start partitions.
3) 2 bytes 0XAA55, used to check whether the MBR is valid.
Note that after the kernel boot program is loaded, the POST part of the code will be cleared from the memory, leaving only some of the Code in the memory for use by the target operating system.
Kernel boot program: the kernel boot program consists of the main and secondary boot programs. The main task of the main Bootstrap program is to collect data, search for active partitions, and load and execute the secondary Bootstrap program in the active partition Bootstrap record. This boot program is responsible for loading the kernel and giving control to the kernel. The kernel Boot programs mentioned above include LILO, GRUB, U-Boot, and RedBoot. The first two are in the pc, and the last two are embedded.
Kernel: the kernel exists in the form of compression, not an executable kernel! Therefore, the first thing to do in the kernel stage is to decompress the kernel image. Here we will talk about the kernel-compressed image vmlinuz formed after the kernel is compiled. After vmlinux is compiled and generated, it is usually compressed to vmlinuz to make it a small kernel of zImage -- smaller than kb, or a large kernel of bzImage -- greater than kb.
Vmlinuz Structure
After so much work, I finally guided the linux kernel .!! Next, we will initialize the Linux kernel!
Kernel initialization: the kernel calls a series of initialization functions to initialize all kernel components ()---..... ---> rest_init ()----.. ----> kernel_init ()----.... --> init_post () ------ To ---> the init process of the first user ends.
Start_kernel (): It initializes most of the kernel. Check the source code of the kernel! Www.kernel.org
Rest_init (): start_kernel () calls rest_init () for subsequent initialization.
Kernel_init (): This function initializes the device driver and calls init_post () to start the init process of the user space.
Init_post (): at the end of initialization, The init of the first user space is blank! Its PID is always 1.
Init: the kernel will look for it in a few places that used init in the past. The correct location (for Linux systems) is/sbin/init. If the kernel cannot find init, it will try to run/bin/sh. If the run fails, the system will also fail to start. After finding/sbin/init, init will follow the/etc/inittab statement. I cannot find it in Ubuntu3.8 kernel, but it can be found in Fedora! Is the release version different? (Please advise) Here is an attachment !) File to complete other work, for example, the getty process accepts user logon and sets the network. Let's talk about it in detail here.
The etc of fedora19 has the inittab file:
All processes in the system form a tree structure, and the root of the tree is formed in the kernel state. The system automatically constructs the 0 process, which is the ancestor of all processes. Generally, in the vmlinux entry startup_32 (head. S), the execution environment is set for the original process with pid 0, and then the process starts to execute start_kernel () to initialize the Linux kernel. Including page table initialization, interrupt vector table initialization, and system time initialization. Then call fork () to create the kernel init process:
Kernel_thread (kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); // parameter CLONE_FS | CLONE_SIGHAND indicates that Thread 0 and thread 1 share the File System (CLONE_FS) and opened files (CLONE_FILES) respectively) and the signal processing program (CLONE_SIGHAND ).
This process is the famous init process with pid 1 (kernel state). It will continue to complete the remaining initialization work ratio and create several kernel threads for high-speed cache and virtual master memory management, for example, kswapd and bdflush, and execve (/sbin/init) (generate user State init process pid = 1, because fork () is not called, so pid is still 1 !), Become the ancestor of all other processes in the system. Let's look back at the process with pid = 0. After the init process is created (kernel state), the process with pid = 0 calls cpu_idle () and translates it into an idle process in the master cpu. The kernel-state pid = 1 init process will also generate an idel process on each cpu. Before init evolves to/sbin/init, it will execute some initialization work. One of them is smp_prepare_cpus (), which initializes the SMP processor. During this process, it will call each slave processor during processing.
Task = copy_process (CLONE_VM, 0, idle_regs (& regs), 0, NULL, NULL, 0); init_idle (task, cpu );
That is, a process is re-created from init and initialized as an idle process (pid is still 0 ). The idle process on the processor performs an Activate Operation and then runs cpu_idle ().
Run/sbin/init. In this way, starting from the kernel too much to the user State is completed according to the/etc/inittab configuration file, and several startup tasks are not numbered 1, 2, 3... the terminal registration process getty is used to set the ID of the Process Group and monitor the interface circuit configured to the system terminal. When a signal arrives, getty will execve () generate the login registration process. You can register and log on. If the logon succeeds, login is displayed as a shell process. If login fails, the opened terminal line is closed, process 1 creates a new getty. Now the init process is complete. Here is a big picture!
Init process:
The init process is finished. Here we will give a rough description of what init has done. First, let's get to know the running level.
Running level: linux can start different startup programs on different occasions, which is called the running level. Start different programs based on different running levels. For example, Apache must be enabled when used as a server, but not on the desktop.
In linux, seven running levels (0--6) are pre-configured ). There are 8 types of ubuntu (0--6 and S). Here we mainly use ubuntu. 0: disable the system. 1: The system enters the single-user mode. S: the single-user recovery mode and the text logon interface. Only a few system services are running. 2: multi-user mode (default system level), graphical logon interface, run all the predefined system services. 3-5: multi-user mode, graphical login interface, run all the predefined system services (for system customization, the operation level is 2-5), 6: restart the system.
For each running level, there is a corresponding sub-directory in/etc/---/etc/rcN. d to specify the program to be loaded.
After careful reading, we can find that all files except README are in the form of "S beginning + double digit + program name. What does this mean? S indicates Start. If it is K, kill is disabled. If it is switched from another running level, the program is closed. The subsequent numbers are in the processing order. The smaller the number, the earlier the execution. If the numbers are the same, start them in alphabetical order.
We can see that all the files here are linked files. Why? As mentioned above, each running level has its own directory used to store its own boot programs. If multiple running levels need to start the same program, the script of this program will be copied to every directory. In this case, if you want to modify the startup script, you need to modify every directory. This is unscientific !!!! Therefore, all these files are linked to/etc/init. d. These scripts are run at startup.
Subsystem initialization:
Kernel options: linux allows users to pass Kernel configuration options to the kernel. During the initialization process, the kernel calls the parse_args () function to parse these options, and then calls the corresponding functions for processing. For the parse_args () function, it can parse a string in the form of "variable name = value". When the module is loaded, it will also be called to parse the module parameters.
Subsystem initialization: After kernel options are parsed, initialize the function call. Call the do_basic_setup () function in the kernel_init () function and then call the do_initcballs () function. For specific implementation of each function, please refer to the source code!
Logon: There are three logon methods.
1) log on to the CLI
Init creates getty. After the user enters the user name and password, the system calls the login program to check the password. If the password is correct, the system reads the/etc/passwd file, read the specified shell of the user and start it.
2) ssh Logon
The system calls the sshd program, replaces getty and login, and then starts the shell.
3) Graphical Logon
The Display Manager for calling the init process. The Gnome graphic interface corresponds to the running of the running machine. Then, enter the user name and password. If the password is correct, start the user session.
The system starts up here! Now let's have some fun !!!!!! Get familiar with linux Startup !!!!!!!!!!! First, you need to prepare a ubuntu system, preferably 13.04 or 12.04, which can be a virtual machine (preferably on a virtual machine! I re-installed the real machine system for this small experiment! I didn't understand it at the time! Miserable .........).
1: Go to the system, create a c language file in the main folder (convenient) and name it init. c. Enter ----> the simplest c language program helloworld, not the greatest c language program!
Main (){
Printf ("helloworld! \ N ");
}
Compilation is not to mention later. Open the terminal (ctrl + alt + t) and execute this command: gcc -- static-o init. c. The init file is ready! Guess what I want to do ..? Haha, let's continue !!
2: run the following command to back up the/sbin/init file: sudo cp/sbin/init. bak to the init. bak file.
Delete the original init file and run the following command: sudo rm/sbin/init.
Now, we will copy our helloworld init to the/sbin/directory! Run the command: sudo mv init/sbin/. Before executing this command, make sure that the current path of your terminal is the same as that of init. Otherwise, the Operation will fail !!
3: This is done !!! Let's restart it! In this way, we can see our helloworld! Alas .. Where has it stopped !! That's for sure. The above section describes the functions of init. If you change it, it is normal to start it .. Think about the status of the kernel here .? In fact, the kernel Initialization is complete! The process generation and subsystem initialization are now available. At the end of the init_post () function, the init path is located. If no init path is found, the system crashes. In addition, an interactive shell (/bin/sh) will be created to replace the unfound init, so that users can fix such errors and restart.
4: Now let's restore our system! The steps in step 2 won't let you do it in white! Restart the system and press left Shift at the beginning. (I didn't need to use the previous system. I don't know what the previous bad thing happened to grub. cfg !!), The system will automatically detect this signal, so that the interface shown in the figure below will appear. (We recommend that you check the features of grub2 !) :
Press e and edit. Press the down button in the lower right corner of the keyboard and add ----> init =/sbin/init to the end of the linux line (quiet. bak, press ctrl + x to start the system. :
If everything is correct, you will be able to restart the system! If you see the logon interface, congratulations! You have already taken a long journey!
Now, the knowledge to be discussed in this article has been completed. Let's take a look at the unsolved problems I encountered here. Please kindly advise!
Problem: First of all, my experiment was made on a virtual machine. I thought init was related to the compressed file in the kernel, so I used 3.8.0-19 to go to the kernel and deleted the init, in this case, the 3.8.0-19 kernel cannot start the kernel. I used the 3.8.0-27 kernel to enter the system .. There is still a great helloworld! In this case, init has nothing to do with files in boot such as vmlinux! So where will init be stored after it is shut down !? And the most important thing! I re-installed the system (Virtual Machine). This does not have the 3.8.0-27 kernel, I put the Kernel File 3.8.0-27 of my real machine (vmlinuz file in/boot, etc.) into the/boot/folder of the virtual machine, restart the system, and find that the resolution has changed, the cursor is not flexible (it may be the relationship between resolutions !), The screen size is twice that of the original one. Why?
Ps: This article is quite long! If you have any questions, contact us and learn! If you know the cause of the above problem, please leave a few words for your study!
This article permanently updates the link address: