linux启动流程分析

来源:互联网 发布:初学英标用什么软件 编辑:程序博客网 时间:2024/06/07 10:20

1:加电到bootloader加载

系统加电,BIOS(基本输入输出系统)代码装载入内存

一:自检,主要负责监测系统外围关键设备(CPU、内存等)是否正常

1、根据配置的启动设备(如harddisk、cdrom、网卡--pxe方式等)去读区启动代码

        A:硬盘启动:

         (1)BIOS会读区硬盘第一个扇区的512Bytes中前446个字节bootloader代码,我们拷贝出硬盘第一扇区的内容

                              dd if=/dev/sda of=mbrFile bs=512 count=1 && file mbrFile

#dd if=/dev/sda of=mbrFile bs=512 count=1 && file mbrFile记录了1+0 的读入记录了1+0 的写出512字节(512 B)已复制,0.000177423 秒,2.9 MB/秒mbrFile: x86 boot sector; GRand Unified Bootloader, stage1 version 0x3, 1st sector stage2 0x449fe, GRUB version 0.94; partition 1: ID=0xee, starthead 0, startsector 1, 4294967295 sectors, extended partition table (last)\011, code offset 0x48  
        MBR会保存有bootloader代码,并且含有分区表记录,主要记录一些分区类型、是否是活动分区、分区跨度等信息。之后我们可以在分区上建立文件系统(常见的文件系统例如FAT、NTFS、EXT2、EXT3等等),俗称格式化。

       "硬盘的第一个扇区是MBR(512字节,512 字节=446(引导程序)+64(分区表信息)+2(结束标记)),如果有安装grub,那么接下来的31KiB (62扇区)是grub引导程序的位置,也就是说,要使用grub这样的双引导程序,硬盘的第一个分区至少要从63扇区开始,而一般情况下(默认),硬盘的第一个分区是从2048扇区开始",这里63个扇区,其中第一个是MBR位置。


关于GRUB:

grub引导也分为两个阶段stage1阶段和stage2阶段(有些较新的grub又定义了stage1.5阶段)。

        1)、stage1:stage1是直接被写入到MBR中去的,这样机器一启动检测完硬件后,就将控制权交给了GRUB的代码。也就是上图所看到的前446个字节空间中存放的是stage1的代码。BIOS将stage1载入内存中0x7c00处并跳转执行。stage1(/stage1/start.S)的任务非常单纯,仅仅是将硬盘0头0道2扇区读入内存。而0头0道2扇区内容是源代码中的/stage2/start.S,编译后512字节,它是stage2或者stage1_5的入口。而此时,stage1是没有识别文件系统的能力的。如果感觉脑子有些晕了,那么下面的过程就直接跳过,去看stage2吧!

        【外传】定位硬盘的0头0道2扇区的过程:

         BIOS将stage1载入内存0x7c00处并执行,然后调用BIOS INIT13中断,将硬盘0头0道2扇区内容载入内存0x7000处,然后调用copy_buffer将其转移到内存0x8000处。在定位0头0道2扇区时通常有两种寻址方式:LBA和CHS。如果你是刨根问底儿型的爱好者,那么此时去找谷哥打听打听这两种方式的来龙去脉吧。

         2)、stage2:严格来说这里还应该再区分个stage1.5的,就一并把stage1.5放在这里一起介绍了,免得大家看得心里乱哄哄的。好的,我们继续说0头0到2扇区的/stage2/start.S文件,当它的内容被读入到内存之后,它的主要作用就是负责将stage2或stage1.5从硬盘读到内存中。如果是stage2,它将被载入到0x820处;如果是stage1.5,它将被载入到0x2200处。这里的stage2或者stage1_5不是/boot分区/boot/grub目录下的文件,因为这个时候grub还没有能力识别任何文件系统

        ?  如果start.S加载stage1.5:stage1.5它存放在硬盘0头0道3扇区向后的位置,stage1_5作为stage1和stage2中间的桥梁,stage1_5有识别文件系统的能力,此后grub才有能力去访问/boot分区/boot/grub目录下的 stage2文件,将stage2载入内存并执行。

        ?  如果start.S加载stage2:同样,这个stage2也不是/boot分区/boot/grub目录下的stage2,这个时候start.S读取的是存放在/boot分区Boot Sector的stage2。这种情况下就有一个限制:因为start.S通过BIOS中断方式直接对硬盘寻址(而非通过访问具体的文件系统),其寻址范围有限,限制在8GB以内。因此这种情况需要将/boot分区分在硬盘8GB寻址空间之前。

        假如是情形2,我们将/boot/grub目录下的内容清空,依然能成功启动grub;假如是情形1,将/boot/grub目录下stage2删除后,则系统启动过程中grub会启动失败。


