(轉)linux系統替換新內核(編譯安裝替換與打包替換)


 

一、簡介

內核,是一個操作系統的核心。它負責管理系統的進程、內存、設備驅動程序、文件和網絡系統,決定着系統的性能和穩定性。Linux作為一個自由軟件,在廣大愛好者的支持下,內核版本不斷更新。新的內核修訂了舊內核的bug,並增加了許多新的特性。如果用戶想要使用這些新特性,或想根據自己的系統度身定制一個更高效,更穩定的內核,就需要重新編譯內核。

本文將以kernel 3.12.5版本為實驗,操作平台為RedHat 6.2,但本文所介紹的內核編譯與安裝方法適合大多數Linux系統(包括RedHat、Ubuntu、Debian等)。

二、下載新內核源碼 

內核下載官網:https://www.kernel.org/ 
解壓內核:#tar xvf linux-3.12.5.tar.xz  /opt

進入內核源碼目錄:#cd /opt/linux-3.12.5

 

這里解壓到任何目錄都行,本人解壓到了/opt目錄下。在網上看到很多朋友解壓到/usr/src目錄下,其實這都無所謂,因為本文所講的方法並不局限於給本機新增一個內核,還有可能是給其他機器的新增內核,就算是新增本機內核那也沒關系,因為后面執行#make install 自動就會將對應文件拷貝到本機相應的目錄下去了。

注:下文所有關於顏色標注的“3.12.5”都替換成自己實際的內核版本號。

三、替換內核

本文介紹兩種替換內核方法:編譯替換內核、打包替換內核(.deb安裝包)。

(一)編譯替換內核

編譯替換內核適合所有Linux系統,也是大多數人常用的方法。

1、定制內核

#make mrproper

作用是在每次配置並重新編譯內核前需要先執行“make mrproper”命令清理源代碼樹,包括過去曾經配置的內核配置文件“.config”都將被清除。即進行新的編譯工作時將原來老的配置文件給刪除到,以免影響新的內核編譯。

即檢查有無不正確的.o文件和依賴關系,如果使用剛下載的完整的源程序包即第一次進行編譯,那么本步可以省略。而如果你多次使用了這些源程序編譯內核,則最好要先運行一下這個命令。 

 

#make menuconfig

注:使用make menuconfig 生成的內核配置文件,決定將內核的各個功能系統編譯進內核還是編譯為模塊還是不編譯。

在這里就不介紹具體的內核配置操作,但是建議就算不打算配置什么也執行一下make menuconfig這個命令,因為如果不執行此操作的話在后面make編譯內核的時候會提示你回答很多問題。

內核配置可參考:

Make menuconfig配置詳解:http://blog.csdn.net/xuyuefei1988/article/details/8635539

http://www.linuxidc.com/Linux/2012-06/63092.htm

 

配置內核還有很多其他方法,主要區別如下:

#make menuconfig        //基於ncurse庫編制的圖形工具界面

#make config         //基於文本命令行工具,不推薦使用

#make xconfig         //基於X11圖形工具界面

#make gconfig        //基於gtk+的圖形工具界面

這里選擇簡單的配置內核方法,即make menuconfig。在終端輸入make menuconfig,等待幾秒后,終端變成圖形化的內核配置界面。進行配置時,大部分選項使用其缺省值,只有一小部分需要根據不同的需要選擇。

對每一個配置選項,用戶有三種選擇,它們分別代表的含義如下:

<*>或[*]——將該功能編譯進內核

[ ]——不將該功能編譯進內核

[M]——將該功能編譯成可以在需要時動態插入到內核中的代碼

2、編譯安裝內核和模塊

(1)  拷貝.confg文件:

執行#cp /boot/config-,然后按下Tab鍵,系統會自動填上該目錄下符合條件的文件名,然后繼續輸入 .config,目的是使用在boot目錄下的原配置文件。

不執行這一步的話,后面make的時候會提示找不到.confg文件。

如果在上一步配置了內核的話應該是會自動生成.config文件,但這里本人只是執行了一次#make menuconfig命令並沒有配置內核。

(2)   建立編譯時所需的從屬文件:

#make dep

根據上一步所選擇的選項,建立文件的依賴關系。

(3)  清除內核編譯的目標文件 :

#make clean

清理一些不必要的文件,如果你在上次編譯的基礎上,刪去了一些選項,建議你執行這一步操作,否則,就沒有必要了。

(4)  編譯安裝內核和模塊:

【本機替換內核】

1)編譯內核和模塊:

       #make –j4

生成內核模塊和vmlinuz,initrd.img,Symtem.map文件。

注:#make相當於分別執行#make bzImage 和#make modules,由於是本機替換內核,所以無需分開執行。

