一、實驗環境
Vmware15.5, Ubuntu18.04, linux-5.6.14內核(以這個環境為例)
二、准備工作
1. 安裝好虛擬機,安裝Ubuntu系統。(本次實驗用的是虛擬機沒有用雙系統,因為實驗中有一要求是實現文件交互,所以采用虛擬機,稍后也會下載相應工具)
(另外,如果電腦配置夠的話,可以將虛擬機配置高端一點,因為后面 make 這個步驟很花時間。)
2. 下載linux-5.6.14內核(https://www.kernel.org/)(linux內核官網,下載壓縮包tarball即可)

3. 現在我們就需要下載VMware Tools,一個可以將文件從主機拖入客戶機的工具。(因為目前虛擬機掛起狀態,所以它不可選)

4. VMware Tools下載完成之后,會有一個CD圖標。然后我們進入所在路徑 /media,可以將壓縮包拖入桌面,進行解壓。
解壓命令:sudo tar -zxvf VMware Tools-...... (直接用Tab鍵補全文件名稱以免出錯)

解壓完成后,進入/vmware-tools-distrib路徑,后執行命令 sudo ./vmware-install.pl 開始安裝,一路回車。

因為我已經安裝過,就不再截圖演示。如果安裝出現問題,可以自行百度。
安裝完成后,重啟虛擬機。
5. 現在我們可以將下載的linux-5.6.14壓縮包拖入虛擬機。若不能拖入則說明VMware Tools安裝出問題。
拖入后,執行命令 sudo mv linux-5.6.14.tar.xz /usr/src 然后進入/usr/src路徑,執行命令 sudo tar -xvf linux-5.6.14.tar.xz
就可看到生成linux-5.6.14文件夾。

到此我們的准備工作就完成了。
三、實驗過程
(實驗過程我以root用戶進行,通過命令 su 就可進入 root用戶。如果報錯有可能是沒有設置密碼,輸入 sudo passwd,設置密碼即可)
我們先來看一下默認的內核。在終端輸入 uname -a。(這個是重裝虛擬機之前的圖,所以虛擬機、用戶名稱不一樣。無傷大雅)

下來我們開始編譯自己的內核:
1. cd linux-5.6.14,進入該路徑。我們通過 make 來編譯內核,所以我們需要環境和依賴。
1. apt install gcc
2. apt install make
3. apt install gcc make libncurses5-dev openssl libssl-dev
4. apt install pkg-config
5. apt install bison
6. apt install flex
7. apt install libelf-dev
安裝完成我們就可以進行下一步工作。執行命令 make nconfig ,進入下面界面(如果make nconfig過程中報錯,按照錯誤提示安裝相應依賴即可)。

我們將內核名稱自行命名。進入 General setup ,修改 Local version。修改完成后保存(此處會保存為.config),后退出。

在此步驟做一點說明,此處我們僅修改了名稱,別的選項都是默認。因為選項設置麻煩,所以不做說明,但這會導致下一步
make的時候比較費時間。可以自行在網上找簡潔的 .config 文件,將文件拷到虛擬機即可。
2. 好了, .config 文件我們已經完成了。下一步就開始 make。執行命令 make -j4 (4個線程跑,會快很多。-j4 是可選項,取決於
你的虛擬機配置)。這一步驟需要 3h 左右(我第一次跑三小時,后來4線程跑一個多小時。這個過程會有 warning 內存過大,
這個不用管,注意warning信息,如果需要可以暫停更改環境配置)。
3. 經過漫長的等待,make 這步終於完成了。然后執行命令 make modules_install 。
4. 執行命令 make install。完成后重啟虛擬機。

好啦。到此內核編譯就完成了。我們開始內核引導,必須要看到屬於自己的內核~
重啟過后,終端執行 cd /boot/ 。System.map - * 就是要用的東西。
執行命令 sudo update initramfs -c -k 5.6.1418130500337-ssc (這里用你的文件名稱替換哦!)

完成后執行命令 sudo update-grub 。會生成一個.img文件,這是由內核源碼生成的內核鏡像。
我們需要修改grub,執行命令 cd /boot/grub/ ,修改 grub.cfg文件。執行命令 sudo vim grub.cfg


到這里就已經修改完成了。重啟虛擬機。
再次進入執行命令 uname -a , 便可看到自己的內核。

四、總結與心得
這里說一下對內核的一些了解。ubuntu = kernel + users application + shell,是一個介於一般程序與硬件之間的東西。
比如c語言中的 printf(), 就是 printf() -> c庫中的printf() -> c庫中的write() -> kernel中的 write()。
下一篇是打算是關於系統調用,這也是實驗內容之一。
實驗的完成也是磕磕絆絆,所有的失敗都歸結於錯誤的開始。因為這是幾天前完成的實驗,我沒有保留
完整的實驗現場,所以中間內容可能展示不到位,不過如果有錯歡迎評論指出,初學者的路還很長。
