linux文件系統啟動流程、啟動腳本


linux文件系統啟動流程、啟動腳本

下面是一張Linux啟動流程圖:

在了解啟動流程之前,我們應該先知道系統的幾個重要腳本和配置文件,他們對應的路徑為:

1. /sbin/init

2. /etc/inittab

3. /etc/rc.d/rc.sysinit

4. /etc/rc.d/rcN.d //這是幾個文件夾N代表數字1,2,3,4..

5. /etc/fstab

1.關於/sbin/init與/etc/inittab

關於/sbin/init ,它是一個二進制可執行文件,為系統的初始化程序,而/etc/inittab是它的配置文件,我們可以通過/etc/inittab來一睹 它的功能, 里面的內容是一種固定的文本格式,id:runlevels:action:process

我們來通過它的內容來學習它之前,先了解寫運行級別的分類(0-6):

0: 關機 half

1: 單用戶模式 singel user

2: 多用戶模式 multi user , 不提供nfs服務 without nfs

3: 完全多用戶字符模式 full multiuser text mod

4: 系統預留 officially undefined

5: 圖形登錄界面 graphical login

6: 重啟 reboot

 

[html]  view plain  copy
 
 
  1. id:3:initdefault:                             //這里定義linux的啟動時的運行級別,可以看到我主機的啟動級別是3  
  2. # System initialization.  
  3. si::sysinit:/etc/rc.d/rc.sysinit     //緊接着,運行系統第一個腳本/etc/rc.d/rc/sysinit      
  4.                                                //它的action:sysyinit指的是定義系統初始化過程  
  5. l0:0:wait:/etc/rc.d/rc 0                            
  6. l1:1:wait:/etc/rc.d/rc 1                             
  7. l2:2:wait:/etc/rc.d/rc 2                  //然后就是加載服務了,他們被定義在/etc/rc.d/rcN.d  
  8. l3:3:wait:/etc/rc.d/rc 3                  //action:waite 這個進程在在對應級別啟動一次,直到它結束為止,我的系統啟動級別為3,所有執行rc 3對應的服務  
  9. l4:4:wait:/etc/rc.d/rc 4  
  10. l5:5:wait:/etc/rc.d/rc 5  
  11. l6:6:wait:/etc/rc.d/rc 6  
  12.                             
  13. ca::ctrlaltdel:/sbin/shutdown -t3 -r now     //這里定義了一個組合快捷鍵,熟悉吧,沒錯就是重啟,你可以把它注釋掉不用     
  14. pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"  //這里定義了ups電源,powerfail 指的是如果突然斷電,它對應的process命令是,提示用戶系統電源失效,將要關機,提醒用戶把數據都存儲好  
  15. pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"  //這里的action,powerokwaite,指的是系統恢復供電,關機取消...  
  16.   
  17. 1:2345:respawn:/sbin/mingetty tty1           //開啟終端,在系統准備工作做好后,就會啟動出6個終端,tty1~6 mingetyy就是終端的執行命令  
  18. 2:2345:respawn:/sbin/mingetty tty2           //可以看到他們對應的級別是2345,你也可以注釋掉幾個,這樣啟動后,就會開啟你指定個數的終端...   
  19. 3:2345:respawn:/sbin/mingetty tty3           //這里的動作respawn意思是如果用戶關閉,那么這個進程會立刻再次執行   
  20. 4:2345:respawn:/sbin/mingetty tty4  
  21. 5:2345:respawn:/sbin/mingetty tty5  
  22. 6:2345:respawn:/sbin/mingetty tty6  
  23. x:5:respawn:/etc/X11/prefdm -nodaemon       //當一切准備完畢,就會運行守護進程,它是不分運行級別的,同樣也是respawn  

2. 關於etc/rc.d/rc.sysinit 和 /etc/rc.d/rc.Nd

在inittab文件中,我們了解到rc.sysinit是系統運行的第一個腳本,那么它的作用都有哪些呢?如果有shell腳本基礎的話可以用vim打開這個文件來看看,它有900多行...是linux里最牛的腳本,總結下它的作用,有如下幾點:(一定要牢記,必要時我們要重寫它!)

