Core Data Structure initialization-kernel boot Part 1
Start_kernel () calls a series of initialization functions to complete the kernel settings.
Some of these actions are public, and others are executed only after configuration.
In the start_kernel () function,
- Output Linux version information (printk (linux_banner ))
- Set the architecture-related environment (setup_arch ())
- Page table structure initialization (paging_init ())
- Use the entry point in "arch/alpha/kernel/entry. s" to set the system self-trapping entry (trap_init ())
- Use the alpha_mv structure and entry. s entry to initialize the system IRQ (init_irq ())
- Initialize the core process scheduler (including initializing several default bottom-half and sched_init ())
- Time, Timer initialization (including reading CMOS clock, estimated clock speed, initialization timer interruption, etc., time_init ())
- Extract and analyze the core startup parameters (read the parameters from the environment variables, set the corresponding flag to wait for processing, (parse_options ())
- Console initialization (initialize before PCI for output information, console_init ())
- Profile data structure initialization (prof_buffer and prof_len variables)
- Core cache initialization (Cache describing Cache Information, kmem_cache_init ())
- Delay calibration (get the delay between the clock jiffies and CPU clock speed ticks, calibrate_delay ())
- Memory initialization (set the initial values of memory upstream and downstream and page table items, mem_init ())
- Create and set internal and general cache ("slab_cache", kmem_cache_sizes_init ())
- Create uid taskcount Slab
Cache ("uid_cache", uidcache_init ())
- Create a File Cache ("files_cache", filescache_init ())
- Create directory cache ("dentry_cache", dcache_init ())
- Create a cache related to the VM ("vm_area_struct", "mm_struct", vma_init ())
- Block device read/write buffer initialization ("buffer_head" cache user accelerated access, buffer_init ())
- Create page cache (Memory Page hash table initialization, page_cache_init ())
- Create a signal queue cache ("signal_queue", signals_init ())
- Initialize memory inode table (inode_init ())
- Create a memory file descriptor table ("filp_cache", file_table_init ())
- Check the architecture Vulnerability (for Alpha, this function is empty, check_bugs ())
- Initialize the remaining CPU of the SMP machine (except the current Boot CPU) (this function is null for kernels without SMP configuration, smp_init ())
- Start the INIT process (create the first core thread and call the init () function. The original execution sequence calls cpu_idle ()
Waiting for scheduling, INIT ())
So far start_kernel () has ended, and the basic core environment has been established.
For i386 platforms
The kernel Startup Process on the i386 platform is basically the same, and the main difference is the implementation method.
For the 2.4.x Kernel
In 2.4.x, the changes are large, but the basic process remains unchanged. The changes are specific implementations of various data structures, such as cache.
Peripheral initialization-kernel boot Part 2
As the core thread, the init () function first locks the kernel (only valid for SMP machines) and then calls
Do_basic_setup () to load and initialize peripherals and their drivers. The process is as follows:
- Initialize the bus (such as pci_init ())
- Network initialization (initialize the network data structure, including sk_init (), skb_init (), and proto_init (). In proto_init, will call the initialization process of all protocols contained in the protocols structure, sock_init ())
- The bdflush Core Thread (bdflush () process is resident in the core space, and the core wakes up to clean up the written memory buffer. When bdflush () is started by kernel_thread, it named itself kflushd)
- The kupdate Core Thread (kupdate () process is resident in the core space and scheduled and executed by the core on time. The information in the memory buffer is updated to the disk. The updated content includes the super block and inode table)
- Set and start the core paging thread kswapd (to prevent kswapd from outputting version information to other information at startup, the core line calls kswapd_setup () to set the environment required for running kswapd, and then create
Kswapd Core Thread)
- Create the Event Management Core Thread (start_context_thread () function to start the context_thread () process and rename it to keventd)
- Device initialization (including parallel port parport_init (), character device chr_dev_init (), block Device
Blk_dev_init (), SCSI device scsi_dev_init (), network device net_dev_init (), disk initialization and partition check, etc. device_setup ())
- Set the execution file format (binfmt_setup ())
- Start any function identified by _ initcall (to facilitate core developers to add the startup function, do_initcballs ())
- File system initialization (filesystem_setup ())
- Install the root file system (mount_root ())
Now the do_basic_setup () function returns Init (). After the startup memory segment (free_initmem () is released and the kernel is unlocked, INIT () is enabled.
/Dev/console device, redirects stdin, stdout, and stderr to the console, and finally searches for the INIT program in the file system (or by init = command line parameter)
And execve () System Call to load and execute the INIT program.
The init () function ends at this point, and the kernel boot part ends at this point. The first thread created by start_kernel () has become a process in user mode. At this time, there are six running entities in the system:
- Start_kernel () itself is located in the execution body, which is actually a "manually" created thread. It enters the cpu_idle () loop after the init () thread is created, it does not appear in the process (thread) List
- Init thread, created by start_kernel (). It is in the user State and the INIT program is loaded.
- Kflushd Core Thread, which is created by the init thread and runs the bdflush () function in the core state.
- Kupdate Core Thread, which is created by the init thread and runs the kupdate () function in the core state.
- Kswapd Core Thread, created by the init thread, runs the kswapd () function in the core State
- The Core Thread of keventd, which is created by the init thread and runs the context_thread () function in the core state.
For i386 platforms
Basically the same.
For the 2.4.x Kernel
This part of the startup process simplifies a lot in the 2.4.x kernel, and the default independent initialization process only leaves the network
(Sock_init () and create the Core Thread of event management. Other initialization tasks require the _ initcall () Macro.
Include in the do_initcils () function to start execution.
INIT process and inittab boot command
The INIT process is the starting point of all processes in the system. After the kernel is started, it is null in this thread (process ).
The INIT program is loaded, and its Process number is 1.
The INIT program needs to read the/etc/inittab file as its behavior pointer. inittab is a descriptive (non-executive) Text of the behavior unit. Each Command Line has the following format:
ID: runlevel: Action: process where ID is the entry identifier, runlevel is the running level, action is the action code, and process is the specific execution program.
Generally, the ID must be within four characters. For Getty or other login program items, the ID must be the same as the TTY number. Otherwise, the Getty program will not work properly.
Runlevel is the identifier of the running level of init. It is generally 0-6 and S or S. The running levels 0, 1, and 6 are retained by the system, 0 is used as the shutdown action, and 1 is used as the restart
In single-user mode, 6 indicates restart. S and S indicate single-user mode, and the inittab file is not required. Therefore, it is not displayed in inittab. In fact, when you enter single-user mode,
Init runs/sbin/sulogin directly on the console (/dev/console.
In general system implementation, 2, 3, 4, and 5 are used. In the RedHat system, 2 indicates that the multi-user mode is not supported by NFS, 3 indicates full multi-user mode (also the most commonly used level)
Otherwise, 4 is reserved for user-defined, and 5 indicates the xdm graphical logon mode. The 7-9 level can also be used. Traditional UNIX systems do not define these levels. Runlevel can be parallel.
Multiple values to match multiple running levels. For most actions, it is executed only when the runlevel matches the current running level.
Initdefault is a special action value used to identify the default startup level. When init is activated by the core
Later, it reads the initdefault item in the inittab, obtains the runlevel, and serves as the current running level.
No. If there is no inittab file or there is no initdefault item, init will request the input in the console
Runlevel.
Actions such as sysinit, boot, and bootwait will run unconditionally at system startup, while ignoring runlevel. Other actions (excluding initdefault) are related to a certain runlevel. The definitions of each action are described in detail in the man manual of inittab.
In the RedHat system, inittab generally has the following items:
ID: 3: initdefault: # Indicates that the current default running level is 3-full multi-task mode; Si: sysinit:/etc/rc. d/rc. sysinit # Automatically execute the/etc/rc. d/rc. sysinit script at startup L3: 3: Wait:/etc/rc. d/RC 3 # When the runtime level is 3, run the/etc/rc. d/RC Script with the parameter 3. init will wait for its return 0: 12345: respawn:/sbin/mingetty tty0 # Run the/sbin/mingetty program with tty0 as the parameter at each level from 1 to 5. Open the tty0 terminal # Log On As a user. If the process exits, run the mingetty program again. X: 5: respawn:/usr/bin/X11/xdm-nodaemon # Run The xdm program at level 5, provide the xdm graphical login interface, and re-execute it upon exit
|
RC Startup Script
As mentioned in the previous section, the INIT process starts to run the RC Script. This section describes the specific work of the RC Script.
Normally, the rc startup script is located in the/etc/rc. d directory. The most common action in RC. sysinit is to activate swap partitions, check disks, and load hardware modules.
The running level must be prioritized. Only after RC. sysinit is executed will init execute other boot or bootwait actions.
If there are no other boot or bootwait actions,/etc/rc. d/RC will be executed at runtime Level 3, and the command line parameter is 3
All files in the/etc/rc. d/rc3.d/directory. Files under rc3.d are symbolic connections to various shell scripts under the/etc/rc. d/init. d/directory.
These scripts generally accept parameters such as start, stop, restart, and status. The RC Script starts all scripts starting with s with the start parameter.
The corresponding script also has a K-header link and is in the running state (marked by a file under/var/lock/subsys ), start the script starting with K and start with stop
As a parameter, stop these started services and run them again. Obviously, the direct purpose of this is that when init changes the running level, all related services will be restarted, even at the same level.
After the RC program is executed, the system environment has been set up. Now the user is logged on to the system.
Getty and login
After the RC returns, init gets control and starts mingetty (see section 5 ). Mingetty is the simplification of Getty and cannot process serial port operations. The getty functions include:
- Open the terminal line and set the Mode
- Output the logon interface and prompt to accept user name input.
- Use this username as the login parameter to load the login program
Note: the prompt message for remote logon is located in/etc/issue.net.
The login program runs in the same process space of Getty and accepts the username parameter sent from Getty as the login
User name.
If the user name is not root and the/etc/nologin file exists, login will output the content of the nologin file,
Then exit. This is usually used to prevent non-Root User Logon during system maintenance.
Only terminals registered in/etc/securetty allow the root user to log on. If this file does not exist,
Then, the root user can log on to any terminal. The/etc/usertty file is used to restrict access to users. If
If this file does not exist, there are no other restrictions.
After the user logs in and passes these checks, login searches for the/etc/passwd file (if necessary ).
/Etc/shadow file) is used to match the password, set the main directory, and load the shell. If no home directory is specified, Set
The default value is the root directory. If no shell is specified, the default value is/bin/sh. Before transferring control to shell,
Getty will output the information of the Last Logon system recorded in/var/log/lastlog, and then check whether the user has a new
Email (/usr/spool/mail/{username }). Set the shell uid, GID, and term, path
After the environment variables, the process loads the shell and the login task is completed.
Bash
After login is run under Level 3, a user-specified shell will be started. The following uses/bin/Bash as an example to continue the startup process.
Bash is Bourne
The GNU extension of shell not only inherits all the features of SH, but also adds many features
Features. Bash started by login is started as a logon shell. It inherits the environment variables such as the term and path set by Getty, where path is "/bin: /usr/bin:/usr/local/bin ", for root
"/Sbin:/bin:/usr/sbin:/usr/bin ". As a login shell, it will first look for/etc/profile
Script file, and execute it; then if ~ /. Bash_profile, execute it; otherwise, execute
~ /. Bash_login. If the file does not exist, execute ~ /. Profile file. Then Bash will act as
Interactive Shell execution ~ /. Bashrc file (if any), in many systems ,~ /. Bashrc will be started
/Etc/bashrc is used as the configuration file within the system.
When a command line prompt is displayed, the entire startup process ends. At this time, the system runs the kernel,
Several core threads are running, the INIT process is running, and a batch of daemon processes activated by the rc startup script (such
(Inetd), and runs Bash as the user's command interpreter.