Linux Startup Process Overview
I.Bootloader
II.KernelGuide entry
Iii. Core Data Structure initialization-kernel boot Part 1
Iv. Peripheral initialization-kernel boot Part 2
V. INIT process and inittab boot command
Vi. RC Startup Script
7. Getty and login
8. Bash
Appendix: xdm Logon
This document uses RedHat 6.0Linux2.2.19 for alpha/AXP as the platform, which describesLinuxStart the entire process. This article also applies to the i386 platform.
I.Bootloader
Pilot on Alpha/AXP PlatformLinuxThere are usually two methods: one is guided by Milo and other similar boot programs, and the other is directly guided by firmware. Milo features are similar to lilo on the i386 platform, but has built-in basic disk drivers (such as IDE and SCSI) and common file system drivers (such as ext2 and iso9660 ), firmware has two forms: arc and SRM. ARC has a BIOS-like interface and even multiple boot settings. SRM has a powerful command line interface, you can use commands such as boot on the console to guide the system. ARC has the concept of partition, so it can access the first sector of the partition. SRM can only forward the control to the first sector of the disk. Both firmware can be guided by MiloLinuxCan also be directly guidedLinux.
Under "arch/alpha/Boot ",Linux Bootloader. "Head. the S file provides the call entry to osf pal/1. It will be compiled and placed in the pilot sector (the first sector of the arc partition or the disk 0 sector of the SRM ), after obtaining the control, initialize some data structures and transfer the control to "Main. start_kernel () and start_kernel () in C "output some prompts to the console, call pal_init () to initialize the pal code, and call openboot () to open the boot device (by reading the firmware environment ), call load () to load the core code to start_addr (see "include/ASM-alpha/system. h), load the core boot parameters in firmware to zero_page (0), and call runkernel () to transfer the control to the kernel of 0x100000. the bootloader part ends.
"Arch/alpha/boot/Bootp. C" is based on "Main. c". It can be used instead of "Main. c" and "head. S" to generateBootloader.
BootloaderAll the "SRM _" functions used in are defined in "arch/alpha/lib.
The above boot method is the simplest way, that is, it can be guided without other tools.KernelThe premise is to generate the bootimage file according to the makefile instructions, including the Bootloader and vmlinux mentioned above, and then write the bootimage to the position starting from the disk Boot Sector.
When using a boot program like MiloLinuxYou do not needBootloaderInstead, if you only need vmlinuxor vmlinux.gz, the boot program will take the initiative to extract and load the kernel to 0x1000 (Small kernel) or 0x100000 (large kernel), and directly enter the kernel boot part, this is the second section in this article.
For i386 platforms
Generally, BIOS is used in the i386 system to perform the initial boot, that is, to load the first sector of the first bootable partition in the four primary partition tables to the real-mode address 0x7c00, then pass the control to it.
In the "arch/i386/Boot" directory, bootsect. S is the source code for generating the boot sector. It first copies itself to 0x90000, and then copies the setup section (second sector) following it to 0x90200, copy the real kernel code to 0x100000. All of the above copy actions are based on bootsect. s, setup. S and vmlinux are stored continuously on disks. That is to say, our bzimage or zimage files are organized in the order of bootsect, setup, and vmlinux, it is stored in the continuous disk sector that begins with the first sector of the boot partition.
After bootsect. s completes the loading, it will jump directly to 0x90200. Here is the program entry of setup. S. Setup. the main function of S is to copy the system parameters (including memory and disk, which are returned by the BIOS) to the 0x90000-0x901ff memory, which is exactly the bootsect. S is stored, and it will be overwritten by system parameters. In the future, these parameters will be read by the code in protection mode.
In addition, setup. s includes the code in video. s to detect and set the display and display modes. Last, setup. s converts the system to the protection mode and redirects to the kernel boot code in the 0x100000 (for the large kernel in bzimage format, 0x100000, for zimage format,BootloaderThe process ends.
For the 2.4.x Kernel
No changes.
II.KernelGuide entry
Under the link script control of arch/alpha/vmlinux. LDS, the linking program places the vmlinux entry on _ start in "arch/alpha/kernel/head. s". Therefore, whenBootloaderWhen you jump to 0x100000, the code at _ start starts to be executed. The _ start code is very simple. You only need to set the global variable and jump to start_kernel. Start_kernel () is the asmlinkage function in "init/Main. c". So far, the startup process is transferred to the General C code unrelated to the architecture.
For i386 platforms
In the i386 architecture, due to i386's own problems, in the "arch/alpha/kernel/head. s "requires more settings, but it is finally executed through call symbol_name (start_kernel) to start_kernel (), an architecture-independent function.
The difference is that in the i386 system, bootsect must be pre-processed when the kernel is compressed in the form of bzimage, that is, the big kernel mode (_ big_kernel. S and setup. s. bbootsect is generated using $ (CPP) processing in the big core mode. S and bsetup. s, and then compile the corresponding. o file, and use "arch/i386/boot/compressed/build. C "build tool, the actual kernel (uncompressed, including the head in the kernel. s Code) and head under "arch/i386/boot/compressed. S and Misc. C is merged, where the head. s replaces "arch/i386/kernel/head. sBootloaderBootstrap execution (startup_32 entry), and then it calls Misc. the decompress_kernel () function defined in C, using "lib/inflate. C "defines gunzip () to extract the kernel to 0x100000, and then run" arch/i386/kernel/head. startup_32 code in S.
For the 2.4.x Kernel
Not changed.
Iii. 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,
OutputLinuxVersion 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, call the init () function, the original execution sequence calls cpu_idle () 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.
Iv. 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, then create the 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 ())
At this point, the do_basic_setup () function returns Init (). After the startup memory segment (free_initmem () is released and the kernel is unlocked, INIT () opens the/dev/console device, redirects stdin, stdout, and stderr to the console. Finally, search for the INIT program in the file system (or the program specified by the init = command line parameter) and execve () the system calls 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. The default independent initialization process only involves the network (sock_init () and the creation of the Event Management Core Thread, the _ initcall () macro is used for initialization and other operations.
V. INIT process and inittab boot command
The INIT process is the starting point of all the processes in the system. After the kernel is guided, the INIT program is loaded in the null room of the thread (process). 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, 1 is used as the restart to the single-user mode, and 6 is used as the restart; S and S have the same meaning, indicating the single-user mode, the inittab file is not required, so it does not appear 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 common level), 4 is reserved for user customization, and 5 indicates xdm graphical login mode. 7-9 levels are also available, which are not defined by traditional UNIX systems. Runlevel can be multiple parallel values to match multiple running levels. For most actions, runlevel is executed only when it 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, it reads the initdefault item in inittab and obtains the runlevel, as the current running level. If there is no inittab file or there is no initdefault item, init will request to enter runlevel on the console.
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
Vi. 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.
Generally, the RC startup scripts are located at/etc/rc. d directory, RC. the most common actions in sysinit are to activate swap partitions, check disks, and load hardware modules. These actions need to be performed first regardless of the operating level. Only after RC. sysinit is executed will init execute other boot or bootwait actions.
If there are no other boot or bootwait actions, at runtime Level 3,/etc/rc. d/RC will be executed. The command line parameter is 3, that is, run/etc/rc. d/rc3.d/all files in the directory. All files under rc3.d point to/etc/rc. d/init. d/The shell scripts in the directory are connected by symbols. 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. Before that, if the corresponding script also has a K-header link, and it is already in the running state (marked by a file under/var/lock/subsys/), the script starting with K will be started first, use stop as the parameter to stop these started services and then 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.
7. 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
The default logon prompt is recorded in the/etc/issue file. However, the RC. Local script will generate a new logon prompt based on the system environment.
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 username.
If the user name is not root and the/etc/nologin file exists, login outputs the content of the nologin file and then exits. 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, the root user can log on to any terminal. The/etc/usertty file is used to add access restrictions to users. 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, searches for the/etc/shadow file) to match the password, set the main directory, and load the shell. If no main directory is specified, the root directory is used by default. If no shell is specified,/bin/sh is used by default. Before transferring control to shell, Getty will output the information of the Last Logon system recorded in/var/log/lastlog, then, check whether the user has a new email (/usr/spool/mail/{username }). After the UID, GID, term, path, and other environment variables of the shell are set, the process loads the shell and the login task is completed.
8. 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 the GNU extension of the Bourne shell. It not only inherits all the features of SH, but also adds many features and functions. 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, the value is"/sbin:/bin:/usr/sbin:/usr/bin ". As a login shell, it will first find the/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 be executed as an interactive shell ~ /. Bashrc file (if any), in many systems ,~ /. Bashrc starts/etc/bashrc as the configuration file within the system.
When a command line prompt is displayed, the entire startup process ends. The system runs the kernel, several core threads, The INIT process, and a batch of daemon (such as inetd) activated by the rc startup script ), run Bash as your command interpreter.
Appendix: xdm Logon
If the default running level is set to 5, not only are 1-6 Getty listeners listening to text terminals, but also an xdm graphical logon window started. The logon process is similar to the text method. The user name and password are also required. The xdm configuration file is/usr/x11r6/lib/X11/xdm-config by default, the/usr/x11r6/lib/X11/xdm/xsession is specified as the xdm session description script. After successful logon, xdm will execute this script to run a session manager, such as gnome-session.
In addition to xdm, different window management systems (such as KDE and gnome) provide an xdm alternative, such as GAM and KDM. The functions of these programs are similar to those of xdm.