從上一篇介紹了系統啟動流程可以得知,在BIOS讀取相關信息之后,接下來就是去找第一個可以啟動的設備當中的MBR中讀取Boot Loader信息,Boot Loader提供具有慘淡功能,直接加載內核信息,以及相關的控制權轉交功能。啟動系統必須有Boot Loader,然后才能去加載內核,Boot Loader存儲于MBR當中,MBR只有512字節,其中前446字節存儲Boot Loader,區區只有446自己不可能容納較多的功能,Linux將Boot Loader的程序運行與配置項加載分成三個階段來運行
stage1:運行Boot Loader主程序,這個程序必須安裝在啟動分區中,即MBR,因為MBR的空間有限,因此在MBR當中進安裝Boot Loader的最小主程序,沒有安裝Boot Loader相關的配置文件
stage1_5:在MBR隨后的扇區存放的是文件系統所需要的驅動程序
stage2:通過Boot Loader加載所有配置文件及相關的環境參數信息,這些配置文件及相關的環境都存放在磁盤分區的/boot目錄下
在此大家一起回憶下系統的啟動流程
POST(加電自檢)àBoot Sequence(BIOS)Boot Loadteràkernel(ramdisk)àrootfsàswitchroot/sbin/inità(/etc/inittab,/etc/init/*.conf)設定默認運行級別系統初始化腳本rc.sysinità關閉或啟動對應級別的服務à啟動終端
grub:Grand Unified Bootloader
grub 0.X(版本號) grub legacy(之前教老的系統用的事0.9的版本)
grub 1.x:grub2
grub legacy
stage1:mbr
stage1_5:mbr之后的扇區,讓stage1中的boot loader能識別stage2所在分區上的文件系統
stage2:磁盤分區(/boot/grub/)
配置文件/etc/grub/grub.confà/etc/grub.conf 此文件是個鏈接文件,真正的文件指向/boot/grub/grub.conf
stage2及內核通常放在一個單獨的磁盤分區
grub的功能
1、 提供啟動菜單、并提供交互接口
a:編輯內核參數
e:編輯模式,用于編輯菜單
c:命令模式,交互式接口
2、 加載用戶選擇的內核或操作系統
允許傳遞參數給內核如max_loop=100,給系統100個loop設備
可隱藏啟動菜單
3、 為菜單提供了保護機制
為編輯啟動菜單進程認證(給grub設置密碼,當用戶進入grub編輯界面需要輸入密碼)
為啟用內核或操作系統進程認證(用戶想進入某個系統需要輸入密碼)
grub的命令行接口
help:獲取幫助列表
help keyword:詳細幫助信息
find(hd#,#)/path/to/somefile
root (hd#,#)
kernel /path/to/kernel_file:設定本次啟動用到的內核文件;額外還可以添加許多內核支持使用的cmdline參數,內核的所有參數文件至/usr/share/doc/kernel-doc-2.6.32/Documentation
如:max_loop=100 selinux=0(關閉selinux) init=/bin/bash啟動的程序
initrd /pah/to/initramfs.img:設定為選定內核提供額外文件的ramdisk
boot:引導啟動選定的內核
這一段過程也是當grub.conf文件損壞或丟失的修復過程
識別硬盤設備:
hd(hd#,#)
hd#:磁盤編號,用數字表示,從0開始編號代表的第一塊硬盤
#:分區標號,用數字表示,從0開始編號代表第一個分區
(hd0,0)第一塊硬盤的第一個分區
手動在命令行接口啟動系統
grub>root (hd#,#)
grub>kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=/dev/device(此分區是“/”文件系統所在分區)
grub>initrd / initramfs-2.6.32-642.el6.x86_64.img
grub>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 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=/dev/mapper/vg0-LogVol00
# initrd /initrd-[generic-]version.img
#boot=/dev/sda //告訴boot所在的磁盤位置
default=0 //設定默認啟動的titile的編號,從0開始
timeout=5 //等待用戶選擇的超時市場,單位是秒
splashimage=(hd0,0)/grub/splash.xpm.gz //grub的背景圖片
hiddenmenu //隱藏菜單
password –md5 加密后的密碼 //設定grub密碼
title CentOS (2.6.32-431.el6.x86_64) //內核標題或操作系統名稱,字符串,可自由修改
root (hd0,0) //內核文件所在的設備對grub而言所有類型硬盤一律為hd;hd#,#表示第n個磁盤,最后的0表示對應磁盤的分區,格式為(hd#,#)
kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=/dev/mapper/vg0-LogVol00 rd_NO_LUKS.UTF-8 rd_LVM_LV=vg0/LogVol00 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet //內核文件路徑,及傳遞給內核的參數
initrd /initramfs-2.6.32-431.el6.x86_64.img //ramdisk文件路徑
password –md5 密碼串 //啟動內核輸入密碼
grub加密
grub-md5-crypt命令(此命令是個交互式,輸入明文密碼,輸出加密密碼)
或
openssl paswwd –salt “abc” -l abc指的是鹽指定任意字符即可
破解root口令(5,6版本的系統)
啟動系統,設置其運行級別為1,也就是所謂的單用戶模式(當然grub沒有設置密碼,如果你不行其他人通過此方式修改root密碼,可以為grub加個密碼)
進入單用戶模式:
1、 編輯grub菜單(選定要編輯的title,之后使用e命令)
2、在選定的kernel后附加 1 | s |S |single 都可以進入單用戶模式
3、在kernel所在行,鍵入b命令,啟動系統進入單用戶模式
grub的安裝
安裝grub的第一種方式
grub-install
安裝grub stage1和stage1_5到/dev/sda1磁盤行(硬盤的第一個分區,通常為boot目錄),并賦值grub相關文件到/boot/目錄下
grub-install –root-directory=dir(通常為boot目錄的父目錄) /dev/sda (boot所在的磁盤)
安裝grub的第二種方式
在命令下執行grub命令,會打開一個交互式的界面等待用戶輸入命令
grub>root (hd#,#) //指定內核所在分區安裝grub
grub>setup (hd#)
系統裁剪(自制linux)
1、 分區并創建文件系統
fdisk /dev/sdb 分兩個必要的區,一個掛載boot,一個掛載sysroot,將分區格式化ext4格式的文件系統
2、 掛載
mkdir /mnt/{boot,sysroot}
mount /dev/sdb1 /mnt/boot
mount /dev/sdb2 /mnt/sysroot
3、 安裝grub
rub-install –root-directory=/mnt /dev/sdb
4、 復制內核和intramfs文件
cp /boot/vmlinuz-2.6.32-642.el6.x86_64 /boot/initramfs-2.6.32-642.el6.x86_64.img /mnt/boot/
5、 創建grub.conf文件
vim /mnt/boot/grub/grub.conf
default=0
timeout=3
title my linux
root (hd0,0)
kernel /vmlinuz-2.6.32-642.el6.x86_64 root=/dev/mapper/vg0-root root=/dev/sda2 selinux=0 init=/bin/bash
initrd /initramfs-2.6.32-642.el6.x86_64.img
6、 創建根下面所需要的目錄
mkdir –-pv/mnt/sysroot/{etc,lib,lib64,bin,sbin,boot,home,var
/log,usr/{bin,sbin},root,tmp,var,usr,proc,sys,dev,mnt,media}
7、 復制bash和相關庫文件
這里使用腳本完成,腳本內容如下:
#!/bin/bash
#
target=/mnt/sysroot
clearCmd() {
if which $cmd &> /dev/null; then
cmdPath=`which –skip-alias $cmd`
else
echo "No such command"
return 5
fi
}
cmdCopy() {
cmdDir=`dirname $1`
[ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir}
[ -f ${target}${1} ] || cp $1 ${target}${cmdDir}
}
libCopy() {
for lib in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`; do
libDir=`dirname $lib`
[ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
[ -f ${target}${lib} ] || cp $lib ${target}${libDir}
done
}
while true; do
read -p "Enter a command: " cmd
if [ "$cmd" == 'quit' ] ;then
echo "quit"
exit 0
fi
clearCmd $cmd
[ $? -eq 5 ] && continue
cmdCopy $cmdPath
libCopy $cmdPath
done
執行腳本移植需要用到的命令如mount,umount,ifconfig,ls,pwd,route,ip,vim等等
系統配置文件丟失修復
系統在引導期間,很重要的一個而過程就是init進程讀取其配置文件/etc/inittab,啟動系統基本服務程序及默認運行級別的服務程序完成引導,如果/etc/inittab誤刪除或修改錯誤,Linux將無法正常啟動,此時,至于通過救援模式才可以解決此類問題,分兩種情況
有備份文件的恢復方法:
進入救援模式,切到根下去(chroot /mnt/sysimage) ,直接將備份文件拷貝到原目錄下即可,如:cp /etc/inittab.bak /etc/inittab
沒有備份文件的恢復方法:
如果一些配置文件丟失或軟件誤刪除,且無備份,可以通過重新安裝軟件包來恢復,首先查找到/etc/inittab屬于哪一個rpm包
chroot /mnt/sysimage
rpm –qf /etc/inittab
initscripts-9.03.53-1.el6.centos.x86_64
之后掛載光盤,然后在安裝initscripts-9.03.53-1.el6.centos.x86_64包
rpm –ivh –replacepgks /media/Packages/initscripts-9.03.53-1.el6.centos.x86_64
如果只提取/etc/inittab文件進行恢復,可以在掛載光盤后執行命令
rpm2cpio /media/Packages/initscripts-9.03.53-1.el6.centos.x86_64 |cpio –id
cp ./etc/inittab /etc/inittab
注意:此命令執行時不能將文件直接恢復至/etc/目錄,只能提取到當前目錄下,且恢復的文件名稱所在路徑要寫完整的路徑,提取文件成功后,將其復制到根分區所在的/mnt/sysimage目錄下相應位置即可
內核版本
uname命令
命令格式:uname [OPTION]..
選項
-n:顯示節點名稱(主機名)
-r:顯示內核版本號
-a:顯示所有信息
-s:顯示內核名稱
-m:顯示硬件平臺
內核模塊命令
lsmod :顯示由核心已經裝載的內核模塊
顯示的內容來自于/proc/modules文件
modinfo顯示模塊的詳細描述信息
命令格式:modinfo [ -0 ] [ -F field ] [ -k kernel ] [ modulename|filename… ]
選項
-n:只顯示模塊文件的路徑
-p:顯示模塊參數
-a:author作業
-d:description描述
-l:license
示例:
modinfo ext4
modprobe裝載或卸載內核模塊
modprobe [ -r ] [ -v ] [ -n ] [ -i ] [ modulename… ]
選項
-r:卸載模塊 modprobe -r mod_name
rmmod
rmmod modulesname
示例:
rmmod ext4
insmod 指定模塊文件,不能自動解決依賴模塊,必須指定絕對路徑
insmod [ filename ] [ module options… ]
insmod `modinfo –n ext3`
/proc目錄
剛剛提過/proc/modules來查看內核裝載的模塊,/proc目錄我們最初的文件系統結構當中也講過,該目錄是系統與內核交互的一個偽文件系統接口,/proc下的每個文件名都是內核參數,目錄名為內核參數節點信息
/proc/sys
sysctl命令用于查看或設定此目錄中諸多參數
sysct l –a 查看當前運行中的內核所有參數及值
sysctl –w path.to.parameter=value
sysctl –w kernel.hostname=xiao.com 修改內核參數,立即生效但不能永久生效要想永久生效必須將參數寫到配置文件/etc/sysctl.conf中
echo “value”> /proc/sys/path/to/parameter
ehco “xiao” > /proc/sys/kernel/hostname
sysctl –p 通過讀取配置文件設置參數
常用的幾個參數
net.ipv4.ip_forward 路由轉發
kernel.hostname 主機名
vm.drop_caches 緩存 0為不清理緩存,1為清理緩存
net.ipvr.icmp_echo_ignore_all 0開啟ping功能,1禁止ping功能
/sys目錄
sysfs:為用戶使用的為文件系統,輸出識別出硬件設備的相關屬性信息,也有內核對硬件特性的設定信息,有些參數是可以修改的,用于調整硬件工作特性
udev通過此路徑下輸出的信息動態為各設備創建所需需設備文件,udev是運行用戶空間程序
專用工具udevadmin,hotplug
udev為設備創建設備文件時,會讀取其實現定義好的規則文件,一般在/etc/udev/rules.d及、usr/lib/udev/rules.d目錄下
ramdisk制作
ramdisk是一個虛擬的根文件系統,這個虛擬的根文件系統在/boot目錄下以init開頭的文件,他的特點是能夠通過Boot Loader程序將其將在到內存當中,然后解壓縮并在內存模擬一個根文件系統,這個根文件系統能夠提供一個可以運行的程序,通過該程序可以加載在啟動過程當中所需要的模塊如(RAID、LVM、SCSI),加載完成,會協助內核啟動/sbin/init程序來執行后續的啟動,那么如何去制作一個ramdisk呢
在CentOS5之上,是通過mkinitrd命令來進行制作,在Centos6之后用dracut命令來制作ramdisk,具體如下:
1、 為當前正在使用的內核重新制作ramdisk文件
mkinitrd命令
mkinitrd /boot/iniramfs-$(uname –r).img $(uname –r)
dracut命令
2、 制作好之后通過file命令查看initramfs文件,得知是一個gizp的要文件,使用zcat initramfs通過過管道送過cpio進行接壓縮查看里面的內容,展開之后發現其實就是一些類似根文件系統目錄結構
zcat initramfs-2.6.32-642.el6.x86_64.img | cpio -id 解開
find . | cpio -o –H newc –quiet > gzip -9 /boot/myramdisk.img 歸檔
內核編譯
首先想到的是為什么要編譯內核,我們知道內核里包含了可以讓硬件設備與軟件發揮功能的信息,如果內核里面沒有這些設備等信息,系統不會完整的工作的,那我們是不是可以一次性的將所有功能模塊編譯到內核中去,這樣就可以保持目前所有的硬件設備了,如此一來,內核文件大小也變大了不少,而且有些根本不需要的東西也編譯進來了,適得其反,所以我們是有選擇性的進行編譯,對需要的東西就行編譯。
需要編譯內核的情況有一下幾種
1、 有新的功能需求,如支持虛擬化
2、 原來的內核非常臃腫,想對內核進行簡化
3、 升級模塊修復bug用來提高穩定性
4、 定制系統
5、 純屬個人學習內核編譯使用
在編譯內核之前需要充分熟知硬件設備信息,系統平臺的相關信息,準備好軟件開發環境及內核源代碼
1. 獲取硬件設備信息
1) cpu
cat /proc/cpuinfo
lscpu
x86info –a
2) PCI
lspci
lsusb
lsblk
3) hal-device
hal
2. 開發環境準備
1) 安裝開發包組
Devlopment Tools Server Platform Development
2) 獲取源代碼
ftp上獲取內核源代碼
3) 內核功能的選擇
make menuconfig
[ ]不啟動此功能
[M]編譯成模塊
[*] 編譯成核心
注意:要保存退出,所有選定的設置會保存在.config隱藏文件中
3. 編譯內核步驟
1) 首先下載所需要的內核源代碼
通過ftp上資源進行下載
2) 解壓縮源代碼文件到指定目錄
tar xf linux-3.18.41.tar.xz -C /usr/src/
3) 將解壓縮后生成的目錄新建一個鏈接
cd /usr/src
ln -sv linux-3.18.41/ linux
4) 復制系統的內核配置模版文件到新內核目錄下(文件在/boot目錄下有一個config開頭的文件)
cp /boot/config-2.6.32-642.el6.x86_64 .
5) 選定配置
make help 獲取make命令的幫助信息
make config 遍歷每個選項
make menuconfig 打開文本串口,配置內核選項(這里需要注意的是,有些小伙伴喜歡用遠程工具如xshell這時就需要注意了窗口最好最大化,其他使用screen命令打開一個新串口,以免編譯到一遍是遠程桌面斷開)
make allnoconfig 所有選擇均不選擇,執行結果將會保存在配置文件.config中
6) 編譯
make -j # #表示數字,指多線程編譯
7) 安裝模塊
make modules_install
8) 安裝內核
make install
至此內核編譯的過程就完成了,只需要重新啟動系統,選擇自己所編譯的內核進入系統即可
編譯內核擴展
make clean :保留.config配置文件,刪除其他編譯生成的所有文件
make mrproper :刪除編譯生成的所有文件,包括.config文件
make distclean:相當于mrproper 以及刪除編譯器備份及補丁文件
make gconfig Gnome桌面環境使用,需要安裝圖形開發庫
make xconfig KDE桌面環境使用,需要安裝圖形開發庫
make defconfig 基于內核為目標平臺提供的默認配置進行配置
make allyesconfig 所有選項均回答為yes
make allnoconfig 所有選項均回答為no
1、 只編譯其中部分代碼
只編譯某個子目錄下的相關代碼
make dir/ make driver/net/
2、 只編譯部分模塊
make m=driver/net/
3、 只編譯某一個模塊
make driver/net/pcnet32.ko
4、 將編譯完成的結果放置于指定的目錄中
make o=/tmp/kernel
5、 交叉編譯
make ARCH=arch_name
獲取特定目標平臺的使用幫助
make ARCH=arch_name help
make ARCH=arm help
原創文章,作者:fszxxxks,如若轉載,請注明出處:http://www.www58058.com/45116