Linux system startup (2) and linux system startup
The above section describes the general process of Linux Startup and the role of grub. This section mainly talks about initramfs and simply modifies initramfs to run the entire operating system into the memory.
3 Description of initramfs3.1
In the 2.4 kernel, initrd is boot loader initialized RAM Disk. Before linux is started, boot loader unpacks the initrd file and loads it into the memory. After the boot loader loads the kernel, it will first run initrd, and then switch_root to the real root fs.
In the 2.6 kernel, The initrd is upgraded to initramfs, which has the same effect as initrd. However, the initramfs process is more concise, that is, after initramfs is decompressed, The init script is run, so the task is handed over to the init script.
For more information about initrd and initramfs, see [3].
[3]: Linux2.6 kernel Initrd Mechanism Analysis http://www.ibm.com/developerworks/cn/linux/l-k26initrd/
3.2 Basic init process
Initramfs is used to load hardware and file system modules and switch to the real root fs on the root device. Of course, because root fs should be supported on md or dm devices, the md and dm modules will also be loaded during initramfs. If the md is compiled with the kernel, it cannot be viewed from the loaded module.
The following describes how to add a log to the initramfs init file to analyze a general boot process, which is not detailed.
1) After unzipping and loading initramfs to the memory, the current root fs is initramfs, so all files in/are from initramfs.
2) Mount/proc and/sys; mknod to create basic devices, such as/dev/console and/dev/null.
3) udev rules scan the hardware, load the corresponding module, and create the corresponding device. for grub. the root device set in conf. If it is successfully created, the/dev/root link will be created under/dev/to point to the corresponding real device.
4) at the same time, determine whether/dev/root already exists in an infinite loop. If not, execute all udev rules again to check whether new hardware is ready, after 40 judgments (about 20 seconds), if no result is found, "no root device fonud, sleep forever" is returned"
5) mount the real root fs through the root device.
6) Determine whether the/proc directory exists as the standard for successful mounting of root fs (at this time,/proc is only an empty directory ).
7) Determine whether the real root fs init script exists. Generally, it is/sbin/init.
8) after the root fs is mounted to the/sysroot directory, run switch_root/sysroot/sbin/init.
9) after the switch_root command is executed, all initramfs tasks are completed. Switch to the real root fs and start to execute/sbin/init.
3.3 Module loading during initramfs
Begin init:
Opening/proc/modules: No such file or directory
Pre udev:
Module Size Used
After udev:
Module Size Used
Sd_mod 37157 0
Crc_t10dif 1507 1 sd_mod
Sr_mod 16162 0
Cdrom 39769 1 sr_mod
Mptspi 16537 0
Mptscsih 35302 1 mptspi
Mptbase 91106 2 mptspi, mptscsih
Scsi_transport_spi 26117 1 mptspi
Pata_acpi 3667 0
Ata_generic 3611 0
Ata_piix 22588 0
Dm_mod 76856 0
After mount root fs, before switch root:
Module Size Used
Ext4 353883 1
Mbcached 7918 1 ext4
Jbd2 88969 1 ext4
Sd_mod 37157 2
Crc_t10dif 1507 1 sd_mod
Sr_mod 16162 0
Cdrom 39769 1 sr_mod
Mptspi 16537 1
Mptscsih 35302 1 mptspi
Mptbase 91106 2 mptspi, mptscsih
Scsi_transport_spi 26117 1 mptspi
Pata_acpi 3667 0
Ata_generic 3611 0
Ata_piix 22588 0
Dm_mod 76856 0
3.4 decompress and compress initramfs
1. decompress:
-Bash-4.1 # file initramfs-2.6.32-71.el6.5.vsds.x86_64.img
Initramfs-2.6.32-71.el6.5.vsds.x86_64.img: gzip compressed data, from Unix, last modified: Tue Dec 18 17:25:14 2012, max compression
# Gzip file format. Therefore, the mv must be a gz file.
-Bash-4.1 # mv initramfs-2.6.32-71.el6.5.vsds.x86_64.img initramfs-2.6.32-71.el6.5.vsds.x86_64.img.gz
-Bash-4.1 # file initramfs-2.6.32-71.el6.5.vsds.x86_64.img
Initramfs-2.6.32-71.el6.5.vsds.x86_64.img: ascii cpi archive (SVR4 with no CRC)
-Bash-4.1 # gunzip initramfs-2.6.32-71.el6.5.vsds.x86_64.img.gz
Initramfs-2.6.32-71.el6.5.vsds.x86_64.img
# Cpio format
-Bash-4.1 # mkdir initramfs
-Bash-4.1 # cd initramfs
-Bash-4.1 # cpio-id ../initramfs
Initramfs/initramfs-2.6.32-71.el6.5.vsds.x86_64.img
-Bash-4.1 # cpio-id <../initramfs-2.6.32-71.el6.5.vsds.x86_64.img
72953 blocks
2. Compression:
-Bash-4.1 # find. | cpio-c-o> ../initramfs-2.6.32-71.el6.5.vsds.x86_64.img
72953 blocks
-Bash-4.1 # gzip ../initramfs-2.6.32-71.el6.5.vsds.x86_64.img
-Bash-4.1 # cp ../initramfs-2.6.32-71.el6.5.vsds.x86_64.img.gz/boot
3.5 instance --- run the entire operating system in the memory
The following solutions are not actually used. The following are my personal understandings for your reference.
3.5.1 advantages and disadvantages
1. Advantages:
1) Faster running. After the instance is started, the system runs in the memory and runs faster.
2) the file system will not be damaged. System power failure or other damage operations will not cause damage to the operating system.
3) saves storage media space. The operating system can be compressed and stored in a storage medium (with a compression rate of about 80%), or even in a network environment. After the operating system is started, it can be decompressed to the memory.
4) facilitates unified upgrade and upgrade of multiple systems. If the system stores the compressed file in the network environment, the file is upgraded. Any device that uses this file can only be upgraded after being restarted.
2. Disadvantages:
1) The Boot speed is slightly slow. Because the operating system needs to be decompressed to the memory during the startup process, it will be a little slower, about 10 ~ 20 seconds is not obvious.
2) root fs cannot store data. Because the system runs in the memory, the new storage is lost after restart. Therefore, it is generally necessary to separately mount a non-loss medium to the partition where data is stored.
3) more memory requirements. Since a fixed part of the memory is divided into a ram disk, it is used to run the operating system. For applications that require MB of space for the operating system, 2 GB memory is insufficient to support the entire system.
4) updating the system is troublesome. If you want to change the system environment on a regular basis, you need to recreate the compressed file, which is troublesome.
3.5.2 application scenarios
Currently, most embedded systems use this solution based on their small storage space and no data writing requirements. (I am not an embedded engineer, but I guess it is my guess)
3.5.3 Implementation ideas
Idea 1: make the overall system initramfs. (Not tested)
Initramfs is a small file system and the first file system to be loaded when it is started. Therefore, to make the entire system into initramfs, you only need two files to start the system. First, the kernel is vmlinux; second, initramfs.
That is to say, when initramfs finally needs to switch to the real root fs, it will directly run/sbin/init in the system.
However, initramfs may reach 300 MB (about root fs900M). Will the boot loader be loaded for a long time?
Train of Thought 2: In initramfsDecompress the compressed system and copy it To the memory.
As mentioned above, initramfs is actually executing an init script to modify the script process. After the root device is found, mount the mounted root device to/sysroot and then mount the root device to other mount points, find the compressed system file from the root device, decompress the file to ramdisk, Mount ramdisk to/sysroot, and then switch to the real root fs.
3.5.4 implementation code
The following is a simple model based on idea 2.
To decompress the system file and copy it To the memory, you must first make the real root fs as a system file and then load it To the memory through the initramfs process.
1. Create the root fsfile ramlinux.img.gz.
Starting with ramlinux.img.gz (about 80 M after compression and less than 200 M after decompression), panic should be started on the system, and all the files under/should be produced to ramdisk.img.gz, the system runs normally.
The script for making ramdisk.img.gz is mkrootfs. sh as follows:
#! /Bin/sh
Rootfs = "/mnt/ram"
Umount $ rootfs
Rm-rf $ rootfs
# Make ram disk and mount
Dd if =/dev/zero of =/dev/ram bs = 1 M count = 900
Echo y | mkfs. ext2/dev/ram
Mkdir $ rootfs
Mount-o loop/dev/ram $ rootfs
# Cp file to ram disk
Pre_dir = "/"
# Pre_dir = "/mnt/sdf1 /"
# All file in dir cp to ram disk
Cpdir = (bin boot cgroup etc home lib lib64 media opt sbin selinux srv usr var)
For dir_ I in $ {cpdir [@]}
Do
Echo "cp-av $ pre_dir $ dir_ I $ rootfs"
Cp-av $ pre_dir $ dir_ I $ rootfs
Done
# Just mkdir, not cp file
Mkdir = (proc sys tmp mnt root)
For dir_j in $ {mkdir [@]}
Do
Echo "mkdir $ rootfs/$ dir_j"
Mkdir $ rootfs/$ dir_j
Done
# Create dev device
Mkdir $ rootfs/dev
Dev = 'Find/dev'
For dev_ I in $ {dev [@]}
Do
If [$ dev_ I = "/dev/ram"-o $ dev_ I = "/dev"]
Then
Echo "find $ dev_ I pass .................................. ........."
Continue
Fi
Echo "cp-R $ dev_ I $ rootfs/dev"
Cp-R $ dev_ I $ rootfs/dev
Done
# Do ramlinux. img from ram disk
Umount $ rootfs
Dd if =/dev/ram of =/mnt/bigspace/ramlinux. img bs = 1 M
Gzip/mnt/bigspace/ramlinux. img
2. initramfs loads the root FS file ramlinux.img.gz.
Initramfs mounts the real root fs by executing the mount directory of initramfs *. sh, add 98mount-ramdisk.sh to the mount directory, and remove 99mount-root.sh (the original script for mounting the root device to/sysroot ). 98mount-ramdisk.sh is used to decompress and mount system files.
98mount-ramdisk.sh:
#! /Bin/sh
Echo "Mount root device for get img file"
Mount-o defaults -- rw/dev/root/mnt
Echo "zcat img file to ram"
/Bin/zcat/mnt/root/ramlinux.img.gz>/dev/ram
Umount/mnt
Echo "mount-o loop/dev/ram/sysroot"
Mount-o loop/dev/ram/sysroot
Echo "ls/sysroot"
/Bin/ls/sysroot/
[-D "/sysroot/proc"] | echo "proc not exist 5555555555555555555 ........"
3. After completing the preceding steps, extract initramfs, copy 98mount-ramdisk.sh to the mount directory, delete 99mount-root.sh, and regenerate initramfs to overwrite the original file under/boot. the restart takes effect immediately.
4. Other notes. To decompress ramlinux. img, You need to copy the zcat command from the system to the bin directory of initramfs. (Before copying a command, you need to use ldd/bin/zcat to check whether the command has a corresponding dynamic link library. If you want to copy the command together with cp-R to the corresponding directory of initramfs, otherwise, the command cannot be executed if you only copy the command)
5. system environment after restart:
A) After restart, the system can see from the mounting information that the current system is running in the memory, and the new file of touch is not saved after restart. The mounting information is as follows:
-Bash-4.1 # df-h
Filesystem Size Used Avail Use % Mounted on
/Dev/sda1 886 M 886 M 0 100%/
Tmpfs 2.0G 52 M 1.9G 3%/dev/shm
/Dev/sda2 146 M 32 M 106 M 24%/var/log
(The mount device of/Should Not Be/dev/sda1, it should be a problem that the df command shows in the current model, it should be/dev/ram, because it is only a simple model building, many configurations are not modified .)
B)/dev/sda1 is the root device set in grub. conf and is also the medium for the real storage of ramlinux. imgfiles.
-Bash-4.1 # cat/boot/grub. conf
# Grub. conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a/boot partition. This means that
# All kernel and initrd paths are relative to/, eg.
# Root (hd0, 0)
# Kernel/boot/vmlinuz-version ro root =/dev/sda1
# Initrd/boot/initrd-[generic-] version. img
# Boot =/dev/sda
Default = 0
Timeout = 5
Splashimage = (hd0, 0)/boot/grub/splash.xpm.gz
Hiddenmenu
Title SkySAN Storage System (2.6.32-71. el6.5.vsds. x86_64)
Root (hd0, 0)
Kernel/boot/vmlinuz-2.6.32-71.el6.5.vsds.x86_64 ro root = UUID = export rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG = en_US.UTF-8 SYSFONT = latarcyrheb-sun16 KEYBOARDTYPE = pc KEYTABLE = us
Initrd/boot/initramfs-2.6.32-71.el6.5.vsds.x86_64.img
3.6 add log information to the init script.
In the process of understanding the init script, in order to better understand the role of init and the current environment status, we often need to print some information we need, while printing to the screen, if you may save the file, it is easier to read it multiple times.
The method is as follows:
Logfile = "/tmp/logfile"
# Tee is used to output the information to the screen and save the file at the same time.-a: Does not overwrite the original content of the file, which is equivalent to>
Echo "begin init -------------------------------------------------------" 2> & 1 | tee-a $ logfile
Lsmod 2> & 1 | tee-a $ logfile
Sleep 5
......
# Copy the file to the/dev/directory before swith_root and switch it to root fs.
Cp $ logfile/dev/
Exec switch_root "$ NEWROOT" "$ INIT" $ initargs
......