Ubuntu20.04linux內核(5.4.0版本)編譯準備與實現過程-編譯過程(2)

   前面因為博客園維修,所以內核編譯過程一直沒有發出來,現在把整個內核過程分享出來。本隨筆給出內核的編譯實現過程,在編譯前需要參照我前面一篇隨筆:

Ubuntu20.04linux內核(5.4.0版本)編譯準備與實現過程-編譯前準備(1) ://www.cnblogs.com/iFrank/p/14556664.html

  切記:注意一點需要參照前一篇隨筆,不然編譯過程十有八九出問題。

開發環境

  Ubuntu20.04(ubuntu-20.04.2-live-server-amd64.iso)

  系統自帶的內核版本:5.4.0-67-generic(上篇隨筆的內核版本為5.4.0-42-generic,但是-67版本與-42具體操作一樣)

編譯過程

  準備工作做完,接下來就要編譯內核了。這個編譯其實也分了好幾個大的步驟,下面首先介紹第一步配置。

  原則上來講,內核需要配置的項非常多,而且很多涉及到了一般讀者並不太熟悉的硬件細節。這樣一來,稍不留神就會導致配錯項,而這個錯誤往往是在編譯內核時才暴露出來,非常耽誤時間。可能大家花費幾天甚至十幾天的時間都不能編譯成功,原因就在於諸多的配置項把自己卡住了。鑒於這種情況,我建議直接使用系統內核已有的配置文件.config,直接使用不容易報錯,但是短板也是對應的-只能編譯系統已有的內核版本,比如我只能編譯5.4.0系列的內核版本,但是在學習過程,這樣是非常方便的,系統在安裝過程中,就已經根據當前的硬件環境做出了選擇。直接拿來用就可以了,非常省事。

  首先把該配置文件,複製到下載並解壓好的內核源碼目錄中,比如本機環境的/home/frank/Desktop/linux-5.4。前面提到,下載的內核源碼版本是5.4.0,和當前系統所用的內核版本一致。其原因就在這裡,可以非常方便地直接使用系統自帶的內核配置文件。注意,在複製配置文件/boot/config-5.4.0-67-generic的同時,需要將其更名為.config,執行下面命令:

1  sudo cp /boot/config-5.4.0-67-generic .config

  前面提到過使用內核命令行參數,禁止內核地址隨機化。其實也可以在.config文件中,注釋掉CONFIG_RANDOMIZE_BASE配置項以實現禁用的目的。這之後,可以執行命令「make menuconfig」,在圖形界面中對.config文件進行配置,按默認的配置就行(kgdb也默認配置好了),直接選擇load,選擇保存退出即可。

  配置好了以後,先不着急編譯。我們需要改一改內核的Makefile文件(即頂層Makefile文件),以去優化編譯內核。我們編譯內核的目的是為了調試,而優化很多時候會影響調試。比如代碼的順序被改變了,某個變量被優化掉了等等,這常常導致源碼和實際運行情況不一致。如何解決?直接修改內核的Makefile文件,我的環境中為/home/frank/Desktop/linux-5.4/Makefile,將其中的-O2優化級別全部替換成-O1(總共有三處)。既然去優化,為什麼不直接改成-O0呢?答案很簡單,改成-O0或者-Og,後面編譯過不了。能降低一點優化級別,也是好的。

  雖然頂層Makefile文件中不能將優化級別變成-O0,但是有可能把某個模塊的優化級別降成-O0。比如,當我們需要調試研究某一個模塊時,可以在該模塊自己的Makefile文件中加入-O0。但是,這個做法並不能保證適合於每一個模塊。

  去優化完成之後,我們就可以開始真正編譯了。命令也十分簡單:

1 sudo make-kpkg --initrd kernel-headers kernel_image

  我在運行過程中,遇到了簽名問題報錯:

1 make[2]: *** No rule to make target 'debian/certs/[email protected]', needed by 'certs/x509_certificate_list'。 停止。
2 Makefile:988: recipe for target 'certs' failed
3 make[1]: *** [certs] Error 2
4 make[1]: Leaving directory '/home/sakura/linux-4.10.12'
5 debian/ruleset/targets/common.mk:295: recipe for target 'debian/stamp/build/kernel' failed
6 make: *** [debian/stamp/build/kernel] Error 2

  需要重新複製/boot/config-5.4.0-67-generic,修改名.config,然後直接修改.config文件,之後重新注釋掉CONFIG_RANDOMIZE_BASE配置項,隨後執行下面操作:

1 把CONFIG_MODULE_SIG_ALL,
2 CONFIG_MODULE_SIG_KEY
3 和CONFIG_SYSTEM_TRUSTED_KEYS三項注釋掉,編譯時系統會自動生成一次性密鑰來加密,
4 另外記得把CONFIG_DEBUG_INFO=y去掉

  .config配置好之後,重新執行make menuconfig命令,選擇load,然後保存即可,隨後在當前目錄輸入:

1 sudo make-kpkg --initrd kernel-headers kernel_image

  如果沒有報錯就會進行內核編譯,耐心等待較長時間後(約3-5小時),會在前一級目錄生成兩個deb文件:

1 linux-headers-5.4.0_5.4.0-10.00.Custom_amd64.deb
 
2 linux-image-5.4.0_5.4.0-10.00.Custom_amd64.deb

  兩個deb文件位於/home/frank/Desktop目錄下。之後在此目錄下直接執行下面命令,進行安裝就可以了:

1 dpkg -i *.deb

  到此為止,內核就編譯完成了。不過,ubuntu 20.04默認情況下,開機是看不到grub界面的,也就無法選擇進入新編譯好的內核。所以,此時還得修改一個/etc/default/grub文件。將其中的「GRUB_TIMEOUT_STYLE=hidden」注釋掉,以顯示grub界面;並且將GRUB_TIMEOUT修改成「GRUB_TIMEOUT = 10」,以留出10秒時間讓用戶選擇進入哪個內核:

  同樣,最後還需要執行update-grub命令,並重啟系統。

  為了便於大家進行內核編譯,下面總結性地列出了主要步驟:

第一步:將下載的內核源碼5.4.0,解壓於目錄~/Desktop/linux-5.4中。並假設該目錄,就是當前工作目錄(即執行pwd命令,將得到路徑~/Desktop/linux-5.4);

第二步:# cp /boot/config-5.4.0-67-generic .config;

第三步:# sudo vim .config,注釋掉CONFIG_RANDOMIZE_BASE;

第四步:# make menuconfig,選擇load,隨即保存即可;

第五步:去優化編譯,將頂層Makefile中的-O2,改成-O1(總共有三處);

第六步:# sudo make-kpkg --initrd kernel-headers kernel_image;

第七步:# cd ../,回到上級目錄,即~/Desktop;
       # dpkg -i *.deb,安裝生成的兩個deb文件;

第八步:修改/etc/default/grub,注釋掉「GRUB_TIMEOUT_STYLE=hidden」,並設置等待時間GRUB_TIMEOUT = 10。

第九步:# update-grub
       # reboot

編譯完成,重新啟動選擇內核版本

  選擇5.4.0版本內核,具體過程如下: