使用Clion 閱讀/修改/注釋 Linux 內核源碼

前言

其實,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__)

添加內容主要包括:

  1. 修改sysroot,這需要首先在CMakeLists.txt的同目錄下創建一個名為sysroot的空目錄,然后設置編譯參數"--sysroot=${SYSROOT}",這是因為sysroot其實是C標準頭文件的位置,顯然內核是不需要這些東西的,他們存在反而會干擾clion尋找正確頭的文件,產生一下不必要得沖突
  2. 添加頭文件路徑,如果不進行這一步,那么clion將會出現大量的錯誤,提示找不到頭文件或者變量、常量、函數等。具體添加的內容是我反復測試過的,添加這些內容后基本上保證頭文件尋找正確,其中后四個是與架構相關的,x84_64可放心使用
  3. 使用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中,這個很奇怪!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容