这里备注几个链接:

http://blog.chinaunix.net/uid-24774106-id-3500759.html

http://www.civilnet.cn/bbs/browse.php?topicno=78395

http://blog.chinaunix.net/uid-23069658-id-3142047.html



           (2)grub加载好以后会根据分区表找到active分区,从分区的文件系统中找到/boot/grub目录下menu.list配置信息

                                  cat /boot/grub/menu.list

#cat /boot/grub/menu.lst # grub.conf generated by anaconda## Note that you do not have to rerun grub after making changes to this file# NOTICE:  You have a /boot partition.  This means that#          all kernel and initrd paths are relative to /boot/, eg.#          root (hd0,0)#          kernel /vmlinuz-version ro root=LABEL=/#          initrd /initrd-[generic-]version.img#boot=/dev/sdbdefault=0timeout=5splashimage=(hd0,0)/grub/splash.xpm.gzhiddenmenutitle CentOS 6 (2.6.32-504.el6.x86_64)root (hd0,0)kernel /vmlinuz-2.6.32-504.el6.x86_64 ro root=LABEL=/ rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM biosdevname=0initrd /initramfs-2.6.32-504.el6.x86_64.img
       主要指示了kernel和initrd文件所在分区,grub根据配置文件加载操作系统内核和内存文件系统到内存


这里备注两幅图,分别是centos6.5 grub与centos7分区表:

下面是centos7 grub2引导、MBR分区

[root@localhost etc]# fdisk -lu /dev/vda磁盘 /dev/vda:214.7 GB, 214748364800 字节,419430400 个扇区Units = 扇区 of 1 * 512 = 512 bytes扇区大小(逻辑/物理):512 字节 / 512 字节I/O 大小(最小/最佳):512 字节 / 512 字节磁盘标签类型:dos磁盘标识符:0x000649e5   设备 Boot      Start         End      Blocks   Id  System/dev/vda1   *        <span style="color:#ff0000;">2048</span>     1026047      512000   83  Linux/dev/vda2         1026048   419430399   209202176   8e  Linux LVM

下面是centos6.5 grub引导、GPT分区

[04:57:12root@NOHOSTNAME-2MYJS72 /root]#parted /dev/sdaGNU Parted 2.1使用 /dev/sdaWelcome to GNU Parted! Type 'help' to view a list of commands.(parted) print                                                            Model: DELL PERC H310 (scsi)Disk /dev/sda: 4000GBSector size (logical/physical): 512B/512BPartition Table: gptNumber  Start   End     Size    File system     Name     标志 1      <span style="color:#ff0000;">1049kB</span>  268MB   267MB   ext4            primary  启动 2      268MB   16.4GB  16.1GB  ext4            primary 3      16.4GB  18.5GB  2147MB  linux-swap(v1)  primary 4      18.5GB  4000GB  3982GB                  primary
这里计算一下,分区一的起始是1049KB,换算成扇区是1049/0.5=2098扇区

基本可以归纳一下:

(1)我们可以用fdisk或者parted命令来为磁盘创建分区(主要用来写分区表,MBR分区一般用fdisk命令即可,parted命令则既可以创建MBR也可以创建GPT分区)
(2)分区创建完毕后,我们使用mkfs.extX一类的命令去创建文件系统(也可以使用parted命令在分区并同时创建文件系统)


文件系统:

 一些常见的文件系统比如Linux下使用的ext2、ext3、ext4、btrfs,windows的fat16、fat32、NTFS,vmware的VMFS,一些分布式的文件系统dfs、hdfs、tfs、fastDfs、ceph等

       稍微介绍下linux的ext2文件系统,linux下访问某种文件系统都是都要通过VFS这层去访问。一个分区建立ext2文件系统,一个ext2分区分为多个块组,块组里面必有的信息是index node bitmap、block bitmap、index node table、data blocks;可选信息是super block(存放分区文件系统信息,inode、data block等使用信息等等)、group descriptor。

       对于linux中的进程而言,文件表现为内存中的三张表结构:进程表中的文件记录项(文件描述符标志--FD_CLOEXEC 和指向文件表项的指针)、文件表(文件状态标志--

O_RDONLY O_WRONLY O_RDWR O_APPEND O_NONBLOCK O_SYNC O_ASYNC 、当前文件位移量、指向该文件i节点表项的指针)、i节点结构(每个打开的文件或者设备都有i节点结构,其中绝大部分数据是从磁盘分区的index node table中读取的)

等数据。

备注下关于linux文件系统分析的几个链接:

http://www.cnblogs.com/peon/archive/2011/06/22/2086470.html

http://blog.chinaunix.net/uid-20561320-id-3032661.html

        B:网络启动--pxe启动

PXE     

“The PXE environment relies on a combination of industry-standard Internet protocols,namely UDP/IP, DHCP and TFTP. These protocols have been selected because they are easily implemented in the client's NIC firmware, resulting in standardized small-footprintPXE ROMs. Standardization, small size of PXE firmware images and their low use of resources are some of the primary design goals, allowing the client side of the PXE standard to be identically implemented on a wide variety of systems, ranging from powerful client computers to resource-limited single-board computers (SBC) and system-on-a-chip (SoC) computers.

       DHCP is used to provide the appropriate client network parameters and specifically the location (IP address) of the TFTP server hosting, ready for download, the initial bootstrap program (NBP) and complementary files. To initiate a PXE bootstrap session the DHCP component of the client's PXE firmware broadcasts a DHCP DISCOVER packet containing PXE-specific options to port 67/UDP (DHCP server port); it asks for the required network configuration and network booting parameters. The PXE-specific options identify the initiated DHCP transaction as a PXE transaction. Standard DHCP servers (non PXE enabled) will be able to answer with a regular DHCP OFFER carrying networking information (i.e. IP address) but not the PXE specific parameters. A PXE client will not be able to boot if it only receives an answer from a non PXE enabledDHCP server.

     After parsing a PXE enabled DHCP server DHCP OFFER, the client will be able to set its own network IP address, IP Mask, etc., and to point to the network located booting resources, based on the received TFTP Server IP address and the name of the NBP. The client next transfers the NBP into its own random-access memory (RAM) using TFTP,possibly verifies it (i.e. UEFI Secure Boot), and finally boots from it. NBPs are just the first link in the boot chain process and they generally request via TFTP a small set of complementary files in order to get running a minimalistic OS executive (i.e.WindowsPE, or a basic Linux kernel+initrd). The small OS executive loads its own network drivers and TCP/IP stack. At this point, the remaining instructions required to boot or install a full OS are provided not over TFTP, but using a robust transfer protocol (such asHTTP, CIFS, or NFS). ”

简单翻译上面一段话就明白了

