Linux基礎教程之內核編譯以及自制Linux系統
內核編譯
單內核體系設計、但充分借鑒了微內核設計體系的優點,為內核引入模塊化機制。
內核組成部分:
kernel: 內核核心,一般為bzImage,通常在/boot目錄下,名稱為vmlinuz-VERSION-RELEASE;
kernel object: 內核對象,一般放置于/lib/modules/VERSION-RELEASE/
[ ]: None
[M]: 表示模塊化安裝
[*]: 表示打到內核核心
輔助文件: ramdisk
initrd
initramfs
運行中的內核:
uname命令:
uname – print system information
uname[OPTION]…
-n: 顯示節點名稱;
-r: 顯示VERSION-RELEASE;
-a:顯示所有信息
lsmod命令:
顯示由核心已經裝載的內核模塊
顯示的內容來自于: /proc/modules文件
示例:可以看見已經加載的模塊
modinfo命令:
顯示模塊的詳細描述信息
modinfo[ -k kernel ] [ modulename|filename… ]
-n: 只顯示模塊文件路徑
-p: 顯示模塊參數
-a: author
-d: description
-l: license
示例:顯示模塊的詳細信息
modprobe命令:
裝載或卸載內核模塊
modprobe [ -C config-file ] [ modulename] [ module parame-ters… ] 安裝內核
配置文件:/etc/modprobe.conf, /etc/modprobe.d/*.conf
modprobe [ -r ] modulename… 卸載內核模塊
示例1:卸載網卡驅動,然后發現沒有eth那些網卡配置信息了
示例2:加載網卡驅動
depmod命令:
內核模塊依賴關系文件及系統信息映射文件的生成工具
裝載或卸載內核模塊:
insmod命令:指定模塊文件,不自動解決依賴模塊
insmod[ filename ] [ module options… ]
insmod`modinfo–n exportfs`
lnsmod`modinfo–n xfs`
rmmod
rmmod[ modulename]
rmmod xfs
rmmod exportfs
內核相關目錄
/proc目錄:
內核把自己內部狀態信息及統計信息,以及可配置參數通過proc偽文件系統加以輸出
參數:只讀:輸出信息
可寫:可接受用戶指定“新值”來實現對內核某功能或特性的配置
/proc/sys
(1) sysctl命令用于查看或設定此目錄中諸多參數
sysctl-w path.to.parameter=VALUE
sysctl-w kernel.hostname=mail.magedu.com
(2) echo命令通過重定向方式也可以修改大多數參數的值
echo “VALUE” > /proc/sys/path/to/parameter
echo “websrv” > /proc/sys/kernel/hostname
/sys目錄:
sysfs:為用戶使用的偽文件系統,輸出內核識別出的各硬件設備的相關屬性信息,也有內核對硬件特性的設定信息;有些參數是可以修改的,用于調整硬件工作特性。
udev通過此路徑下輸出的信息動態為各設備創建所需要設備文件,udev是運行用戶空間程序
專用工具:udevadmin, hotplug
udev為設備創建設備文件時,會讀取其事先定義好的規則文件,一般在/etc/udev/rules.d及/usr/lib/udev/rules.d目錄下
sysctl命令:
默認配置文件:/etc/sysctl.conf
(1) 設置某參數
sysctl-w parameter=VALUE
(2) 通過讀取配置文件設置參數
sysctl-p [/path/to/conf_file]
內核中的路由轉發:
/proc/sys/net/ipv4/ip_forward
常用的幾個參數:
net.ipv4.ip_forward
net.ipv4.icmp_echo_ignore_all
vm.drop_caches
ramdisk文件的制作:
(1) mkinitrd命令????為當前正在使用的內核重新制作ramdisk文件
mkinitrd /boot/initramfs-$(uname-r).img $(uname-r)
(2) dracut命令????為當前正在使用的內核重新制作ramdisk文件
dracut /boot/initramfs-$(uname-r).img $(uname-r)
示例:假如initramfs文件丟失,恢復之
刪除initramfs文件,然后重啟
會發現已經登陸不進去系統
此時進入救援模式運行進行修復
修復完畢,重啟,會發現SELinux在檢查,稍等即可進入系統
編譯內核
前提:
(1) 準備好開發環境
(2) 獲取目標主機上硬件設備的相關信息
(3) 獲取目標主機系統功能的相關信息
例如:需要啟用相應的文件系統
(4) 獲取內核源代碼包
www.kernel.org
開發環境準備
包組(CentOS 6):
Server Platform Development
Development Tools
目標主機硬件設備相關信息:
CPU:
# cat /proc/cpuinfo
# x86info -a
# lscpu
硬件設備
PCI設備:
lspci
-v
-vv
lsusb
-v
-vv
lsblk ?塊設備
了解全部硬件設備信息
hal-device
內核編譯安裝系統
安裝開發包組
下載源碼文件
.config:準備文本配置文件
make menuconfig:配置內核選項
make [-j #]
make modules_install:安裝模塊
make install :安裝內核相關文件
安裝bzImage為/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
編輯grub的配置文件
(1) 配置內核選項
支持“更新”模式進行配置:make help
(a) make config:基于命令行以遍歷的方式去配置內核中可配置的每個選項
(b) make menuconfig:基于curses的文本窗口界面
(c) make gconfig:基于GTK (GNOME)環境窗口界面
(d) make xconfig:基于QT(KDE)環境的窗口界面
支持“全新配置”模式進行配置
(a) make defconfig:基于內核為目標平臺提供的“默認”配置進行配置
(b) make allyesconfig: 所有選項均回答為“yes“
(c) make allnoconfig: 所有選項均回答為”no“
(2) 編譯
全編譯:make [-j #]
編譯內核的一部分功能:
(a) 只編譯某子目錄中的相關代碼:
# cd /usr/src/Linux
# make dir/
(b) 只編譯一個特定的模塊:
# cd /usr/src/Linux
# make dir/file.ko
例如:只為e1000編譯驅動:
# make drivers/net/ethernet/intel/e1000/e1000.ko
如何交叉編譯內核:
編譯的目標平臺與當前平臺不相同才需要交叉編譯
# make ARCH=arch_name
要獲取特定目標平臺的使用幫助
# make ARCH=arch_namehelp
# make ARCH=arm help
在已經執行過編譯操作的內核源碼樹做重新編譯:
需要事先清理操作:
# make clean:清理大多數編譯生成的文件,但會保留config文件等
# make mrproper: 清理所有編譯生成的文件、config及某些備份文件
# make distclean:mrproper、patches以及編輯器備份文件
示例:簡單Linux kernel內核編譯過程
首先提示,此處用虛擬的同學,盡量把虛擬機的核心數量調大一點,跟實際的主機一樣就可以了,此處操作只是為了加快編譯的時間,編譯的時候會消耗大量的cpu資源,如果想繼續做其他操作的小伙伴,可以忽略此處
在系統里面可以查看到當前系統的核心數量
進行內核操作,請自備Linux內核。而且編譯內核以前,請做好備份,編譯內核的主版本,請盡可能跟原有的內核版本相近,因為直接采用最新的內核版本,有可能會導致系統崩潰。
此處內核可以到www.kernel.org下載
此次實驗我們用的是Linux-3.18.41版本的內核,當前系統是3.10.0的版本的內核
/usr/scr/kernels,此處目錄是存放內核文件的地方,現在只有一個3.10版本的內核
解壓新的內核到/usr/src目錄下面
創建Linux-3.18-41的軟連接目錄Linux,此處的操作是為了后面的操作每次都需要內核版本號,一旦輸入錯誤的話,就又得重來了(編譯兩小時,報錯5秒鐘)
復制原有系統的/boot/config-3.10.0-327.el7.x86_64的文件到/usr/src/Linux目錄下面為.config的文件
運行make menuconfig命令來配置內核選項,如果此處有報錯的話,例如下圖,表明一些編譯內核的工具還沒有安裝,此處我們通過yum倉庫來安裝一下相關的文件,此處除了報錯的curses.h的文件以外,還有
Server Platform Development、Development Tools等工具是必須要安裝的,編譯以前需要查看一下工具是否都已經安裝完畢。
安裝完相關的工具以后,重新運行make menuconfig命令
此時我們已經可以正常進入編輯內核選項的圖形化界面,在這里我們可以選擇我們需要的內核功能
例如此處可以編譯內核的名字,像本機內核的3.10.0-327.el7.x86_64后面的-327.el7.x86_64就是在此處編輯
例如我們可以定義為-1.0_wanLinux
再看看其他功能,比如此處可以選擇windows的文件系統
可以看見有一個NTFS文件系統支持的選擇
按空格鍵可以選中此功能,此處的M表示以模塊化的方式來安裝此文件驅動,這樣的話在系統的 modules文件夾里面即可以查找到這個文件
再多按一次空格健會編程一個*,表示直接把此集成到內核里面,在系統里面運行的話是看不到此文件的
當選擇好那些我們需要內核參數以后,就可以選擇此處的保存
默認保存.config的文件
上面的步驟準備好以后,輸入make -j 4開始編譯,此處的-j 4表示指定cpu的數量,因為我這里核心數量是4,輸入完以后,內核就開始編譯了,此處需要等待很長的時間
編譯完以后/lib/modules并不會馬上生成內核的文件
此時回去/usr/src/Linux目錄下面運行make modules_install安裝內核模塊
上面的運行完以后,我們可以看見/lib/modules目錄下面會多一個3.18.41的內核文件,查看一下該目錄,居然有7G多,所以小伙伴們編譯的時候注意看一下磁盤的空間容量。
再運行make install安裝內核相關文件
安裝bzImage為/boot/vmlinuz-VERSION-RELEASE
生成initramfs文件
然后會發現/boot目錄下面多了內核3.18.41的文件
進入/boot/grub2/目錄下面查看grub.cfg文件
可以看見grub里面已經有3.18.41內核的加載選項
重啟電腦看看,可以發現有3.18.41內核的啟動選項
此時可以正常登陸進來,表示安裝新的內核成功。
自制Linux示例
此處只是利用現有的Linux系統文件來創建一個簡單的Linux系統,還缺乏許多功能
首先準備一個空的磁盤,這里實驗使用一個虛擬機的磁盤
分區并創建文件系統
fdisk/dev/sdb
分兩個必要的分區
/dev/sdb1對應/boot /dev/sdb2對應根/
mkfs.ext4 /dev/sdb1 mkfs.ext4 /dev/sdb2
掛載boot
mount /dev/sdb1 /mnt/boot
安裝grub
grub-install /dev/sdb?–root-directory=/mnt
安裝完grub以后可以查看一下sdb的mbr信息是否正常
恢復內核和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
建立grub.conf:
vim /mnt/boot/grub/grub.conf
title Hello_Linux
root (hd0,0)
kernel /vmlinuz-2.6.32-642.el6.x86_64 root=/dev/sda2 seLinux=0 init=/bin/bash
initrd /initramfs-2.6.32-642.el6.x86_64.img
創建一級目錄
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}
創建/etc/fstab掛載文件
復制bash和相關庫文件,這個是必須的
復制相關命令及相關庫文件,如:ls,cat,vim,reboot,hostname,mount,umount,tree等,非必須,但是最好還是安裝上,這些小命令部分能在小Linux上面跑,有些不能,因為系統文件并不是很全
注意:此處的copycmd.sh是自己編寫的腳本,內容就是復制bash和ls之類這些相關的文件到/sysroot下面,當然,此處也可以自行一個一個復制,只是比較麻煩
復制完可以看見bin和lib64等等目錄下面多了許多相關文件
復制完相關的文件,我們可以用chroot命令來切根試試能不能正常進入,如果可以的話,應該問題就不大,完成此步驟以后就可以關機了
現在我們新建一個虛擬機測試一下剛那塊虛擬磁盤里面的系統看是否能正常運行
虛擬機里面需要使用一塊現有的虛擬硬盤,其他的配置就跟平時創建虛擬機一樣即可
配置完虛擬機以后,開機!
此時可以看見登陸的界面了!
正常進入到系統了!界面有點像救援模式,(當然此處可以把自制的小Linux系統安裝到u盤里面當成系統盤運行,就像windows老毛桃pe之類的)
在里面測試了一下之前復制的命令,有些可以,有些不可以,此處實驗完畢。