1. 激活udev和selinux

2. 通過讀取/etc/sysct1.conf來設置內核參數

3. 設置系統時鍾

4. 設置鍵盤映射

5. 啟動交換分區。

6. 設置主機名

7. 檢查根文件系統,如果沒有錯誤,以讀寫的方式來重新掛載文件系統 (重要)

8. 激活raid和lvm設備

9. 啟動磁盤限額

10 掛載其他/etc/fstab里定義的尚未被掛載的設備

11. 清理過時的文件鎖和PID文件

12. 啟動服務/etc/rc.d/rcN.d

/etc/rc.d/rcN.d 是一個存放了系統啟動是加載的服務的文件夾,通過inittab,我們知道了,它的編號對應相應的啟動運行級別。

需要說明的是,它里面的文件,以我的為例 以K開頭的代表stop,以S開頭的代表啟動start,數字越小,有限級別越高

[html]  view plain  copy
 
 
  1. [root@server69 rc.d]# cd rc3.d  
  2. [root@server69 rc3.d]# ls  
  3. K01dnsmasq         K74nscd             S08ip6tables    S25bluetooth   S85gpm  
  4. K02avahi-dnsconfd  K85mdmpd            S08iptables     S25netfs       S90crond  
  5. K02NetworkManager  K87multipathd       S08mcstrans     S25pcscd       S90xfs  
  6. K05conman          K88wpa_supplicant   S10network      S26acpid       S95anacron  
  7. K05saslauthd       K89dund             S11auditd       S26apmd        S95atd  
  8. K10psacct          K89netplugd         S12restorecond  S26haldaemon   S97rhnsd  
  9. K20nfs             K89pand             S12syslog       S26hidd        S97yum-updatesd  
  10. K24irda            K89rdisc            S13irqbalance   S28autofs      S98avahi-daemon  
  11. K35vncserver       K99readahead_later  S13portmap      S50hplip       S99firstboot  
  12. K35winbind         S00microcode_ctl    S14nfslock      S55sshd        S99local  
  13. K50ibmasm          S02lvm2-monitor     S15mdmonitor    S56cups        S99smartd  
  14. K50netconsole      S04readahead_early  S18rpcidmapd    S56rawdevices  
  15. K69rpcsvcgssd      S05kudzu            S19rpcgssd      S58ntpd  
  16. K73ypbind          S06cpuspeed         S22messagebus   S80sendmail  

3./etc/fstab文件

它定義了系統初始化掛載的設備,對系統的啟動至關重要,rc.sysinit通過讀取它來實現系統分區的掛載

它的內容如何呢?我們一起來看下

要掛載的設備 掛載點 文件系統類型 掛載選項 轉儲頻率 文件自檢次序

[html]  view plain  copy
 
 
  1. /dev/sda2               /                       ext3    defaults        0 0  
  2. /dev/sda1               /boot                   ext3    defaults        0 0  
  3. sysfs                   /sys                    sysfs   defaults        0 0  
  4. proc                    /proc                   proc    defaults        0 0  

我截取了4個系統啟動時必須掛載的設備

/ 根文件目錄,由它你才可以進入linux的世界,它在/dev/sda2里

/boot 啟動目錄,在/下,里面有grub,initrd和系統內核,它在/dev/sda1

sysfs 一個虛擬的文件系統,產生包含所有硬件層次視圖,和/proc類似

proc 這是一個虛擬的目錄,它映射內存里的信息對應進程信息,也就是說它對應的是內存而不是硬盤

 

好了,了解了這些文件和目錄的作用,我們在回過頭來看那張流程圖:

1. linux開機從POST加電自檢開始,當自檢完成,讀取第一個硬盤的第0個磁頭里的前446個字節,運行里面的bootloader,linux一般   用的是grub。
2. 通過grub傳遞參數給內核,初始化加載內核過程,內核調用initrd(小型內存文件系統,五臟俱全,是一個微型linux),通過     initrd,以只讀方式掛載根文件系統
3. 當根文件系統被掛載后,就會讀取並運行/sbin/init來進行初始化工作。
4. 按次序依次執行/rc/sysinit ,這個時候會重新以讀寫的方式掛載根文件系統
5. 讀取/etc/rc.d/rcN.d/來啟動以s開頭的服務,停止以k開頭的服務
6. 當一切准備完畢,打印終端,出現熟悉的Login界面!(當然,如果你是以5級別啟動的話,Linux就會啟動圖形界面~)

 

 運行一個linux系統需要三項內容:
   1,kernel, 內核,一些核心的代碼塊,如進程管理,它要求體積很小。
   2,initrd, 進入系統所需預告加載的硬件驅動module的一個最小集。當GRUB加載kernel時,kernel會在內存中將initrd文件mount到rootfs上激活,然后kernel照着initrd中的init一步一步地加載驅動。在initrd文件中所放入的模塊,必須是與操作系統同一版本kernel所編譯的模塊。init腳本的工作流程是:
      initrd的參考文檔可見:
      1) Linux initial RAM disk (initrd) overview, http://www.ibm.com/developerworks/linux/library/l-initrd/index.html
      2)  NTTdocomo-openstack / baremetal-initrd-builder, https://github.com/NTTdocomo-openstack/baremetal-initrd-builder
      2.1, nash指令(一個文件小,內置了一些實用的指令)
      2,2 掛載主要的文件系統, 並建立設備文件所需的文件系統
         mount -t proc /proc /proc
         mount -t sysfs /sys /sys
            2.2.1,procfs映射着內存中的一個虛擬目錄,用於提供硬件、進程的實時信息,會隨時變動。linux為保證穩定性,不允許訪問/proc下的文件,root用戶也不例外。
            2.2.2, sysfs也映射着內存中的一個虛擬目錄,用於硬件信息的分類, sys目錄的每一個文件都只有一個字符為內容來做開關的。
            2.2.3, tmpfs也映射着內存中的一個虛擬目錄,內存中的文件系統。想要速度快時,可以選擇在內存建立tmpfs類型的文件系統,因為它都將建在內存中。
                   例如在內存中建立了一個tmpfs分區並掛載到/mnt/tmpfs目錄 :mount -t tmpfs -o size=50M tmpfs /mnt/tmpfs/
                        [root@zhanghua proc]# df -h
                        Filesystem      Size  Used Avail Use% Mounted on
                        tmpfs            50M     0   50M   0% /mnt/tmpfs
            2.2.4, /dev/shm,它是tmpfs的一種變種,tmpfs所有的內容所放在內存中,而/dev/shm在內存與文件系統有個映射,硬盤和內存中都會有這內容。
                  速度快,能存大於內存的文件,但重啟之后,內容會消失。
                  下面顯示在/dev/shm中建立文件與在普通ext4文件系統建文件的速度比較:
                        [root@zhanghua proc]# time dd if=/dev/zero of=/dev/shm/test.file bs=1M count=100
            100+0 records in
            100+0 records out
            104857600 bytes (105 MB) copied, 0.0395221 s, 2.7 GB/s

            real    0m0.075s
            user    0m0.001s
            sys    0m0.041s
            [root@zhanghua proc]# time dd if=/dev/zero of=/bak/test.file bs=1M count=100
            100+0 records in
            100+0 records out
            104857600 bytes (105 MB) copied, 0.0647526 s, 1.6 GB/s

            real    0m0.090s
            user    0m0.001s
            sys    0m0.066s
            2.2.5,devfs, 所有的device都會在/dev目錄建立一個對應的設備文件.
                   缺點是例如即使打印機沒連在計算機上,/dev/printer文件也會存在,這樣會造成在intrd階段的設備過多,所以devfs正在被udev所取代
                   例如要用光驅時,需先在linux與光驅之間通過 mount /dev/cdrom /mnt/命令做關聯
            2.2.6, udev, udev可以放在/sys目錄下,不需要將所有未使用的文件建立設備文件,不再需要major number和minor number,當硬件被加載時可執行用戶設置的script。
                   例如,如果/dev/cdrom是被udev建立的,而非devfs,那么當光驅被撥除時,/dev/cdrom文件就會消失。
            2.2.7,/proc/PID文件,第一個進程都會對應這要閏個文件
            2.2.8,/proc/partitions用來表示檢測到的硬盤信息, major字段表示SCSI controller的slot ID,minor字段表示分區ID。
                  #[root@zhanghua proc]# cat /proc/partitions  
           major minor  #blocks  name
               8        0  488386584 sda
               8        1   82051956 sda1
            2.2.9, /sys/block,塊設備
                  #[root@zhanghua proc]# cat /sys/block/
                    loop0/ loop1/  sda/   sr0/
            2.2.10, /dev/pts ( pseudo terminal slave) 副虛擬終端,其目錄的文件都是由ptmx(主虛擬終端)產生的,它們是父子關系。當用ssh聯機到localhost本地端之后,就會在
                   /dev/pts目錄下產生一個叫做"0"的文件,當別的console也利用ssh聯到這台機器時,就會出現“1“.
                  [root@zhanghua proc]# ps -ef|grep ssh
                   hua      11186  3068  0 16:01 pts/0    00:00:00 ssh hua@localhost  
                   hua      11195 11187  0 16:01 ?        00:00:00 sshd: hua@pts/3
                   如上,當一個用戶以ssh登錄之后,該用戶就分到一個ptmx所賦予的pts資源(pts/3),所以說ssh使用的是虛擬終端,不是真正的tty接口。telnet用的則是真正的tty接口。
            2.2.11, /dev/mapper,如果使用LVM后,linux要和硬盤打交道時不再直接使用/proc/partitions下的硬盤設備,而是使用/dev/mapper下的設備再去中轉。
                    # ls -l /dev/mapper/*
                      brw-rw---- 1 root disk 253, 0 jan 27 16.16  /dev/mapper/vg0-lv0
                    # cat /proc/partitions
                      major minor #blocks name
                       8     0     17528  sda
                       253   0     1111   dm-0
      3,建立最初所需使用的設備文件
         設備文件使用mknod指令建立,mknod指令用來建立字符(character)或塊(block)文件。
         例:mknod /dev/tty1c41, 建立一個名為tty1的設備文件,c表示是字符文件,major=4, minor=1
      4,加載相關模塊
      5,切入image所指示的硬盤中實體操作系統. (rescue mode是直接通過kernel加載initrd進入單純的內存開機的虛擬操作系統)
         5.1, mkrootdev -t ext4 -o defaults.ro hda1, 即nash指令會將GRUB中所設備的root=xxx中的xxx路徑先建立好
         5.2, mount /sysroot, 將GRUB中的root路徑mount到initrd中的/sysroot下。
         5.3, switchroot這個nash指令將initrd中的/sysroot文件系統切換成/rootfs,從而切換到了硬盤中的文件系統。
   3,image, 操作系統的image文件系統,當initrd被加載后,必須為用戶與文件系統牽線。
   4, init進程,在切入到用戶操作系統之后,首先執行linux的init進程(pid=1), init進程再去加載/etc/rc.d/init.d/functions從而啟動服務。
      關於啟動級別與init進程的事兒,也可參見我的另一博文件,Linux的運行級別與解決開機故障一例 ( by quqi99 ), http://blog.csdn.net/quqi99/article/details/7436926
   5, 系統管理
      5.1, 查看CPU信息 cat /proc/cpuinfo
      5.2, 查看內存, cat /proc/meminfo 或者 free -m
      5.3, 查看usb, lsusb
      5.4, 查看PCI, lspci
      5.5, 查看開機日志, dmesg |grep -i error


   本文講的是如何編譯kernel,接下來也會研究如何制作initrd與image.
   最好使用普通用戶執行下面所有操作。