這一步所需的時間較長,為了加快編譯速度,我們可以加上“-j”選項,后面跟的數字是jobsnum ,建議設置為 CPU 核心數 + 1,jobsnum值可以由命令” cat /proc/cpuinfo |sed -n '/^processor/p' |wc -l”獲得。

2)安裝模塊:

#makemodules_install

編譯成功后,系統會在/lib/modules目錄下生成一個3.12.5子目錄,里面存放着新內核的所有可加載模塊(即將編譯好的modules拷貝到/lib/modules下)。

3)安裝內核:

#makeinstall

即復制.config,vmlinuz,initrd.img,System.map文件到/boot目錄、更新grub。對於RedHat系統以下三個grub文件自動會更新,默認啟動新內核。

/etc/grub.conf

/boot/grub/menu.lst

/boot/grub/grub.conf

注:前兩個配置文件是第三個的軟連接。

Ubutun和Debian系統是/boot/grub/grub.conf文件。

       4)重啟系統:

              #reboot

 

       【非本機替換內核】

在這里也可以像本機替換內核一樣直接執行#make,但本文將編譯內核和編譯模塊分開來執行,但原理和結果是一樣的。

1)編譯內核:

       #make bzImage

內核編譯成功后,會在源碼樹根目錄即linux-3.12.5/arch/x86_64/boot/目錄中生成一個新內核的映像文件bzImage。

注:對於大內核(比如需要SCSI支持),make bzImage (推薦)

對於小內核,make zImage。

       2)編譯模塊:

       #make modules

                   編譯可加載模塊(即內核選項中選擇為M的選項),以便將來使用insmod命令進行加載。編譯時間跟M選項的數量有關。 

3)安裝模塊:

#make modules_install

       即將編譯好的modules拷貝到/lib/modules下。

4)安裝內核:

       由於不是本機替換內核,所以我們需要將新生成的內核文件拷貝到要替換內核的機器上。需要拷貝的內核文件為主要有4個,分別是:.config,bzImage,System.map 和系統/lib/modules/linux-3.12.5目錄。

具體操作如下:

(1)將生成的linux-3.12.5/.config 拷貝到要替換內核系統的/boot下,並重命名為config-3.12.5

(2)將生成的linux-3.12.5/arch/x86-64/boot/bzImage 拷貝到要替換內核系統的/boot下,並重命名為vmlinuz-3.12.5(注:這里需特別注意拷貝后的文件名變為vmlinuz-x.x.x)。

(3)將生成的linux-3.12.5/System.map 拷貝到要替換內核系統的/boot下,並重命名為System.map-3.12.5

(4)將make modules_install生成的系統目錄/lib/modules/linux-3.12.5 拷貝到要替換內核系統的/lib/modules下。

(5)在要替換新內核的系統的/lib/modules目錄下執行以下命令:

        #update-initramfs-c -k3.12.5,生成/boot/initrd.img-3.12.5

#update-grub(或#update-grub2), 更新啟動加載文件。

      注:RedHat系統貌似是沒有以上兩個更新命令,所以以上更新內核方法適合Ubuntu或Debian系統。

       那RedHat系統怎么更新內核呢?建議使用上一種【本機替換內核】方法直接make install安裝,使用【非本機替換內核】方法不太方便,但這里也做一個介紹,我們可以手動更新內核啟動文件。(當然你也可以手動下載一個grub安裝包並安裝,再使用update-grub)。

具體如下(將第(5)步替換成下面操作):

RedHat系統中有三個配置文件/etc/grub.conf;/boot/grub/menu.lst;/boot/grub/grub.conf

前兩個都是第三個的連接,所以我們只需要修改/boot/grub/grub.conf啟動配置文件即可。

內容如下:

title 顯示在啟動菜單上的名稱

root 根文件系統掛載分區,根據自身系統而定,可以仿照舊版本內核填寫。

kernel 壓縮過的內核文件名

initrd 根文件系統文件名

     如:

       titleMy new kernel

         root (hd0,0)

            kernel/boot/vmlinuz-x.y.z

            initrd/boot/initrd-x.y.z.img

      

       在紅帽系統上直接修改grub啟動文件的方法本人沒有親試,這部分內容是參照文章http://wenku.baidu.com/view/cb16a8fdc8d376eeaeaa3126.html所寫的,具體的可以看原文。

       本人系統的/boot/grub/grub.conf中新增內核內容如下:

              title Red Hat Enterprise LinuxServer (3.12.5)

              root (hd0,0)

              kernel /vmlinuz-3.12.5 orroot=/dev/……

              initrd /initramfs-3.12.5.img

 

然后重新生成ram磁盤:

如果您的系統中的/etc/lilo.conf沒有使用了ram磁盤選項initrd,略過

如果您的系統中的/etc/lilo.conf使用了ram磁盤選項initrd,

使用mkinitrd initrd-內核版本號 內核版本號命令重新生成ram磁盤文件,例如我的Redhat 6.2:

mkinitrd initrd-3.12.5 3.12.5

之后把/etc/lilo.conf中的initrd指向新生成的initrd-3.12.5文件:

initrd=/boot/initrd-3.12.5

 

ram磁盤能使系統性能盡可能的優化,具體參考/usr/src/linux/Documents/initrd.txt文件

5)重啟系統:

       #reboot

3、幾個重要的Linux內核文件介紹

(1).config

使用make menuconfig 生成的內核配置文件,決定將內核的各個功能系統編譯進內核還是編譯為模塊還是不編譯。

(2)vmlinuz 和 vmlinux

vmlinuz是可引導的、壓縮的內核,“vm”代表“Virtual Memory”。Linux 支持虛擬內存,不像老的操作系統比如DOS有640KB內存的限制,Linux能夠使用硬盤空間作為虛擬內存,因此得名“vm”。

vmlinuz是可執行的Linux內核,vmlinuz的建立有兩種方式:

一是編譯內核時通過“make zImage”創建,zImage適用於小內核的情況,它的存在是為了向后的兼容性;

二是內核編譯時通過命令make bzImage創建,bzImage是壓縮的內核映像,需要注意,bzImage不是用bzip2壓縮的,bzImage中的bz容易引起誤解,bz表示“big zImage”,bzImage中的b是“big”意思。 zImage(vmlinuz)和bzImage(vmlinuz)都是用gzip壓縮的。它們不僅是一個壓縮文件,而且在這兩個文件的開頭部分內嵌有gzip解壓縮代碼,所以你不能用gunzip 或 gzip –dc解包vmlinuz。內核文件中包含一個微型的gzip用於解壓縮內核並引導它。兩者的不同之處在於,老的zImage解壓縮內核到低端內存(第一個640K),bzImage解壓縮內核到高端內存(1M以上)。如果內核比較小,那么可以采用zImage 或bzImage之一,兩種方式引導的系統運行時是相同的。大的內核采用bzImage,不能采用zImage。 vmlinux是未壓縮的內核,vmlinuz是vmlinux的壓縮文件。

(3)initrd.img

initrd是“initial ramdisk”的簡寫。

initrd一般被用來臨時的引導硬件到實際內核vmlinuz能夠接管並繼續引導的狀態。比如initrd- 2.4.7-10.img主要是用於加載ext3等文件系統及scsi設備的驅動。如果你使用的是scsi硬盤,而內核vmlinuz中並沒有這個 scsi硬件的驅動,那么在裝入scsi模塊之前,內核不能加載根文件系統,但scsi模塊存儲在根文件系統的/lib/modules下。為了解決這個問題,可以引導一個能夠讀實際內核的initrd內核並用initrd修正scsi引導問題,initrd-2.4.7-10.img是用gzip壓縮的文件。initrd映象文件是使用mkinitrd創建的,mkinitrd實用程序能夠創建initrd映象文件,這個命令是RedHat專有的,其它Linux發行版或許有相應的命令。這是個很方便的實用程序。具體情況請看幫助:man mkinitrd

(4)System.map是一個特定內核的內核符號表,由“nm vmlinux”產生並且不相關的符號被濾出。
下面幾行來自/usr/src/linux-2.4/Makefile:

nm vmlinux | grep-v '(compiled)|(.o

)|([aUw])|(..ng

)|(LASH[RL]DI)' | sort >System.map 

 

在進行程序設計時,會命名一些變量名或函數名之類的符號。Linux內核是一個很復雜的代碼塊,有許許多多的全局符號, Linux內核不使用符號名,而是通過變量或函數的地址來識別變量或函數名,比如不是使用size_t BytesRead這樣的符號,而是像c0343f20這樣引用這個變量。 對於使用計算機的人來說,更喜歡使用那些像size_t BytesRead這樣的名字,而不喜歡像c0343f20這樣的名字。內核主要是用c寫的,所以編譯器/連接器允許我們編碼時使用符號名,而內核運行時使用地址。 然而,在有的情況下,我們需要知道符號的地址,或者需要知道地址對應的符號,這由符號表來完成,符號表是所有符號連同它們的地址的列表。

Linux 符號表使用到2個文件: /proc/ksyms  、System.map 。/proc/ksyms是一個“proc  file”,在內核引導時創建。實際上,它並不真正的是一個文件,它只不過是內核數據的表示,卻給人們是一個磁盤文件的假象,這從它的文件大小是0可以看 出來。然而,System.map是存在於你的文件系統上的實際文件。當你編譯一個新內核時,各個符號名的地址要發生變化,你的老的System.map 具有的是錯誤的符號信息,每次內核編譯時產生一個新的System.map,你應當用新的System.map來取代老的System.map。 

雖然內核本身並不真正使用System.map,但其它程序比如klogd, lsof和ps等軟件需要一個正確的System.map。如果你使用錯誤的或沒有System.map,klogd的輸出將是不可靠的,這對於排除程序故障會帶來困難。沒有System.map,你可能會面臨一些令人煩惱的提示信息。 另外少數驅動需要System.map來解析符號,沒有為你當前運行的特定內核創建的System.map它們就不能正常工作。 Linux的內核日志守護進程klogd為了執行名稱-地址解析,klogd需要使用System.map。System.map應當放在使用它的軟件能夠找到它的地方。執行:man klogd可知,如果沒有將System.map作為一個變量的位置給klogd,那么它將按照下面的順序,在三個地方查找System.map: /boot/System.map 、/System.map、/usr/src/linux/System.map 

System.map也有版本信息,klogd能夠智能地查找正確的映象(map)文件。

(二)打包替換內核

打包替換新內核使用的是make-kpkg命令,所以此方法只適合支持make-kpkg命令的系統版本,一般適合Ubuntu、Debian等系統,不適合RedHat系統。

1、定制內核

#make mrprobe ,清理源代碼樹。

#make menuconfig ,配置內核。

2、打包內核

(1)拷貝.confg文件:

執行#cp /boot/config-,然后按下Tab鍵,系統會自動填上該目錄下符合條件的文件名,然后繼續輸入 .config,目的是使用在boot目錄下的原配置文件。

不執行這一步的話,后面make的時候會提示找不到.confg文件。

如果在上一步配置了內核的話應該是會自動生成.config文件,但這里本人只是執行了一次#make menuconfig命令並沒有配置內核。

(2)編譯打包內核

#make-kpkg --initrd  - -append-to-version=-pyh  - -revision=zxxiong.0716 -j 4kernel_image kernel_headers

         執行完以上命令后將在上一級目錄生成兩個.deb包:

頭文件包:linux-headers-3.12.5-pyh_zxxiong.0716_amd64.deb

       內核包:linux-image-3.12.5-pyh_zxxiong.0716_amd64.deb

      

【--initrd】選項會讓make-kpkg自動幫我們生成initramfs;

【--revision】會給生成的deb文件加上一個版本信息。這個參數只是影響到文件名,如果不指定,默認會是“10.00.Custom”;

【--append-to-version】也是一種版本信息,它不僅出現在deb安裝包的文件名里,也會影響到kernel的名稱,比如本例中,內核更新完成之后,用“uname -r”察看會得到“3.12.5-pyh”;

【kernel_image】表示生成內核和默認模塊的安裝包。

【kernel_headers】這樣make-kpkg會生成一個內核頭文件的安裝包。

如果我們用普通用戶來執行make-kpkg,需要加上fakeroot運行

#fakeroot make-kpkg --initrd  - -append-to-version=-pyh  - -revision=zxxiong.0716 -j 4 kernel_image kernel_headers

 

(注:需要設置平台 如-amd64在這里配置文件已經默認配置了,所以這里不用加,選項kernel_image是生成內核.deb包,選項kernel_headers是生成頭文件.deb包,這兩個選項可以只使用一個)

(3)安裝內核

       將上面生成的.deb包拷貝到需要替換內核的機器上,執行以下命令:

#dpkg –i linux-headers-3.12.5-pyh_zxxiong.0716_amd64.deblinux-image-3.12.5-pyh_zxxiong.0716_amd64.deb   (接上一行)

或者直接在deb包所在目錄執行:#dpkg –i ./*.deb

 

       執行命令之后則會自動更新/boot目錄下的文件(即自動執行命令:# update-initramfs -c -k3.12.5 和#update-grub2),然后重啟系統並選定加載的內核就可以了,還可以修改/boot/grub/grub.cfg配置文件中的 set default=”0”, 默認為0,安裝完后查看該文件新加載的內核是第幾項就設置為幾(從0開始),這樣則不需要在開機時選擇啟動第幾項了。

(5)  重啟系統

#reboot

 

 

本文參考資料:

1、http://blog.csdn.net/cdsnmdl/article/details/3922513

2、http://blog.chinaunix.net/uid-26497520-id-3593098.html

 

 注:如果覺得此文對您有所幫助,希望能鑒於博主打字的辛苦給個評論。當然更希望有錯誤之處能夠指正。

警告:轉載請標明出處 http://blog.csdn.net/star_xiong/article/details/17357821


免責聲明!

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



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