CentOS 5和6的啟動流程
服務管理
Grub管理
自制Linux
啟動排錯
編譯安裝內核
系統啟動流程:
POST --> 讀取BootSequence (BIOS),決定引導次序 -->讀取引導設備的Bootloader(MBR grubstage1-->stage1.5/boot/filkeststem--> boot-->/boot/grub.conf/-->磁盤分區上讀取 kernel(ramdisk來完成對真正根文件所在設備的加載) -->掛載rootfs(只讀)到根設備上 --> 開始運行/sbin/init-->(/etc/inittab /etc/init/*.conf)-->設置默認運行級別-->運行系統初始化腳本,完成系統初始化-->關閉對應級別下需要停止的服務,啟動對應級別下需要開啟的服務.-->rc.local-->設置登錄終端[-->圖形終端]
概論
1.linux組成部分:kernel(內核)+rootfs(GUN,根文件系統) kernel:進程管理、內存管理、網絡管理、驅動程序、文件系統、安全功能 IPC:Inter process communication 消息隊列,semerphor,shm socket rootfs:程序和庫文件glibc 程序:二進制執行文件 glibc:函數集合,function,調用接口 過程調用:prpcedure,無返回值 函數調用:function 2.kernel設計流派 微內核:(monolithic kernel):Linux 把所有工具集成與同一個程序 單內核:(micro kernel): Windows, Solaris 每種功能使用一個單獨子系統實現(模塊化) 3.Linux內核特點: 支持模塊化: .ko(內核對象) 如:文件系統,硬件驅動,網絡協議等 支持內核模塊的動態裝載和卸載 4.linux內核組成部分: 核心文件: /boot/vmlinuz-VERSION-release vmlinuz的字母表示內核是壓縮文件 輔助的偽根系統:ramdisk 啟動操作系統,需要驅動,但驅動在根文件系統上,開機時掛載不了根文件系統,就需要一個第三方來輔助,生成一個虛擬的根文件系統,生成專用用戶的專用驅動,來加載真正的根文件系統上的驅動. CentOS 5: /boot/initrd-VERSION-release.img CentOS6,7: /boot/initramfs-VERSION-release.img 模塊文件: /lib/modules/VERSION-release(內核版本號) 注意:安裝多版本的內核,有多個模塊目錄 5.模塊文件目錄: /lib/modules/2.6.32-431.el6.x86_64/kernel arch :與平臺相關的特有代碼(x86 x64) crypto :加密解密的組件 drivers : 驅動 fs :文件系統 kernel :內核追蹤用到的組件 lib :庫 mm :內存管理 net :網絡管理 sound:聲音驅動 6.運行中的系統環境可分為兩層:內核空間,用戶空間 用戶空間:應用代碼(進程或線程) 內核空間(內核模式):內核代碼(系統調用) 任何應用程序在運行過程中,有可能需要不斷發起模式轉換,兩種空間不斷轉換.轉換的速率決定系統的性能. 7.建議在生產環境里面,將ctrl+alt+del里面重啟的快捷鍵禁用
啟動流程
僅適用于MBR類型架構的PC主機
1.centos6啟動流程
1.POST加電自檢 2.加載BIOS的硬件信息,獲取第一個啟動設備。 3.讀取第一個啟動設備MBR的引導加載程序(grub)的啟動信息 4.加載核心操作系統的核心信息,核心開始解壓縮,并嘗試驅動所有的硬件設備。 5.核型執行init程序并獲取運行信息。 6.Init執行/etc/rc.d/rc.sysinit文件。 7.啟動核心的外掛模塊(/etc/modprobe.conf)。 8.Init執行運行的各個批處理文件(scripts). 9.Init執行/etc/rc.d/rc.local. 10.執行/bin/login程序,等待用戶登錄。 11.登錄之后開始以Shell控制主機。
1. POST: Power-On-Self-Test,加電自檢,是BIOS功能的一個主要部分。負責完成對CPU、主板、內存、硬盤子系統、顯示子系統、 串并行接口、鍵盤、 CD-ROM光驅等硬件情況的檢測。 post(加電自檢) 其實就是按開機鍵的那個過程,檢測你的系統硬件信息 ,通過什么檢測(cpu) 什么都不會干,執行事先編排好的指令和程序,cpu從哪加載指令和程序,能從硬盤拿數據嗎?去內存拿數據 剛系統初始化過程中內存是空白的,沒有數據, 這就要求系統自己完成這個的過程,通常內存有兩種:ROM RAM ,計算機識別的內存和我們平時說的內存是不一樣的 設備尋址時 不光識別物理4G內存條,還有一個低地址空間(BIOS的空間)在主板上有一個ROM芯片,里面嵌入了一段程序,(叫BIOS 基本輸入輸出系統)程序的作用就是掃描計算機的硬件, 開機過程中計算機會將他的指針指向內存低地址空間 自動在開機過程中CPU的指揮下將某個特殊的硬件的設備內容裝在進內存,將BOis中的程序和指令映射進(物理地址空間)ROM 中,cpu就能讀取指令,檢測設備是否完整不需要任何額外指令,是硬件內置的,這個過程就是加電自檢。 bios 還要完成啟動設備的次序決定,決定哪個設備先啟動(USB裝系統) ROM: BIOS, Basic Input and Output System,保存著有關計算機系統最重要的基本輸入輸出程序,系統信息設置、 開機加電自檢程序和系統啟動自舉程序等。 RAM: CMOS互補金屬氧化物半導體,保存各項參數的設定按次序查找引導設備,第一個有引導程序的設備為本次啟動設備 2.bootloader: 引導加載器,引導程序 從BISO中按次序查找各引導設備,第一個有引導程序的設備即為本次啟動要用到的設備. 程序類型: windows: ntloader,僅是啟動OS Linux:功能豐富,提供菜單, LILO: LInux LOader(缺陷:無法支持大硬盤分區) GRUB: GRand Unified Bootloader(統一引導加載器) centos 5,6: GRUB 0.X: GRUB Legacy(經典版), 各種安卓手機使用 centos 7: GRUB 1.X: GRUB2(跟0.X版本比,完全重寫) 功能:提供一個菜單,允許用戶選擇要啟動系統或不同的內核版本;把用戶選定的內核裝載到內存中的特定空間中,解壓、展開,并把系統控制權移交給內核 MBR:Master Boot Record 512字節: 446byts: bootloader; 64byts: 分區表; 2byts: 55AA bootloader空間太小,446字符的代碼只能實現最基本的功能 GRUB: 為向用戶提供更好的開機體驗,加入開機菜單,開機圖片等更多功能,bootloader的小空間不能滿足,grub分成三個階段,第一階段放在bootloader,bootloader不再直接加載內核,而是加載grub的第二階段,第二階段是一個虛擬操作系統,在磁盤分區內,有大的容量.相當于在啟動操作系統前,啟動一個虛擬操作系統(程序),不受MBR的限定,提供復雜的功能(陣列圖,菜單,交互式接口),選定操作系統后,再由第二階段加載內核文件.在第二階段之前,還有第1.5階段,提供文件系統驅動,方便虛擬系統的生成. 第一階段: primary boot loader : 1st stage, 1.5 stage 第1.5階段 :Partition:filesystem driver,1.5stage 文件系統驅動接口 第二階段 :Partition /boot/grub/ : 2nd stage,分區文件 不支持復雜邏輯的軟raid,內核分件只能放在基本磁盤分區上 UEFI:可擴展固件接口(Extensible Firmware Interface,EFI)是 Intel 為 PC 固件的體系結構、接口和服務提出的建議標準。其主要目的是為了提供一組在 OS 加載之前(啟動前)在所有平臺上一致的、正確指定的啟動服務,被看做是有近20多年歷史的 BIOS 的繼任者。 GPT: GUID磁碟分割表(GUID Partition Table,縮寫:GPT)其含義為“全局唯一標識磁盤分區表”,是一個實體硬盤的分區表的結構布局的標準。它是可擴展固件接口(EFI)標準(被Intel用于替代個人計算機的BIOS)的一部分,被用于替代BIOS系統中的一32bits來存儲邏輯塊地址和大小信息的主開機紀錄(MBR)分區表。 3.kernel: 有gurb中選定內核,把內核文件展開后,kernel自身初始化,然后接管系統的控制權,開始完成復雜的操作. 自身初始化操作(按順序操作): A.探測可識別到的所有硬件設備 B.加載硬件驅動程序(有可能借助于ramdisk加載驅動) C.以只讀方式掛載根文件系統(只讀掛載,以防內核的錯誤操作,操作過程出錯) D.運行用戶空間的第一個應用程序: /sbin/init init程序的類型: CentOS 5之前: SysV init 配置文件: /etc/inittab CentOS 6: Upstart init (支持并發啟動服務) 配置文件: /etc/inittab(只是定義系統啟動級別) /etc/init/*.conf(ntOS 7主要使用) Ce: Systemd systemd 配置文件: /usr/lib/systemd/system, /etc/systemd/system ramdisk: 不在發行版系統光盤上事先存在,而是在裝系統后,掃描硬件設備后動態生成的 內核中的特性之一:使用緩沖和緩存來加速對磁盤上的文件訪問 ramdisk 轉換成 ramfs(文件系統) 提高速度 centos 5: initrd, 創建工具程序: mkinitrd CentOS 6,7initramfs,創建工具程序: mkinitrd, dracut 系統初始化過程: POST --> 讀取BootSequence (BIOS),決定引導次序 -->讀取引導設備的Bootloader(MBR) -->磁盤分區上讀取 kernel(ramdisk來完成對真正根文件所在設備的加載) -->掛載rootfs(只讀)到根設備上 --> 開始運行/sbin/init( systemd 4.init程序(sbin/init) centos5:SysV init 運行級別:為了系-統的運行或維護等目的而設定的機制; 0-6 :7個級別 0:關機 shutdowm 1:單用戶模式(root自動登錄), single, 維護模式 2: 多用戶模式,啟動網絡功能,但不會啟動NFS;維護模式 3:多用戶模式,正常模式;文本界面 4:預留級別;,目前無特別適用目的, 可同3級別 5:多用戶模式(multi user),完全功能模式;圖形界面 6:重啟 默認級別: 3, 5 切換級別: init # 查看級別: runlevel ; who -r 配置文件: /etc/inittab 每一行定義一種action以及與之對應的process id:runlevel:action:process id:一個任務的標識符 runlevels:在哪些級別啟動此任務;#,###,也可以為空,表示所有級別 action:在什么條件下啟動此任務 wait: 等待切換至此任務所在的級別時運行一次 respawn:此任務終止時,就重新啟動之 initdefault:設定默認運行級別; process省略 sysinit:設定系統初始化方式,此處一般為指定/etc/rc.drc.sysinit ca::ctrlaltdel:/sbin/shutdown -t3 -r now process:具體任務 ,通常是應用程序,或腳本,或二進制程序 例: id:3:initdefault: 表示設定默認啟動級別(centos6兼容) si::sysinit:/etc/rc.d/rc.sysinit 表示所有級別利用/etc/rc.d/rcsysinit設定系統初始化 l3:3:wait:/etc/rc.d/rc 3 表示當切換到3級別時運行/etc/rc.d/rc腳本,往腳本里傳遞參數為3,意味著去啟動或關閉/etc/rc.d/rc3.d/目錄下的服務腳本所控制的服務,不同級別,數字不同. 6:2345:respawn:/usr/sbin/mingetty tty6(定義終端1-6):表示在2345運行級別啟動mingetty指令,給指令傳遞參數tty1,一旦該程序停止,要自動重啟。mingetty會調用login程序,打開虛擬終端的程序,除了minget ty之外,還有諸如getty等 x:5:respawn:/etc/X11/prefdm -nodaemon 表示在5運行級別啟動時,打開圖形化終端 系統初始化腳本:/etc/rc.d/rc.sysinit,完成后才會啟動各種服務 (1) 設置主機名 (2) 設置歡迎信息 (3) 激活udev和selinux (4) 掛載/etc/fstab文件中定義的文件系統 (5) 檢測根文件系統,并以讀寫方式重新掛載根文件系統 (6) 設置系統時鐘 (7) 激活swap設備 (8) 根據/etc/sysctl.conf文件設置內核參數 (9) 激活lvm及software raid設備 (10) 加載額外設備的驅動程序 (11) 清理操作 運行級別的相關服務: init在利用/etc/inittab配置文件,進行用戶空間系統初始化時,會有關于默認運行級別的定義,當定義好默認運行級別,利于/etc/rc.d/rc.sysinit完成系統 初始化后,就會按照運行級別,來關閉、打開相應級別下的服務 /etc/rc:規定關閉啟動服務機制 rc腳本接受一個運行級別數字為參數,/etc.rc.d/有rc+運行級別的目錄,有K和S開頭+運行級別+服務名的文件,每個文件鏈接/etc/init.d相應的程序文件. 各種服務的控制腳本程序是存放在/etc/rc.d/init.d/目錄下,然后各個對應級別下要關閉或開的程序以軟連接的方式存放在/etc/rc.d/rc運行級別.d/目錄下 以K開頭的表示要關閉的服務,K##*:關閉優先級,##數字越小,越是優先關閉;依賴的服務先關閉,而后關閉被依賴的; 以S開頭的表示要開啟的服務,##*:啟動優先級,##數字越小,越是優先啟動;被依賴的服務先關閉,依賴別人的服務后啟動 一般是先關閉相關服務后,再開啟相關服務 /etc/rc.d/rc.local 該腳本為正常行級別運行后的最后一個腳本,可以將一些希望開機時自動啟動,但又不合適編輯成服務腳本的一些命令或程序,寫在該文件中, 單獨成行,即可完成開機自動啟動;正常級別下,最后啟動一個服務S99local沒有鏈接至/etc/rc.d/init.d一個服務腳本,而是指向了/etc/rc.d/rc.local腳本 對應的文件在/etc/init/control-alt-delete.conf里,可通過/etc/inittab獲知其定義信息 /etc/rc.d/init.d/下的腳本的格式: 這類腳本都需要在開頭注釋段標明:一般要接受至少start、stop、restart、status四個參數 #!/bin/bash # crond start/stop the cron daemon 標明腳本功能 ,此項可以不寫 # chkconfig:LLL NN MM 標明該服務腳本初始狀態下的運行級別,啟動優先級,關閉優先級,必須要寫 LLL:自動為on級別 NN:自動為on的優先級 MM:自動為OFF的優先級 例:# chkconfig:2345 11 88 # description: 描述 功能代碼段 … /etc/init.d/*(/etc/rc.d/init.d/*)服務腳本執行方式: #/etc/init.d/服務腳本 {start/restart/stop/status} #service SRV_SCRIPT {start/restart/stop/status} 為了統一管理服務關閉啟動,設置服務腳本機制.利用chkconfig命令自動在各級別目錄下創建對應的K或S的服務管理鏈接文件,且可以管理服務腳本的開機啟動或關閉等,要想利用chkconfig進行管理,腳本必須要滿足上述注釋段的要求,然后將腳本放到/etc/init.d/目錄下 chkconfig命令:管控/etc/init.d/每個服務腳本在各級別下的啟動或關閉狀態; 查看:chkconfig --list [服務名] 添加:chkconfig --add 服務名 SysV的服務腳本放置于/etc/rc.d/init.d (/etc/init.d) 刪除:chkconfig --del 服務名 修改執行的連接類型: chkconfig [--level LEVELS] name <on|off|reset> --level LEVELS:指定級別,默認為234 動態管理服務 xinetd service命令,手動管理服務 瞬態( Transient)服務被xinetd進程所管理進入的請求首先被xinetd代理 配置文件: /etc/xinetd.conf、 /etc/xinetd.d/<service> 與libwrap.so文件鏈接 用chkconfig控制的服務: chkconfig tftp on 總結(用戶空間的啟動流程):/sbin/init(/etc/inittab) 設置默認運行級別-->運行系統初始化腳本,完成系統初始化-->關閉對應級別下需要停止的服務,啟動對應級別下需要開啟的服務.-->設置登錄終端[-->圖形終端] centos6: init程序:upstart,但依然為/sbin/init,其配置文件:/etc/init/*.conf 為了兼容centos5,仍然有/etc/inittab,但僅僅是定義系統默認運行級別
/etc/rcs.conf:定義系統初始化腳本 /etc/rc.conf:主配置文件, /etc/start-tty.conf:定義啟動虛擬終端 /etc/init-system-dbus.conf: 定義啟動服務 注意:*.confwei為upstar風格的配置文件. GRUB:完全一樣 centos7: init程序:systemd,配置文件:/usr/lib/systemd/system/*,/etc/systemd/system/* 與centos5,6的開機啟動服務相比,centos7開機時不啟動任何服務,當訪問某種服務時,才會啟動服務,不訪問的服務保持沉默狀態 完全兼容SycV腳本機制;因此,server命令依然可用,不過,建議使用systemctl命令來控制服務. systemctl {start|stop|restart|status} name[.service] 設定默認系統運行級別:(不再是修改/etc/inittab,此文件指明更改方法) 命令:systemctl set-default TARGET.target 查看當期的運行平臺: systemctl get-default 常用的運行平臺: # multi-user.target: analogous to runlevel 3 # graphical.target: analogous to runlevel 5 沒有運行級別的概念,為了兼容centos5.6,設定不同的運行平臺,來對應0-6的運行級別
2.詳解GRUB(BOOT Loader)
grub legacy:主要運行分三個階段 stage1(第一階段):安裝在mbr中 stage1.5(第1.5階段):存放在mbr之后的扇區中,讓stage1中的bootloader能識別stage2所在的分區上的文件系統(否則他是沒辦法加載第二階段的) stage2(第2階段):這個就是我們開機能看到提供菜單,讓我們能夠編輯時的加載界面的那個階段,第二階段是存放在磁盤分區上的,一般都在/boot/grub/目錄下 =====以上就是grub的組織格式====== grub也有配置文件:/boot/grub.conf通常有個符號連接文件在/etc/grub.conf 配置文件:/boot/grub/grub.conf <-- /etc/grub.conf 因此當我們系統啟動的時候如果要加載grub所在的磁盤時,會讀取這個磁盤上的Mbr,從此能加載到stage1,stage1加載完以后會嘗試去加載stage1.5,stage1.5階段讀到以后,從而就能夠驅動stage2所在的磁盤分區;其實這個磁盤分區上不但有第二階段,還有內核文件和ramdisk等等,都在這個分區上放置著,這就是為什么grub能夠加載內核文件的原因。注意:主板bios必須能夠識別硬盤。然后bios才能去加載硬盤上的boot loader,磁盤上boot loader加載完以后就能夠直接識別當前主機能識別到的硬盤設備了,但是,硬盤設備能夠識別,并不以為著能夠識別硬盤中的文件系統,因為文件系統是額外附加的一層軟件組織的文件結構。所有要想能夠對接某種文件系統,必須要用到文件系統驅動。所謂的stage1.5階段也就是給grub提供了文件系統驅動,從而grub就能夠訪問對應的stage2和內核所在的分區了,這通常應該是一個基本磁盤分區,畢竟stage1.5不可能做的過于復雜。所以grub的第二階段,以及內核以及ramdisk文件通常都會放在一個基本磁盤分區 stage2及內核等通常放置于一個基本磁盤分區(就是一般的磁盤分區,不是lvm和軟raid;因為grub根本就驅動不了邏輯卷) 功用: (1)提供菜單,并提供交互式接口 e:編輯模式,用于編輯菜單 c:命令模式,交互式接口(命令行接口) (2)加載用戶選擇的內核或操作系統 允許用戶傳遞參數給內核 可隱藏菜單 (3) 為菜單提供保護機制 為編輯菜單進行認證 為啟動內核或操作系統進行認證 如何識別硬盤設備: (hd#,#)第幾塊硬盤的第幾個分區 hd#: 磁盤編號,用數字表示;從0開始編號 #: 分區編號,用數字表示; 從0開始編號 (hd0,0) 第一塊硬盤,第一個分區 grub的命令行接口 help:獲取幫助列表 help KEYWORD:詳細幫助信息 find (hd#,#)/PATH/TO/SOMEFILE:
root (hd#,#) 把哪個磁盤設備設定為根設備 kernel /PATH/TO/KERNEL_FILE: 設定本次啟動時用到的內核文件;額外還可添加許多內核支持使用 cmdline參數 例如: max_loop=100 selinux=0 init=/path/to/init initrd /PATH/TO/INITRAMFS_FILE: 設定為選定的內核提供額外文件的ramdisk;必須與內核版本號完全匹配,否則無法被內核裝載 boot: 引導啟動選定的內核 cat /proc/cmdline 顯示/boot/grub/grub.conf中內核的參數 內核參數文檔:/usr/share/doc/kernel-doc-2.6.32/Documentation/kernel-parameters.txt 手動在grub命令行接口啟動系統: grub> root (hd#,#) 指明根設備 grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE(只讀方式啟動根文件系統) grub> initrd /initramfs-VERSION-RELEASE.img 指明ramdisk文件 grub> boot 引導內核 配置文件: /boot/grub/grub.conf
default=#: 設定默認啟動的菜單項;落單項(title)編號從0開始 timeout=#:指定菜單項等待選項選擇的時長(用戶在規定時間內不操作,自動跳過菜單) splashimage=(hd#,#)/PATH/TO/XPM_FILE:菜單背景圖片文件路徑,支持顏色很少 hiddenmenu:隱藏菜單 password [--md5] STRING: 啟動菜單編輯認證 STRING:加密密碼串 重啟生效 title TITLE:定義菜單項“標題” , 可出現多次 root (hd#,#): grub查找stage2及kernel文件所在設備分區;為grub“根” kernel /PATH/TO/VMLINUZ_FILE [PARAMETERS]:啟動的內核 ,這里的根是指root指向的第一個硬盤,第一個分區(hd0,0). 刪除rhgb quiet選項,取消開機圖形界面,查看內核啟動消息 initrd /PATH/TO/INITRAMFS_FILE: 內核匹配的ramfs文件 password [--md5] STRING: 啟動選定的內核或操作系統時進行認證 Max_loop=100 增加loop設備的數量(內核參數) 獨立分區的boot kernel和initrd 可以寫成 (hd0,0)/vimlinuz- 非獨立分區的boot kernrl (hd0.0)/boot/vimlinuz- grub加密: 1.openssl passwd -1 或 指定鹽: openssl passwd -salt "weds" -1 2grub-md5-crypt命令,生成密碼串, 編輯/boot/grub/grub.conf 把生成的密碼串放到password字段后 #password --md5 $1$8xzRy$xKj1/D5nb.9flfTfSRl5x.
進入單用戶模式:(可破解root密碼) 啟動系統時,設置其運行級別1 進入單用戶模式: (1) 編輯grub菜單(選定要編輯的title,而后使用e命令); (2) 在選定的kernel后附加 1, s, S或single都可以;編輯好敲回車 (3) 在kernel所在行,鍵入“ b”命令 安裝grub: (1) grub-install 安裝grub stage1和stage1_5到/dev/DISK磁盤上,并復制GRUB相關文件到 DIR/boot目錄下 grub-install --root-directory=DIR /dev/DISK (2) grub grub> root (hd#,#) grub> setup (hd#)
3.自制linux系統
1.分區并創建文件系統 fdisk /dev/sdb 分兩個必要的分區 /dev/sdb1對應/boot /dev/sdb2對應根 / mkfs.ext4 /dev/sdb1 2.掛載boot mkdir /mnt/boot mount /dev/sdb1 /mnt/boot 3.安裝grub grub-install --root-directory=/mnt /dev/sdb 4.. 恢復內核和initramfs文件 cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /mnt/boot/ cp /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot 5.建立grub.conf文件 Vim /mnt/boot/grub.conf kernel /vmlinuz-2.6.32-642.el6.x86_64 root=/dev/sda2 selinux=0 init=/bin/bash chroot /mnt/sysroot 6. 創建一級目錄 mkdir /mnt/sysroot mount /dev/sdb2 /mnt/sysroot mkdir –pv/mnt/sysroot/{etc,lib,lib64,bin,sbin,tmp,var,usr,sys,proc,opt,home,root,boot,dev,mnt,media} 7. 復制bash和相關庫文件
4.救援模式
5.內核 Kernel
centos系統啟動流程:POST-->biso-->bootloaer 加電自檢后,讀取bootloader中某個磁盤的MBR,kernel ,rootfs,init都是bootloader引導. ldd命令:打印二進制程序文件的依賴庫,沒有對應文件的庫,是真正的二進制程序入口. ldd /bin/ls | grep -o "lib[^[:space:]]*"
內核設計體系:單內核,微內核 linux:單內核,但充分借鑒微內核體系設計的優點:為內核引入了模塊化機制 linux的內核是宏內核架構, 把大部分功能集成在了內核上, 然后又吸取了微內核的優點, 把非必需的驅動做成模塊, 在需要的時候加載至內核中, 由于linux支持的硬件和平臺眾多, 通用內核通常會具有一些用不上的功能和模塊, 此時就需要工作人員對內核進行定制化編譯來達到提升內核運行效率和減少其他驅動出錯造成系統錯誤的機會. 內核的組成部分: kernel:內核核心,一般為bzimage,通常位為/boot目錄,一般我們看到這個文件,就說明內核文件沒用了,在系統啟動時已經被加載過,開機后不在被使用,放在目錄里,方便我們后期管理. kernel object:內核對象,即內核模塊,一般放置于/lib/modules/VERSION-release/. A.內核模塊與內核核心版本一定要嚴格匹配; B.內核模塊化的主要動因:為了能夠支持第三方廠商的硬件設備及其驅動程序,可以引進內核模塊化的方式設計,這樣每一個廠商都可以把自己的設備驅動寫成內核模塊,當用到這個設備時,單獨編譯這個內核模塊.針對于當前內核的源碼樹,編譯這個模塊,并裝載到內核上就可以使用了; C.在對內核的編譯中,定義某個內核的功能,分為三種選擇: [ ]:N 編譯時不啟動功能,留空 [M]:Module 編譯成內核模塊,用到時臨時裝載,只占用磁盤空間,不占用內核內存空間 [*]:Y 直接編譯進內核核心,只要內核在,功能就在,不用裝載. D.內核:動態裝載和卸載 ramdisk:輔助性文件,并非必須,這取決于內核是否能直接驅動rootfs所在的設 備;能直接驅動,ramdisk就不需要;不能驅動,就需要借助ramdisk封裝驅動,不僅包括設備的驅動程序,也可以包括設備上的格式化所提供的邏輯設備,比如說lVM,文件系統;如果都編譯成模塊的話,都可以加載到內核中. 借助于ramdisk,能加載的驅動,包括為: 目標設備驅動,例如:ISCSI設備的驅動 邏輯設備驅動,例如:LVM設備的驅動 文件系統,例如:XFS文件系統 ramdksk:是一個簡裝版的根文件系統;不能作為一個操作系統使用,因為運行在內存中,缺少長久性,所以操作系統必須在持久性存儲設備上,這也是做根切換的原因.提供設備驅動,僅僅是為了能夠讓內核找到真正的根文件系統. 內核信息查看: uname命令: -a, --all 全部顯示 -s, --kernel-name 內核名稱 -n, --nodename 節點名稱(主機名) -r, --kernel-release 內核發行號 -v, --kernel-version 內核編譯版本號 -m, --machine 硬件架構類型 -p, --processor cpu類型 -i, --hardware-platform 硬件平臺名稱 -o, --operating-system 操作系統類型
模塊信息查看: lsmod命令:顯示當前內核已加載的模塊名,模塊大小,被引用次數,被什么模塊所引用 抽取/proc/modules的信息,lsmod抽取內核自己的輸出接口的信息,以人性化的方式輸出. modinfo命令:顯示指定模塊文件的詳細信息 無論模塊是否被裝載,都可以用modinfo查看,modinfo就是通過獲取/lib/modules目錄下與當前內核版本同名的目錄下的模塊原數據文件,加以顯示的.模塊原數據文件類似于rpm包的元數據數據庫,可以支持查詢操作,需要專門的命令.每個文件都是經過hash格式編碼,文件里面的都是鍵值對,從中查找數據的性能是O1(恒定)的,衡量一個算法的標準,O1,On,Olocaln.. 選項: -F:只顯示指定字段的信息 -a: -n:顯示文件路徑,相當于 -F filename, -k:默認顯示當前內核信息,要想顯示其他內核的相關模塊,使用-k選項指明kernel,和模塊名
模塊信息管理: modprobe命令:模塊動態裝載和卸載 modpobe [-r] mod_name 模塊動態裝卸載也可以基于文件實現,-c指明配置文件,默認是/etc/modprobe.d/*.conf文件 選項: 裝載模塊: modprobe 模塊名 被依賴的模塊也會被裝載 卸載模塊: modprobe- r 模塊名 正在使用的和默認裝載的模塊千萬不要卸載,會影響系統使用
depmod命令:生成模塊依賴關系 內核模塊依賴關系文件及系統信息映射文件的生成工具 大多數命令選項,不使用;只有在新增模塊時,這個模塊依賴于其他模塊,不得不手動改寫模塊文件.自己手動執行drpmod命令 在對另外一個的內核文件生成依賴關系,并且保存文件也不放在/boot目錄下,才有必要使用-b,-F,-E 選項指明內核文件,和內核模塊 模塊裝載和卸載的另一組命令: insmod命令: insmod [filename][module options...] filename:模塊文件的文件路徑,配合modinfo -n 查看模塊文件路徑
rmmod命令: rmmod [module_name(模塊名)]
ramdisk文件的管理: 不是直接生成的,而是由命令管理的 (1)mkinitrd命令: centos5 但6,7也有連接 為當前使用中的內核重新制作ramdisk文件 文件名: centos5:initrd-2.6.32-504.30.3.el6.x86_64kdump.img centos6,7:initramfs-2.6.32-504.30.3.el6.x86_64.img 命令格式: mkinitrd [OPTION...] [<initrd-image>] <kernel-version> --with=<module>:除了默認的模塊之外需要裝載至initramfs中的模塊,重新制作ramdisk的重要原因,添加新的模塊. --preload=<module>:initramfs所提供的模塊需要預先裝載的模塊; 示例: mkinitrd /boot/initramfs-$(uname -r).img $(uname -r) (2)dracut命令 centos 6,7 較為底層的生成ramdisk文件的工具 #dracut [OPTION...] [<initrd-image>] <kernel-version> 示例:dracut /boot/initramfs-$(uname -r).img $(uname -r) 內核信息輸出的偽文件系統: /proc/:內核狀態和統計信息的輸出接口.可以通過各種文件系統直接管理.同時,還提供一個配置接口,/proc/sys; 參數: 只讀:信息輸出;/proc下以數字命名的目錄,只是用來輸出某進程的相關信息./例如:/proc/#/* 可寫:可接受用戶指定一個"新值"來實現對內核某功能或特性的配置;寫權限只有管理員擁有./proc/sys/ 專門用來修改用于支持修改其值的參數,從而能夠讓我們實現配置內核參數的 偽文件系統的參數與/proc/sys/目錄下的每個文件有映射關系,都相對與/proc/sys/目錄而言,每個參數對應著我們所看到的/proc/sys/目錄下的每個文件, 文件路徑中的斜杠分隔符替換成點號,就成為參數名; 示例:net/ipv4/ip_forward相當于net.ipv4.ip_forward 修改方式: (1)sysclt命令 專用于查看或設定/proc/sys/目錄下參數的值 命令使用格式: sysclt [options] [variable[=value]] 查看: #sysclt -a 查看全部信息 #sysclt variable 指定參數名稱 variable為文件目錄的簡裝路徑,以點分隔 修改其值: #sysclt -w variable=value
(2)文件系統命令(cat,echo) 偽文件系統,不能使用文本編輯器去直接編輯,而應該使用重定向的方式覆蓋原值 查看: #cat /proc/sys/PATH/TO/SOME_KERNEL_FILE 設定:使用覆蓋重定向修改內核參數 echo "node1" > /proc/sys/kernel/hostname
注意:上述兩種方式的設定僅當前內核有效,內核或系統重啟,配置失效 (3)配置文件 有可能是兩種文件, centos 5,6: /etc/sysctl.conf centos7: /etc/sysctl.d/*.conf 分隔成多段配置 修改配置文件,不會立即生效,下次啟動系統 立即有效:重讀此配置文件,通知讓sysctl命令重讀此文件,并根據此文件的設定,來修改內核參數相關值即可 sysctl -p [/PATH/TO/CONFLG_FILE] 從指定文件中加載內核參數的相關設定,默認讀取/etc/sysctl.conf,可指定其他文件,但最好在/etc/sysctl.d/目錄下. 內核參數: 1.net.ipv4.ip_forward,核心路由轉發功能 2./proc/sys/vm/drop_caches:回收內存 0: 1: 2: 3./proc/sys/kernel.hostname:主機名 4./proc/sys/net/ipv4/icmp_exho_ignore_all 忽略別人ping自己,自己可以ping 別人 /sys/目錄: 掛載的是sysfs:輸出內核識別出的各硬件設備的相關屬性信息,也有內核對硬件特性的可設定參數;對此些參數的修改,即可定制硬件設備工作特性; [root@Wencx ~]# ls /sys block bus class dev devices firmware fs hypervisor kernel module power 塊設備,總線, 不同目錄,通過不同視角對各設備劃分的類別;根據總線劃分,根據類別劃分等等,另外也會根據某些特殊內容做些不同類的輸出,或者說很多文件,很多設備所輸出的位置不止一個目錄,但是在多個目錄下指向的同一個文件或設備. 對一個linux主機來講,每一個硬件設備被訪問就要有設備文件,設備文件在/dev/目錄下,內核怎么知道不同用戶會有哪些硬件設備呢?事先不得而知.那應該準備怎樣的設備文件來讓內核識別呢?不知道的情況下,只能全部列出所有的設備文件,linux內核2.4以后在/dev/目錄下有兩萬多個設備文件,無法預測用戶用到哪些設備,所以把用戶但凡用到的全創建出來,那么有兩個問題?一.用戶使用的很少,大多數文件浪費,雖不占用磁盤空間,但文件數量過大,二,沒辦法通過設備文件判斷某個設備的存在./sys/目錄在linux2.6內核引入后,使得我們能夠按需創建設備文件,意思是說,每一次當內核系統完成自身初始化的時候,它會自動探測識別出每一個硬件設備信息,而后在把設備信息在系統啟動完后,在內核初始化完后,在根文件系統掛載后,在重新探測輸出到/sys/目錄下,有多少硬件都在/sys/目錄下顯示.但是有些設備沒有設備文件,就會臨時讀取/sys/目錄下的設備信息,給它按需創建設備文件.對/dev/目錄來說至關重要. udev:通過讀取/sys/目錄下的硬件設備信息按需為各硬件設備創建設備文件.是用戶空間程序,不能直接跟硬件打交道,/sys/目錄的存在才讓udev讀取硬件設備信息.專用命令:devadmin,hotplug; 當根文件掛載完成后,系統初始化已經結束,系統就不會輸出硬件信息./sys/目錄的存在就會強制內核重新輸出一遍內核信息,把內核中的各硬件設備信息輸出至/sys/目錄下,而這時候udev就會通過讀取/sys/目錄下的硬件設備信息按需為各硬件設備創建設備文件. /dev/目錄下許多文件是Udev創建的,還有一些是內核創建的,比如說內核還要識別/sda硬盤,如果不能識別sda硬盤,標識為一個設備的話,怎么掛載設備?為了讓設備訪問正常,內核自動通過devtmpfs(設備臨時文件系統),為每個內核必須用到的設備創建一個設備文件,這些設備文件可以在根文件系統掛載以后,從內核直接移到/dev/目錄下,但不是完全移動,剩下的拷到udev, udev為設備創建設備文件時,會讀取其事先定義好的規則文件,一般在/etc/udev/rules.d目錄下,以及在/usr/lib/rules.d/目錄下; /etc/udev/rules.d/70-persistent-net.rules文件,更改網卡配置文件的定義,并更改
內核編譯
復習: 內核組成:kernel,kernel object,ramdisk kernel:uname kernel object:lsmod,modinfo,modprobe,rmmod,depmod ramdisk:mkinitrd,dracut 系統啟動流程: post-->bootsequence(BISO)-->bootloader MBR(grub)-->kernel(ramdisk)-->rootfs(swith_root)-->/sbin/init(/etc/inittab,/etc/init/*.conf,/usr/lib/system/)-->設定默認運行級別-->系統初始化-->關閉或啟動服務-->/etc/rc.local/-->啟動終端(圖形終端) grub: 1st stage:mbr 1.5 stage:MBR之后的扇區 2st stage:磁盤分區上/boot/grub/ 加密:grub編輯功能驗證,內核驗證 編譯概論: 程序包的編譯安裝 ./configure,make ,make install 內核編譯的前提 開發環境(開發工具,開發庫),頭文件:/usr/include 為什么編譯呢 開源:拿到自由程序的源代碼,能夠自由獲取,自由學習,自由修改,自由創建衍生版,自由分發,更多拿到源代碼程序是應用,就有了發行版 發行版:按照自已的理解,以"通用(要能夠在某種平臺上被絕大所數用戶的平臺所兼容)"的目標,把各種開源的源代碼拿過來,組織成一個完備的操作系統.不同發行版,有不同的收錄包. 當前內核版本低,內核有重大bug,重新定義內核功能. 前提: (1)準備好開發環境 C語言 (2)獲取目標主機上的硬件設備的相關信息.編譯內核時要選擇驅動,驅動的選擇正確與否,決定編譯是否成功,編譯過程根據硬件平臺和選擇功能不同,編譯時間從20分鐘到二個小時不等.內核代碼數非常大 (3)獲取目標主機系統功能的相關信息,例如要啟動的文件系統 (4)獲取內核源代碼包 www.kernel.org 編譯過程: (1)準備開發環境: centos6: 包組:Development Tools,Server Platform Development entos7: 包組:Development Tools,Server Platform Development, 注意:必須安裝ncurses程序包,通過下面命令查看 [root@wen-6 ~]# yum list all *ncurses* (2)獲取硬件信息 CPU:cpu型號 #cat /proc/cpuinfo #x86info -a (需要安裝程序x86info) #lscpu PCI設備:顯卡,網卡,鼠標,鍵盤 lspci
lsusb
lsblk 塊設備
了解全部硬件設備信息(跟win資源觀路器類似,通過hal硬件抽象層映射的) hal-device (可能需要額外安裝) rpm -q /usr/bin/hal-device 查看安裝情況,centos6默認安裝 (3)獲取內核源代碼包 從kernel.org官方站點下載同主線最新的內核模塊, 筆者用的archlinux , 內核版本為4.7.2 下載了最新版本的4.7.3版本的內核源代碼進行編譯和安裝. 編譯之前組安裝下開發工具(development tools)
wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.12.63.tar.xz 從官網下載內核源碼包 tar xvf linux-3.18.41* -C /usr/src 解壓源碼包至/usr/src cd /usr/src 進入/usr/src目錄 ln -sv linux -3.18.41 linux (使用鏈接方式,以防版本更新,鏈接方便,發支持回滾) 創建源碼包鏈接 ls /usr/src/linux (內核源碼樹) arch:運行平臺 (cpu運行在市面上大部分平臺上) block:塊設備相關內核級代碼 crypto:加密庫 Documentation:幫助文檔(最佳學習內核的資料) drivers:驅動(按類) firmware:固件設備驅動 fs:文件系統 include:頭文件 init:init程序 ipc:進程間通信機制 kernel:內核核心 lib:庫文件 mm:內存管理 net:網絡協議棧 samples:使用示例 scripts:用到的腳本 security:安全機制 sound:聲音設備 tools:內核自帶工具 usr: virt:虛擬化(內核級)
(4) 配置內核選項(選擇其中一種,也可以多種方式聯合)必須在/usr/src/linux目錄下 配置內核選項的工具(方式,一共7種) make help 查看方式 支持“更新”模式進行配置: 在已有的.config文件的基礎上進行更新操作 (a) make config:基于命令行以遍歷的方式去配置內核中可配置的每個選項 (b) make menuconfig:基于curses的文本窗口界面(最容易理解) 必須安裝: yum -y install ncurses-devel 使用方式:通過鍵盤進行選擇,選項后面有箭頭代表有子選項,回車進入,每個選項選*代表編譯進內核,M代表編譯成模塊,不選表示不編譯不啟用此功能,選擇到exit鍵可以退出.  (c) make gconfig:基于GTK (GNOME)環境窗口界面 必須有桌面環境("桌面平臺開發"包組)和相應的開發環境 (d) make xconfig:基于QT(KDE)環境的窗口界面 必須有桌面環境(KDE)和相應的開發環境 支持“全新配置”模式進行配置 原有配置全部覆蓋 (a) make defconfig:基于內核為目標平臺提供的“默認”配置為模板進行配置 (b) make allyesconfig: 所有選項均回答為“yes“ 用于內核測試 (c) make allnoconfig: 所有選項均回答為"no“ 用于內核測試 (5)編譯: (1)多線程編譯:make [-j #] 編譯內核,可使用-j指定編譯線程數量,cpu必須多核心,不指定的話,默認只在一個核心上編譯.編譯順序按照/usr/sur/linux目錄下的文件順序 (2)編譯內核的一部分功能: (a) 只編譯某子目錄中的相關代碼: # cd /usr/src/linux 切換到源碼樹下 # make net/wirelese/ (b) 只編譯一個特定的模塊: # cd /usr/src/linux # make net/wirelese/chan.c 注意:單獨編譯模塊,只能手動復制到定義特定目錄的相應目錄下,編譯好的模塊在/lib/modules/內核版本號/kernel/的相關目錄下.不能使用make install命令自動復制 例如:只為e1000編譯驅動: #make drivers/net/ethernet/intel/e1000/e1000.ko (3)交叉編譯: 如何交叉編譯內核: 目標平臺與當前編譯操作所在的平臺不同; # make ARCH=arch_name make ARCH= 要獲取特定目標平臺的使用幫助 # make ARCH=arch_name help # make ARCH=arm help (4)如何在執行過編輯操作的內核源碼樹上做重新編譯 需要事先清理操作: # make clean:清理大多數編譯生成的文件,但會保留config文件和外部模塊的編譯鏈接等 # make mrproper: 清理所有編譯生成的文件、 config及某些備份文件 # make distclean: mrproper、 patches以及編輯器備份文件 然后在重復以上編譯操作,重新編譯 (6)安裝內核模塊 make modules_install (7)安裝內核 make install (8)重啟系統,選擇新內核即可 root 編譯內核的過程描述 (1)準備好開發環境 C語言(建議在非最小化系統下進行,否則開發環境安裝出錯) (2)獲取目標主機上的硬件設備的相關信息.編譯內核時要選擇驅動,驅動的選擇正確與否,決定編譯是否成功, 編譯過程根據硬件平臺和選擇功能不同,編譯時間從20分鐘到二個小時不等.內核代碼數非常大 (3)獲取目標主機系統功能的相關信息,例如要啟動的文件系統 (4)獲取內核源代碼包 www.kernel.org (5)準備.config 文本配置文件 (5)make menuconfig 配置內核選項(其中一種做法) (6)make [-j #] 編譯內核,可使用-j指定編譯線程數量,cpu必須多核心,不指定的話,默認只在一個核心上編譯.編譯順序按照/usr/sur/linux目錄下的文件順序 (7)make modules_install 安裝內核模塊 (8)make install 安裝內核 (9)reboot 注意:如果是遠程連接主機編譯內核,建議在screen下操作配置內核選項過程 打開screen:screen 拆除screen:Crtl+a,d 列出screen:screen -ls 連接至screen:screen -r screen_id 關閉screen:exit 第一次編譯,為了編譯成功,可以仿照當前系統的內核選項,來進行設定要編譯的內核.要復制一個模板,在/boot/config****.x86下, redhet放在這目錄下,可供我們參照.但有些發行版的內核模板是/proc/config.gz.可自動輸出.復制這個文件,到內核源碼目錄下,改名成 .config.打開文件都是內核選項. 操作示例: (1)準備開發環境 安裝必要包組 yum groupinstall
安裝ncurses服務
(2)獲取目標主機的硬件設備信息
(3)獲取內核源碼包 [root@wen-6 src]# wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.12.63.tar.xz [root@wen-6 src]tar xf linux-3.10.67.tar.xz -C /usr/src [root@wen-6 src] cd /usr/src [root@wen-6 src]ln -sv linux-3.10.67 linux (4)準備內核配置模板.config文件(有能力自己配置內核選項,可忽略此步) cd /usr/src/linux cp /boot/config-$(uname -r) ./.config
(5)配置內核選項 make menuconfig
(6)編譯內核( make -j 2)
(7)安裝內核模塊 make modules_install
(8)安裝內核 make install
(9)查看內核文件
(10)重啟系統,選擇最新內核進入系統 reboot
原創文章,作者:wencx,如若轉載,請注明出處:http://www.www58058.com/46271