1,下載內核源碼
   git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
   用git tag查看版本,將並代碼切換到v3.8-rc5下, git checkout v3.8-rc5
2,配置內核(有點類似於./configure), 配置前先安裝一個依賴包, sudo yum install ncurses-devel,
   make menuconfig
   說明一下,內核的配置項是三選一,yes, no, 或module。yes, no意味着直接將該特性編譯或不編譯到內核中,module意味着以模塊形式編譯,模塊意味着你開機會可以通modprobe命令動態加載或卸載。
   我在這里選擇的默認配置,生成的配置位於根目錄下的.config文件之中。
   如果你在一個老的配置文件上更改配置的話,可以用make oldconfig命令比較與之前的配置文件的差異來驗證你配置的正確性。
3,執行make命令編譯,
   make
   說明一下,這條命令實際上已經包括了下面的命令:
   1)確定依賴性 make dep
   2)清理編譯中間文件,make clean
   3)編譯內核, make bzImage
   4)生成模塊, make modules
4, 安裝模塊,下列命令會將模塊自動安裝到/lib/modules/3.8.0-rc5/目錄下.
   sudo make modules_install

5, 安裝內核及initrd,人工將arch/x86/boot/bzImage的內核文件拷到/boot目錄即可。
   sudo cp arch/x86_64/boot/bzImage /boot/vmlinuz-3.8.0-rc5
   sudo chmod a+x vmlinuz-3.8.0-rc5

   sudo update-initramfs -u -k version 

  sudo update-grub -o /boot/grub/grub.cfg
   注意:以vmlinuz-<version>這樣命名它。

  上述三步等價於make install, 但make install在自動執行update grub命令時有時候會破壞你的grub文件,特別對於進行PGP加密過的硬盤。

