前言
其實,bootlin就是一個聽不錯的閱讀源碼的工具了,可以非常方便的幫我們查閱函數、宏的定義、引用等等。而且是基于瀏覽器,對我們本機的配置沒有什么過高的要求。
但是如果想要做一些注釋,修改,那我們就要將源碼下載到本地了,這個時候我們可能就需要其他的工具了。
Clion我最熟悉的C/C++ IDE,我非常喜歡Jetbrains家族的IDE,因此使用Clion來閱讀/注釋/修改源碼,就成了我的首選,很可惜的是,Linux kernel是通過Makefile進行構建的,然后Clion是用的是CMake,因此如果我們想要借助Clion來閱讀源碼,就需要生成Linux kernel的Cmake文件!
目前來看,可以成功的實現使用Clion來閱讀/注釋/修改源碼,但是不能成功的進行編譯,因此編譯還得用make,不過這個無傷大雅!
配置要求
Clion需要大量的緩存內核文件,因此我們必須保證本機有足夠的內存,并調高Clion的堆內存配置,本機至少要有8G內存,Clion堆內存至少調整到4G以上。配置方法:
點擊CLion的狀態欄上的"Help->Change Memory Settings",然后修改"MAX Heap Size",如下圖所示,我將其調整到了8G,我本機有24G。然后重啟配置生效!
源碼準備
安裝編譯必須的工具
sudo apt update && sudo apt upgrade
sudo apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
下載源碼,最好到The Linux Kernel Archives下載源碼的壓縮包,然后再解壓!
tar -zxf linux-5.14.2.tar.xz
cd linux-5.14.2
使用本機的配置文件來配置內核
cp /boot/config-$(uname -r) .config
make menuconfig
上述過程其實就是編譯內核的步驟。
注意:
直接使用ubuntu的.config在編譯時可能遇到如下的錯誤:
make[1]: *** No rule to make target 'debian/certs/benh@debian.org.cert.pem', needed by 'certs/x509_certificate_list'
此時需要編輯一下.config,將CONFIG_SYSTEM_TRUSTED_KEYS置為空:
CONFIG_SYSTEM_TRUSTED_KEYS = ""
生成CMakeLists.txt
安裝bear工具,bear可以根據追蹤make編譯的過程,生成compile_commands.json文件,然后我們在通過其他工具通過compile_commands.json最終生成CMakeLists.txt
sudo apt-get install bear
使用bear,make編譯內核。最新的bear應該需要在bear和make之間加上"--"。make的"-j12"表示啟用12個線程同時編譯,這取決你本機的core數,這個過程需要很久!
bear make -j12
2020年 9月21日更新
之前我一直使用make -j12
來編譯內核,在我這臺擁有12個core的機器上,編譯時間也長達30分鐘,直到前幾天我才發現,這樣其實是非常蠢的,因為make -j12
其實默認編譯了所有的內容,但是如果我們僅僅編譯內核,只需要編譯vmlinux即可,后面為了使用qemu來調試,在加上bzImage就行了,即make -j12 vmlinux bzImage
,這樣一來,編譯的時間只需要不到5分鐘,最終生成Cmakea文件也只有5MB左右,這樣Clion就可以無需那么高的內存配置了!
克隆kernel-grok項目
cd ~
git clone https://github.com/habemus-papadum/kernel-grok
回到內核目錄,生成CMakeLists.txt
cd linux-5.14.2
~/kernel-grok/generate_cmake ## creates CMakeLists.txt
修改CMakeLists.txt
這個時候需要我們手動添加一些參數配置
在文件的最開頭添加以下內容:
cmake_minimum_required(VERSION 2.8.8)
project(kernel)
set(SYSROOT sysroot)
SET(CMAKE_C_COMPILER "gcc")
set(CMAKE_C_STANDARD 90)
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} " --sysroot=${SYSROOT}" )
include_directories("include")
include_directories("include/uapi")
include_directories("arch/x86/include")
include_directories("arch/x86/include/uapi")
include_directories("arch/x86/include/generated")
include_directories("arch/x86/include/generated/uapi")
add_definitions(-D__KERNEL__)
添加內容主要包括:
- 修改sysroot,這需要首先在CMakeLists.txt的同目錄下創建一個名為sysroot的空目錄,然后設置編譯參數"--sysroot=${SYSROOT}",這是因為sysroot其實是C標準頭文件的位置,顯然內核是不需要這些東西的,他們存在反而會干擾clion尋找正確頭的文件,產生一下不必要得沖突
- 添加頭文件路徑,如果不進行這一步,那么clion將會出現大量的錯誤,提示找不到頭文件或者變量、常量、函數等。具體添加的內容是我反復測試過的,添加這些內容后基本上保證頭文件尋找正確,其中后四個是與架構相關的,x84_64可放心使用
- 使用C90的C語言標準,一開始我使用的是Clion的默認C標準,一直沒有出過問題,但是昨天一下子就出現大量報錯,不排除是因為我升級了最新的Clion 2021.2.2 ,最終加上了
set(CMAKE_C_STANDARD 90)
才恢復正常
啟動CLion
點擊狀態欄"File->Open",然后選中我們創建的CMakeLists.txt,確定后選擇"Open as Project"
然后Clion會自動加載Cmake,目前最終會加載失敗,因為這個方法并不能用來編譯內核!
這時候查看內核源碼,正常是沒有任何紅色報錯信息,可以正常的進行跳轉和自動補全。
問題
除去不能編譯外,還有一個問題,那就是編譯選項的宏定義,顯示不正常:
上面是task_struct中的一段代碼,clion的代碼顯示表明找不到CONFIG_MEMCG,因此也就沒有定義memcg_data,但是按住Ctrl是可以跳轉到CONFIG_MEMCG的定義的,就在include/generated/autoconf.h中,這個很奇怪!