PXE程序集成在硬件上的一段程序,他有自己小的协议栈udp/ip协议(无tcp,因为tcp比较复杂--协议本身和连接过程),PXE要配合DHCP和TFTP服务器,NIC固件中此PXE程序,会从DHCP获得必要的参数信息,例如,IP、NETMASK、GATEWAY、TFTP Server Address、Execution File(传统DHCP server是不会传递TFTP server address和Execution File这类信息的),PXE程序解析配置这些信息后开始从TFTP server获取bootstrap program (NBP),一般为pxelinux.0文件


查看dhcp配置文件如下:

ddns-update-style none;option routers 172.18.1.254;option subnet-mask 255.255.255.0;default-lease-time 21600;max-lease-time 43200;subnet 192.168.122.0 netmask 255.255.255.0 {range 192.168.122.240 192.168.122.253;# TFTP Serverfilename "pxelinux.0";next-server 192.168.122.1;
PXE固件在DHCP OFFER报文中的sname和file字段可以得到TFTP Server地址和要下载的文件名,集合在tftp配置文件中配置的根目录,可以得到完整文件路径。



PXELINUX.0

PXELINUX is used in conjunction with a PXE-compliant ROM on a network interface controller (NIC), which establishes a PXE environment that uses DHCP or BOOTP to configure its minimalistic networking stack capable of UDP/IP networking, and then downloads a bootstrap program via TFTP. This bootstrap program loads and configures an operating system kernel according to directives that are also downloaded from theTFTP server; after the kernel is booted, it sets up its own drivers for network devices,establishes networking configuration, etc. and carries out desired tasks on its own.Typically, PXELINUX is used for performing Linux installations from a central network server, or for booting diskless workstations. 

pxelinux启动参数可以硬编码进pxelinux文件本身,也可以由在DHCP文件中配置,这样这些DHCP option在DHCP OFFER中传递给PXE固件,PXE固件程序在从TFTP server中获得pxelinux后,以获得的参数执行pxelinux。

pxelinux.0也要从TFTP Server中获得配置文件,配置文件目录为working_directory/pxelinux.cfg/目录中(working_directory目录是与pxelinux.0在同一目录层级),具体是哪个配置文件则要根据客户端的UUID MAC IP来决定,其中default文件是最后的选择。

一份配置文件格式如下:

default ksprompt 1timeout 600display boot.msgmenu background splash.jpgmenu title Welcome to CentOS 6.5!menu color border 0 #ffffffff #00000000menu color sel 7 #ffffffff #ff000000menu color title 0 #ffffffff #00000000menu color tabmsg 0 #ffffffff #00000000menu color unsel 0 #ffffffff #00000000menu color hotsel 0 #ff000000 #ffffffffmenu color hotkey 7 #ffffffff #ff000000menu color scrollbar 0 #ffffffff #00000000label linux  menu label ^Install or upgrade an existing system  menu default  linux [ENTER]  kernel vmlinuz  append initrd=initrd.imglabel vesa  menu label Install system with ^basic video driver  kernel vmlinuz  append initrd=initrd.img xdriver=vesa nomodesetlabel rescue  menu label ^Rescue installed system  kernel vmlinuz  append initrd=initrd.img rescuelabel ks  kernel vmlinuz  append ks=http://192.168.122.1/ks.cfg initrd=initrd.imglabel local

pxelinux.0读取此配置后就根据配置情况去取kernel和initrd文件



二:内核启动到内存文件系统挂载

向内核传参的几种方式:https://wiki.archlinux.org/index.php/Kernel_parameters

(1):编译内核时修改参数

(2):在boot loader加载启动内核时

          根磁盘相关启动参数:

               root #指出启动的根文件系统 如:root=/dev/sda1

               ro #指定根设备在启动过程中为read-only,默认情况下一般都是这样配的

               rw #和ro类似,它是规定为read-write,可写

               rootfstype #根文件系统类型,如:rootfstype=ext4

          Console和kernel log相关启动参数:

               console #console的设备和选项,如:console=tty0 console=ttyS0

               debug #enable kernel debugging 启动中的所有debug信息都会打印到console上

               quiet #disable all log messages 将kernel log level设置为KERN_WARNING,在启动中只非常严重的信息

              loglevel #设置默认的console日志级别,如:loglevel=7 (0~7的数字分别为:KERN_EMERG,..,KERN_DEBUG)

              time #设置在每条kernel log信息前加一个时间戳

          内存相关的启动参数:

              mem #指定kernel使用的内存量,mem=n[KMG]

              hugepages #设置大页表页(4MB大小)的最多个数,hugepages=n

          CPU相关的启动参数:

              mce # Enable the machine check exception feature.

              nosmp #Run as a single-processor machine. 不使用SMP(多处理器)

              max_cpus #max_cpus=n, SMP系统最多能使用的CPU个数(即使系统中有大于n个的CPU)

              Ramdisk相关的启动参数:

              initrd #指定初始化ramdisk的位置,initrd=filename

             noinitrd #不使用initrd的配置,即使配置了initrd参数

      初始化相关启动参数:

             init #在启动时去执行的程序,init=filename,默认值为/sbin/init

       PCI相关的启动参数:

             pci #pci相关的选项,我常使用pci=assign_buses,也使用过pci=nomsi

       SELinux相关启动参数:

             enforcing #SELinux enforcing状态的开关,enforcing=0表示仅仅是记录危险而不是阻止访问,enforcing=1完全enable,默认值是0

             selinux #在启动时关闭或开启SELinux,selinux=0表示关闭,selinux=1表示开启selinux

(3):在运行时传参(/proc、/sys)


pid=1的进程那些事:

先来看两个进程树:

centos6.x 采用upstart initsystem

init,1  ├─NetworkManager,1994 ...  ├─Xvnc,30084 :1 -desktop NOHOSTNAME-2MYJS72:1\040(root) -auth ...  ├─atd,2146  ├─auditd,1785  │   └─{auditd},1786  ├─bonobo-activati,30151 --ac-activate --ior-output-fd=18  │   └─{bonobo-activat},30152  ├─ck-xinit-sessio,30089 /usr/bin/ssh-agent /etc/X11/xinit/Xclients  │   ├─gnome-session,30115  │   │   ├─gnome-panel,30148  │   │   │   └─{gnome-panel},30227  │   │   ├─gnome-power-man,30198  │   │   ├─gnome-volume-co,30193  │   │   ├─gpk-update-icon,30195  │   │   ├─metacity,30147  │   │   ├─nautilus,30149  │   │   ├─nm-applet,30194 --sm-disable  │   │   ├─polkit-gnome-au,30202  │   │   ├─ssh-agent,30116 /etc/X11/xinit/Xclients  │   │   └─{gnome-session},30125  │   └─vncconfig,30091 -iconic  ├─clock-applet,30173 --oaf-activate-iid=OAFIID:GNOME_ClockApplet_Factory--  ├─cloudagent.py,27893 ./cloudagent.py  ├─console-kit-dae,2864 --no-daemon  │   ├─{console-kit-da},2865  │   ├─{console-kit-da},2866  │   ├─{console-kit-da},2867  │   ├─{console-kit-da},2868  │   ├─{console-kit-da},2869  │   ├─{console-kit-da},2870  │   ├─{console-kit-da},2871  │   ├─{console-kit-da},2872  │   ├─{console-kit-da},2873  │   ├─{console-kit-da},2874  │   ├─{console-kit-da},2875  │   ├─{console-kit-da},2876  │   ├─{console-kit-da},2877  │   ├─{console-kit-da},2878  │   ├─{console-kit-da},2879  │   ├─{console-kit-da},2880  │   ├─{console-kit-da},2881  │   ├─{console-kit-da},2882  │   ├─{console-kit-da},2883  │   ├─{console-kit-da},2884  │   ├─{console-kit-da},2885  │   ├─{console-kit-da},2886  │   ├─{console-kit-da},2887  │   ├─{console-kit-da},2888  │   ├─{console-kit-da},2889  │   ├─{console-kit-da},2890  │   ├─{console-kit-da},2891  │   ├─{console-kit-da},2892  │   ├─{console-kit-da},2893  │   ├─{console-kit-da},2894  │   ├─{console-kit-da},2895  │   ├─{console-kit-da},2896  │   ├─{console-kit-da},2897  │   ├─{console-kit-da},2898  │   ├─{console-kit-da},2899  │   ├─{console-kit-da},2900  │   ├─{console-kit-da},2901  │   ├─{console-kit-da},2902  │   ├─{console-kit-da},2903  │   ├─{console-kit-da},2904  │   ├─{console-kit-da},2905  │   ├─{console-kit-da},2906  │   ├─{console-kit-da},2907  │   ├─{console-kit-da},2908  │   ├─{console-kit-da},2909  │   ├─{console-kit-da},2910  │   ├─{console-kit-da},2911  │   ├─{console-kit-da},2912  │   ├─{console-kit-da},2913  │   ├─{console-kit-da},2914  │   ├─{console-kit-da},2915  │   ├─{console-kit-da},2916  │   ├─{console-kit-da},2917  │   ├─{console-kit-da},2918  │   ├─{console-kit-da},2919  │   ├─{console-kit-da},2920  │   ├─{console-kit-da},2921  │   ├─{console-kit-da},2922  │   ├─{console-kit-da},2923  │   ├─{console-kit-da},2924  │   ├─{console-kit-da},2925  │   ├─{console-kit-da},2926  │   └─{console-kit-da},2928  ├─crond,2133  ├─cupsd,2020 -C /etc/cups/cupsd.conf  ├─dbus-daemon,30105 --fork --print-pid 5 --print-address 7 --session  ├─dbus-daemon,1983 --system  ├─dbus-launch,30104 --sh-syntax --exit-with-session  ├─devkit-power-da,2940  ├─dhcpd,3131 -user dhcpd -group dhcpd  ├─fcoemon,1970 --syslog  ├─gconfd-2,30123  ├─gdm-user-switch,30171--oaf-activate-iid=OAFIID:GNOME_FastUserSwit  ├─gnome-keyring-d,30129 --start  │   ├─{gnome-keyring-},30130  │   └─{gnome-keyring-},30131  ├─gnome-screensav,30221  ├─gnome-settings-,30132  │   └─{gnome-settings},30134  ├─gvfs-fuse-daemo,30141 /root/.gvfs  │   ├─{gvfs-fuse-daem},30142  │   ├─{gvfs-fuse-daem},30143  │   └─{gvfs-fuse-daem},30144  ├─gvfs-gdu-volume,30161  ├─gvfsd,30137  ├─gvfsd-trash,30167 --spawner :1.8 /org/gtk/gvfs/exec_spaw/0  ├─hald,2035  │   ├─hald-runner,2036  │   │   ├─hald-addon-acpi,2083  │   │   └─hald-addon-inpu,2082  │   └─{hald},2037  ├─httpd,3062  │   ├─httpd,30992  │   ├─httpd,30993  │   ├─httpd,30994  │   ├─httpd,30995  │   ├─httpd,30996  │   ├─httpd,30997  │   ├─httpd,30998  │   └─httpd,30999  ├─ksmtuned,2122 /usr/sbin/ksmtuned  │   └─sleep,9828 60  ├─libvirtd,25359 --daemon  │   ├─{libvirtd},25360  │   ├─{libvirtd},25361  │   ├─{libvirtd},25362  │   ├─{libvirtd},25363  │   ├─{libvirtd},25364  │   ├─{libvirtd},25365  │   ├─{libvirtd},25366  │   ├─{libvirtd},25367  │   ├─{libvirtd},25368  │   └─{libvirtd},25369  ├─lldpad,1853 -d  ├─mingetty,2429 /dev/tty1  ├─mingetty,2431 /dev/tty2  ├─mingetty,2433 /dev/tty3  ├─mingetty,2435 /dev/tty4  ├─mingetty,2437 /dev/tty5  ├─mingetty,2439 /dev/tty6  ├─modem-manager,1998  ├─notification-ar,30172--oaf-activate-iid=OAFIID:GNOME_Notificati  ├─polkitd,3026  ├─pulseaudio,30211 --start  │   ├─gconf-helper,30222  │   └─{pulseaudio},30223  ├─python,35969 /usr/share/virt-manager/virt-manager.py  ├─qemu-kvm,464 -name testos1 -S -M rhel6.6.0 -enable-kvm -m 2048-realtim  │   ├─{qemu-kvm},489  │   └─{qemu-kvm},490  ├─qemu-kvm,11836 -name vm-1-150 -S -M rhel6.6.0 -enable-kvm -m 8192-realti  │   ├─{qemu-kvm},11859  │   ├─{qemu-kvm},11860  │   ├─{qemu-kvm},11861  │   └─{qemu-kvm},11862  ├─qemu-kvm,27096 -name centos7 -S -M rhel6.6.0 -enable-kvm -m 8192-realtim  │   ├─{qemu-kvm},27120  │   ├─{qemu-kvm},27121  │   ├─{qemu-kvm},27122  │   └─{qemu-kvm},27123  ├─rpcbind,1835  ├─rsyslogd,1815 -i /var/run/syslogd.pid -c 5  │   ├─{rsyslogd},1816  │   ├─{rsyslogd},1817  │   └─{rsyslogd},1818  ├─sshd,2098  │   └─sshd,9933   │       └─bash,9961  │           └─pstree,10058 -ahp  ├─trashapplet,30158--oaf-activate-iid=OAFIID:GNOME_Panel_TrashApplet_Facto  ├─udevd,812 -d  │   ├─udevd,15592 -d  │   └─udevd,15596 -d  ├─udisks-daemon,3014  │   └─udisks-daemon,3015  ├─wnck-applet,30156 --oaf-activate-iid=OAFIID:GNOME_Wncklet_Factory--oaf-i  ├─wpa_supplicant,2038 -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f/va  └─xinetd,2107 -stayalive -pidfile /var/run/xinetd.pid


centos7 采用Systemd initsystem

systemd,1 --switched-root --system --deserialize 24  ├─NetworkManager,707 --no-daemon  │   ├─{NetworkManager},901  │   ├─{NetworkManager},903  │   └─{NetworkManager},904  ├─adb,31477 -P 5037 fork-server server  │   └─{adb},31478  ├─agetty,618 --noclear tty1  ├─auditd,573 -n  │   └─{auditd},584  ├─crond,609 -n  ├─dbus-daemon,603 --system --address=systemd: --nofork --nopidfile...  │   └─{dbus-daemon},632  ├─firewalld,595 -Es /usr/sbin/firewalld --nofork --nopid  │   └─{firewalld},1037  ├─irqbalance,599 --foreground  ├─java,2408-Djava.util.logging.config.file=/home/hz_qa/  │   ├─{java},26037  │   ├─{java},26038  │   ├─{java},26039  │   ├─{java},26040  │   ├─{java},26041  │   ├─{java},26042  │   ├─{java},26043  │   ├─{java},26044  │   ├─{java},26045  │   ├─{java},26046  │   ├─{java},26047  │   ├─{java},26048  │   ├─{java},26049  │   ├─{java},26050  │   ├─{java},26051  │   ├─{java},26052  │   ├─{java},26053  │   ├─{java},26056  │   ├─{java},26058  │   ├─{java},26059  │   ├─{java},26068  │   ├─{java},26069  │   ├─{java},26070  │   ├─{java},26071  │   ├─{java},26072  │   ├─{java},26073  │   ├─{java},26074  │   ├─{java},26075  │   ├─{java},26077  │   ├─{java},26078  │   ├─{java},26079  │   ├─{java},26082  │   ├─{java},26083  │   ├─{java},26084  │   ├─{java},26085  │   ├─{java},26086  │   ├─{java},26087  │   ├─{java},26091  │   ├─{java},26092  │   ├─{java},26093  │   ├─{java},26094  │   ├─{java},26104  │   ├─{java},26105  │   ├─{java},26106  │   ├─{java},26107  │   ├─{java},26108  │   ├─{java},26109  │   ├─{java},26110  │   ├─{java},26111  │   ├─{java},26113  │   ├─{java},26125  │   ├─{java},26126  │   ├─{java},26127  │   ├─{java},26137  │   ├─{java},26138  │   ├─{java},26139  │   ├─{java},20565  │   ├─{java},20572  │   ├─{java},20576  │   ├─{java},13332  │   ├─{java},13339  │   ├─{java},13341  │   ├─{java},12007  │   ├─{java},14743  │   └─{java},14744  ├─lvmetad,493 -f  ├─master,1286 -w  │   ├─pickup,11775 -l -t unix -u  │   └─qmgr,1288 -l -t unix -u  ├─polkitd,953 --no-debug  │   ├─{polkitd},1040  │   ├─{polkitd},1041  │   ├─{polkitd},1044  │   ├─{polkitd},1045  │   └─{polkitd},1046  ├─rsyslogd,600 -n  │   ├─{rsyslogd},630  │   └─{rsyslogd},631  ├─sshd,1209 -D  │   └─sshd,14746      │       └─bash,14752  │           └─pstree,14772 -aph  ├─systemd-journal,481  ├─systemd-logind,602  ├─systemd-udevd,499  └─tuned,601 -Es /usr/sbin/tuned -l -P      ├─{tuned},642      ├─{tuned},643      ├─{tuned},644      └─{tuned},645




用户登录

(1)终端登录


等待终端登录的进程

    1  2429  2429  2429 tty1      2429 Ss+      0   0:00 /sbin/mingetty /dev/tty    1  2431  2431  2431 tty2      2431 Ss+      0   0:00 /sbin/mingetty /dev/tty    1  2433  2433  2433 tty3      2433 Ss+      0   0:00 /sbin/mingetty /dev/tty    1  2435  2435  2435 tty4      2435 Ss+      0   0:00 /sbin/mingetty /dev/tty    1  2437  2437  2437 tty5      2437 Ss+      0   0:00 /sbin/mingetty /dev/tty    1  2439  2439  2439 tty6      2439 Ss+      0   0:00 /sbin/mingetty /dev/tty


(2)网络登录


如今,都已经使用ssh远程登录,所以我们看到的进程情况可能如下所示了:

 2098 ?        Ss     0:00 /usr/sbin/sshd41017 ?        Ss     0:00  \_ sshd: root@pts/1 41060 pts/1    Ss+    0:00  |   \_ -bash15728 ?        Ss     0:00  \_ sshd: root@pts/4 15770 pts/4    Ss     0:00      \_ -bash43057 pts/4    R+     0:00          \_ ps afx
其中守护进程sshd的父进程为1

不管是终端登录或者是网络登录也好,其中一些步骤是一致的,如下图所示:


shell启动后会执行相应的配置文件去设置环境变量等,其中有一些配置文件比如:/etc/profile ~/.bashrc等等,shell退出时回执行~/.bashrc.logout等文件


一言概之:

当通过终端或者网络登录时我们得到一个登录shell,其标准输入、标准输出、标准出错都连接到一个终端或者伪终端设备上。这一个登录shell是一个会话的开始,而此终端或者伪终端则是此会话的控制终端,于此相关的一些概念就是:进程、进程组、会话、控制终端、作业控制等相关概念。(父子进程通过网络终端相连接,父进程处理网络通信,子进程为登录shell)

1 0