6,「可選」,安裝符號表,只有調試時才需要用到。符號表System.map用以將內核符號和它們的起始地址對應起來,調試的時候,如果需要把內存地址翻譯成容易理解的函數名和以及變量名,就會很有用。

   sudo cp System.map /boot/System.map-3.8.0-rc5
7, 建立initrd文件
   sudo mkinitrd --with=ntfs -o /boot/initrd-linux3.8.0-rc5.img 3.8.0-rc5
   以上mkinitrd命令是參照現有系統的/etc/modprobe.conf和/etc/fstab文件創建一個全新的initrd, 用--with=ntfs會從/lib/modules/3.8.0-rc5目錄將ntfs模塊也做到initrd里去。

   那如何要從頭開始做一個initrd呢?
   1) 可以用 sudo zcat initrd-linux3.8.0-rc5.img | cpio -id 命令解壓 ( initrd文件是以ext2作為文件系統中,所以可以用mount -o loop initrd.img /mnt命令加載.)
   2) 然后將模塊ntfs.ko加到相應的目錄,如lib/modules/3.8.0-rc5/kernel/fs/ntfs目錄
   3) 將ntfs.ko模塊加到init腳本
   4) 重新壓縮,find | cpio -co | gzip -9 > initrd-new.img

8, 更新grub, 編譯/etc/grub/grub.conf文件,添加下面內容,注意千成不要用update grub命令來更新grub哦,這可能會導致你的雙系統無法用。
   menuentry 'Fedora,Linux 3.8.0' --class fedora --class gnu-linux --class gnu --class os {
        set root='(hd0,msdos9)'
        linux   /boot/vmlinuz-3.8.0-rc5 root=/dev/sda10 ro   quiet splash
        initrd /boot/initrd-linux3.8.0-rc5.img
   }

   也可以在開機時按e進入grub編輯模式,再按e一次進入kernel的設置界面:
   grub> root (hd0,msdos9)
   grub> kernel /boot/vmlinuz-3.8.0-rc5 ro root=/dev/sda9 acpi=off (注意,kernel在前的grub>光標后一定要空一行)
   grub> initrd /boot/initrd-linux3.8.0-rc5.img

   grub> boot


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM