0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何高效的閱讀Linux源碼

Wildesbeast ? 來源:今日頭條 ? 作者:TopSemic ? 2020-02-22 14:43 ? 次閱讀

1.引言

如何閱讀代碼還要單獨寫一篇文章?難道不是隨便用一個IDE就可以了嗎?回到上一篇文章里介紹的那個問題,需要修改uboot里board_mmc_init函數(shù)里的writel(0x66666666,REG_MFP_GPD_L) ,對于初學(xué)者如何在uboot代碼里找到這句話呢?當(dāng)時問我這個問題的網(wǎng)友就有這個困惑。

因為Uboot和Kernel里有非常多數(shù)量的文件,另外為了支持多種芯片,在整個目錄里存在大量的同名文件、同名函數(shù)。所以如果用一般的IDE把整個工程目錄加載進去,然后閱讀代碼,會相當(dāng)?shù)牟环奖悖愫茈y理清楚各個函數(shù)之間的調(diào)用關(guān)系。我曾經(jīng)嘗試過在Windows下用SourceInsight去看內(nèi)核源碼,實在看不下去,而且由于文件太多經(jīng)常卡住。在網(wǎng)上也看到有人通過一些腳本去精簡文件數(shù)量再配合SourceInsight的,我也嘗試過,感覺也不是很好用。見到過幾個高手是直接通過VIM閱讀,效率很高,我經(jīng)過幾天的摸索,稍微入了一點門,在這里給初學(xué)者做個分享,希望對大家有所幫助。

2.工具安裝與使用

因為我一開始學(xué)的單片機,用Keil軟件比較多,咱們就在Ubuntu里構(gòu)建一個類似于Keil軟件常見功能的環(huán)境。為了讓大家看起來更直觀,我找了一個單片機的工程同時放到Ubuntu里和Window下,兩邊同時對比分析。我們需要在Ubuntu系統(tǒng)里安裝配置以下幾個工具。

2.1 ctags

2.1.1 ctags安裝配置

以下一段話摘自于維基百科:Ctags is a programming tool that generates an index (or tag) file of names found in source and header files of various programming languages. Depending on the language, functions, variables, class members, macros and so on may be indexed. These tags allow definitions to be quickly and easily located by a text editor, a code search engine, or other utility.安裝方式如下:sudo apt-get install ctags驗證是否安裝成功的方式可以輸入ctags --version

使用ctags --list-languages可以查看ctags支持的編程語言

使用ctags --list-maps可以查看ctags支持的編程語言對應(yīng)的文件擴展名

使用ctags --list-kinds可以查看ctags識別的語法元素,使用ctags --list-kinds=c可單查看C語言識別的語法元素

安裝完成之后,想要使用ctags,必須在你想要查看的代碼目錄中有tags文件。2.1.2 ctags使用在執(zhí)行下述操作前,已經(jīng)在Ubuntu里~/mcuproject目錄下放了一個MCU的工程。第1步: ctags -R *生成tags文件。

第2步:需要找到main函數(shù)定義在哪里,先輸入vim打開vim窗口,然后在vim命令行窗口輸入ts main它的作用是:Search for a particular tag

再根據(jù)提示輸入1 回車就跳轉(zhuǎn)到main函數(shù)所在的位置了,

有一點需要大家注意的是:一定要在tags所在的目錄打開vim,輸入ts才能搜到你要找到的tag,在其它目錄是不行的,比如我進入到上一級目錄,就會提示如下信息了。

對比下Windows里Keil環(huán)境下,我通常用如下方式去查找:

搜索結(jié)果如下:

看到這里你是不是有個疑問,為什么Ubuntu下搜索main只有一個地方,但是在Keil下搜索出來了6處。原因是使用ctags搜索的結(jié)果是main的定義,而Keil里是只要main這個字符串出現(xiàn)的地方都會被搜索出來。除了剛才使用的ts命令,還有其他相關(guān)命令:

:ts or :tselect List all of the definitions of the last tag

:tn or :tnext Go to the next definition for the last tag

:tp or :tprev Go to the previous definition for the last tag

:tf or :tfirst Go to the first definition for the last tag

:tl or :tlast Go to the last definition for the last tag

第3步:ctags兩個常用的快捷鍵

Ctrl-] Jump to the tag underneath the cursor

Ctrl-t Jump back up in the tag stack

通過ctrl+] ,取出當(dāng)前光標(biāo)下的word作為tag的名字并進行跳轉(zhuǎn)。你需要查看main函數(shù)里的BOARD_InitPins()函數(shù)定義,直接在vim里,將光標(biāo)移動到那里,然后ctrl+]就跳轉(zhuǎn)過去了

實現(xiàn)的效果和Keil里點擊Go to Definition 效果一致

看完了這個函數(shù),想回到原來的地方怎么辦呢,ctrl+t即可,對應(yīng)Keil中下方紅框向左的箭頭功能。

但是只有ctags還不行,因為還有下面3個閱讀代碼過程中的問題沒有解決1)沒有類似Keil中下方的工程文件列表,不方便隨意選中某個文件瀏覽

2)沒有類似Keil中下方的function功能,方便快速找到一個文件中的函數(shù)定義

3)如果瀏覽到下面這個文件的BOARD_InitPins函數(shù),我想搜索誰調(diào)用它的,就沒招了。

上述第一個問題,我們通過2.2節(jié)的Nerdtree工具實現(xiàn),第二個問題通過2.3節(jié)的Taglist工具實現(xiàn),第三個問題通過2.4節(jié)的cscope工具實現(xiàn)。

2.2安裝配置Nerdtree

2.2.1 Nerdtree安裝

The NERD tree : A tree explorer plugin for navigating the filesystem

The NERD tree allows you to explore your filesystem and to open files and directories. It presents the filesystem to you in the form of a tree which you

manipulate with the keyboard and/or mouse. It also allows you to perform

simple filesystem operations.

安裝方式是先在https://www.vim.org/scripts/script.php?script_id=1658 網(wǎng)站下載壓縮包,將解壓縮的文件拷貝到~/.vim/中即可,下面是我~/.vim/中的文件:

如果沒有.vim 目錄的話,自己創(chuàng)建下即可。

2.2.2 Nerdtree使用

在使用前,現(xiàn)在~/.vimrc中添加以下兩句話:

map :NERDTreeToggle

nnoremap :NERDTreeFind

具體什么用途,下文馬上解釋。Nerdtree使用方式是在vim打開的文件中,切換到底線命令模式,輸入NERDTree,回車就可以了。

顯示效果如下,多出來左側(cè)部分就是Nerdtree

如果需要關(guān)閉Nerdtree,需要切換到底線命令模式,輸入NERDTreeClose,這樣操作顯然很麻煩,這時上面map :NERDTreeToggle 這句話就起作用了,我們只需要按F2鍵就可以來回切換打開與關(guān)閉該窗口了。在Nerdtree打開的情況下,有兩個窗口,默認打開后光標(biāo)是在最左側(cè)的窗口,怎么切換到右側(cè)窗口瀏覽代碼呢?通過Ctrl+w+w在兩個窗口切換,我們先切換到右邊的窗口,然后進入到CLOCK_EnableClock定義的文件里(還記得上一節(jié)的Ctrl-]快捷鍵吧),進入后顯示如下

這時按一下F3快捷鍵,注意左側(cè)窗口的變化,自動就定位到該函數(shù)所在的文件了,可以很清晰的看到所在文件的目錄結(jié)構(gòu)。這就是上面添加的第二句話的作用。

另外如果工程里文件很多,你想通過搜索快速找到某個文件,可以使用vim自帶的find命令也能完成所需功能。find 會從 path 中搜索文件。所以在使用find之前一定要配置一下path變量(不是PATH環(huán)境變量)具體方法是:在右側(cè)窗口中,進入命令行窗口:set path=./**然后

find gpio_led_output.c或

find g[TAB]

即可搜索文件

2.3 安裝配置Taglist

2.3.1 Taglist安裝

Taglist也是vim的一個插件,能將當(dāng)前vim打開的文件中函數(shù)名、變量名等在一個窗口中列出來,并支持通過列出的函數(shù)名實現(xiàn)跳轉(zhuǎn)。將Taglist下載下來的壓縮包解壓縮,將解壓縮出來的doc里面的taglist.txt復(fù)制到~/.vim/doc/下面,plugin里面的taglist.vim文件拷貝到~/.vim/plugin目錄下。這樣Taglist這個插件安裝完成了。下載地址在:https://www.vim.org/scripts/script.php?script_id=2732.3.2 Taglist使用在使用前,現(xiàn)在~/.vimrc中添加以下兩句話:

map :TlistToggle

let Tlist_Use_Right_Window = 1

其中第1句話是建了一個F4的快捷鍵,用來方便打開和和關(guān)閉該插件第2句話是將該插件窗口放到最后側(cè)。另外根據(jù)需要你還可以選擇是否添加以下特性:

let Tlist_Show_One_File = 1 "不同時顯示多個文件的tag,只顯示當(dāng)前文件的
let Tlist_Exit_OnlyWindow = 1 "如果taglist窗口是最后一個窗口,則退出vim

按下F4打開Taglis后,整體窗口顯示如下:

三部分窗口比例不是很和諧,中間代碼窗口太窄,怎么調(diào)整窗口大小呢?在~/.vimrc中添加以下兩句話:

map :vertical resize +1

map :vertical resize -1

:vertical resize 是用來調(diào)整當(dāng)前窗口寬度的。

我們在最左側(cè)窗口中先按F5幾次,減小當(dāng)前窗口寬度,

然后到最右側(cè)窗口中也按F5幾次,減小當(dāng)前窗口寬度,

就變成這樣了:

另外你也可以在中間窗口通過Ctrl + - 減小字體來顯示的更多內(nèi)容

Ctrl + + 為增大字體

2.4 cscope

2.4.1 cscope安裝配置

先看下ctags和cscope的區(qū)別:ctags can be used to take you to the definition of a variable (e.g., a function, variable, or macro). cscope can be used to take you to the call site of a definition (e.g., all function calls, all variable uses, all macro uses).簡而言之,它是 ctags 的加強版,ctags 只能讓我們跳轉(zhuǎn)到某個 tag 的定義之處,但是無法讓我們知道這個 tag 還在哪里出現(xiàn)過,或者被哪個函數(shù)調(diào)用過,這時候就需要 cscope 來完成該功能了。安裝方式如下:sudo apt-get install cscope驗證是否安裝成功的方式可以輸入cscope --version

表示安裝成功

2.4.2 cscope使用

第1步:使用 cscope 生成數(shù)據(jù)庫文件

cscope -Rbkq

其中參數(shù)的含義:

-R 遞歸,對子目錄也建立數(shù)據(jù)庫

-b 只生成數(shù)據(jù)庫,不進入 scope 界面

-k 生成數(shù)據(jù)庫時,不搜索 /usr/include 目錄

-q 生成 cscope.in.out 和 cscope.po.out 文件,加快查找速度

第2步:在vim命令行窗口輸入:cs add ./cscope.out第3步:通用格式為 :cs find -option labeloption 可以有很多種模式,在 Vim 中使用 :help cscope-find 來查看 option:

0 or s: Find this C symbol

1 or g: Find this definition

2 or d: Find functions called by this function

3 or c: Find functions calling this function

4 or t: Find this text string

6 or e: Find this egrep pattern

7 or f: Find this file

8 or i: Find files #including this file

比如:

cs find g BOARD_InitPins 會直接跳轉(zhuǎn)到這個函數(shù)的定義處

cs find c BOARD_InitPins 會直接跳轉(zhuǎn)到調(diào)用這個函數(shù)的地方

cs find t BOARD_InitPins 會列出以下5個出現(xiàn)該函數(shù)的地方

通過選擇不同的數(shù)字,可以查看具體不同出現(xiàn)的位置。這個搜索結(jié)果和Keil里搜索的結(jié)果一樣:

但是這樣使用有一個問題:就是我查看一個結(jié)果后,如果我還想繼續(xù)查看其它的結(jié)果,還得重新搜索再選擇一次。該問題的解決方法是:用cscopequickfix,在.vimrc中添加:set cscopequickfix=c-,d-,e-,g-,i-,s-,t-

在命令行copen打開quickfix窗口,用cclose關(guān)閉,cprev、cnext移動再次cs find t BOARD_InitPins 就會再右下角的窗口里顯示,這樣查看完一個文件后如果繼續(xù)查看另外的文件,就可以通過最右下角的窗口切換選擇。

這種方式打開的窗口是在右下角,看著不是很舒服,怎么弄成Keil那樣放到最下方呢,在中間命令行窗口處輸入以下內(nèi)容,就可以在下方顯示了:botright copen

3.Uboot實戰(zhàn)應(yīng)用

先回到我們之前遇到的那個問題,我是如何在Uboot工程里找到需要修改的那個代碼地方的,我們先把上一章改動后的0x0666666改回原來的0x66666666。第1步:進入到Uboot所在目錄make cscope

第2步:make ctags

注意上面兩步驟沒用第二章介紹的方法生成tags和cscope.out文件,原因是因為如果那樣操作的話,就把uboot整個文件夾里的所有文件都加進去了,而使用make的方式只生成了實際用到的。第3步:vim:cs add ./cscope.out第4步:F2 、F4 把Nerdtree和Taglist窗口打開,通過F5減小下兩側(cè)窗口寬度,Ctrl+-縮小字體:botright copen 打開quickfix窗口第5步::cs find t 0x66666666我們找到16處,通過簡單分析就可以定位到第一個結(jié)果就是我們需要的。

你如果是在整個目錄去查詢,就遠遠不止這16處了。通過最右側(cè)的Taglist窗口可以看到它是在board_mmc_init這個函數(shù)調(diào)用的。緊接著我們看下是誰調(diào)用的這個函數(shù)board_mmc_init::cs find c board_mmc_init

我們把光標(biāo)移動到board_mmc_init 處 Ctrl-t 一下,你會發(fā)現(xiàn)進入到不是剛才那個函數(shù)定義的地方了,變成了下面這里,這是咋回事??

我們再輸入:ts board_mmc_init 查看下該函數(shù)的定義,發(fā)現(xiàn)竟然有三處

不過前兩個是weak弱定義,所以直接Ctrl-t 跳轉(zhuǎn)的就是上述的第一個結(jié)果輸入:tn 就會跳轉(zhuǎn)到下一個定義,直到找到正確的定義

另外輸入ts 就可以看到最后一次tag結(jié)果。

使用上面的方法就可以一步步的繼續(xù)分析Uboot代碼,這里不是本篇的重點,不詳細介紹了。

4.結(jié)束語

本篇為大家介紹了Linux下使用vim配合4個插件實現(xiàn)Linux代碼的高效閱讀,因為我也是剛學(xué)習(xí),所以肯定有很多更好的使用方法還沒有掌握,歡迎大家多交流,共同進步,可以在網(wǎng)頁下方留言討論

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11123

    瀏覽量

    207912
  • IDE
    IDE
    +關(guān)注

    關(guān)注

    0

    文章

    334

    瀏覽量

    46540
  • Uboot
    +關(guān)注

    關(guān)注

    4

    文章

    124

    瀏覽量

    28055
收藏 人收藏

    評論

    相關(guān)推薦

    一文詳解Linux內(nèi)核源碼組織結(jié)構(gòu)

    概要:本文內(nèi)容包含Linux源碼樹結(jié)構(gòu)分析、Linux Makefile分析、Kconfig文件分析、Linux內(nèi)核配置選項分析。這些知識是為了理解內(nèi)核文件的組織形式,為具體移植內(nèi)核做
    的頭像 發(fā)表于 05-10 19:28 ?5613次閱讀

    Linux內(nèi)核源碼之我見——內(nèi)核源碼的分析方法

    一、內(nèi)核源碼之我見Linux內(nèi)核代碼的龐大令不少人“望而生畏”,也正因為如此,使得人們對Linux的了解僅處于泛泛的層次。如果想透析Linux,深入操作系統(tǒng)的本質(zhì),
    發(fā)表于 05-11 07:00

    下載編譯源碼的要點和搭建源碼閱讀環(huán)境的方法

    下載編譯源碼的要點和搭建源碼閱讀環(huán)境的方法。下載編譯源碼,一方面是為了搭建源碼閱讀環(huán)境,另一方面
    發(fā)表于 01-10 06:49

    Linux內(nèi)核源代碼(free)

    一些基本概念 操作系統(tǒng)的基本概念 I386系統(tǒng)的基本概念 Linux簡介 源碼閱讀和project環(huán)境 Linux 2.6.26 源碼
    發(fā)表于 01-08 17:41 ?26次下載

    幾個RT-Linux 源碼

    幾個RT-Linux 源碼
    發(fā)表于 01-08 14:27 ?11次下載

    Linux內(nèi)核閱讀心得體會

    Linux內(nèi)核閱讀心得體會
    發(fā)表于 10-24 08:55 ?8次下載
    <b class='flag-5'>Linux</b>內(nèi)核<b class='flag-5'>閱讀</b>心得體會

    需要掌握的Linux內(nèi)核源碼分析方法

    Linux內(nèi)核代碼的龐大令不少人“望而生畏”,也正因為如此,使得人們對Linux的了解僅處于泛泛的層次。如果想透析Linux,深入操作系統(tǒng)的本質(zhì),閱讀內(nèi)核
    發(fā)表于 04-28 16:54 ?737次閱讀
    需要掌握的<b class='flag-5'>Linux</b>內(nèi)核<b class='flag-5'>源碼</b>分析方法

    分享一個超級實用的源碼閱讀小技巧

    工欲善其事必先利其器; 我發(fā)現(xiàn)函數(shù)調(diào)用圖可以讓我們更加直觀地了解到源碼函數(shù)直接的調(diào)用和層次關(guān)系,提高閱讀源碼的效率 。 1 前言 看源碼的時候,心血來潮想弄一下函數(shù)之前的調(diào)用關(guān)系,想起
    的頭像 發(fā)表于 05-29 11:50 ?1904次閱讀
    分享一個超級實用的<b class='flag-5'>源碼</b><b class='flag-5'>閱讀</b>小技巧

    如何選擇合適的工具來閱讀源代碼

    在做嵌入式 Linux 軟件開發(fā)的時候,經(jīng)常會閱讀大型工程源碼,比如 uboot 源代碼,Linux Kernel 源碼等。
    的頭像 發(fā)表于 03-30 14:01 ?1086次閱讀

    Core 1808 JD4 Linux SDK源碼

    電子發(fā)燒友網(wǎng)站提供《Core 1808 JD4 Linux SDK源碼.txt》資料免費下載
    發(fā)表于 09-16 09:27 ?0次下載
    Core 1808 JD4 <b class='flag-5'>Linux</b> SDK<b class='flag-5'>源碼</b>

    ROC RK3566 PC Linux SDK源碼

    電子發(fā)燒友網(wǎng)站提供《ROC RK3566 PC Linux SDK源碼包.txt》資料免費下載
    發(fā)表于 09-21 15:03 ?20次下載
    ROC RK3566 PC <b class='flag-5'>Linux</b> SDK<b class='flag-5'>源碼</b>包

    AIO 3568J Linux SDK源碼

    電子發(fā)燒友網(wǎng)站提供《AIO 3568J Linux SDK源碼包.txt》資料免費下載
    發(fā)表于 09-21 11:02 ?10次下載
    AIO 3568J <b class='flag-5'>Linux</b> SDK<b class='flag-5'>源碼</b>包

    閱讀開源項目源碼的實用技巧(下)

    這句話其實是高效 debug 的關(guān)鍵。初看源碼時「猜」是很重要且很有效的手段,結(jié)合 IDE 的搜索功能,能夠幫我們快速定位關(guān)鍵代碼。
    的頭像 發(fā)表于 04-12 11:37 ?618次閱讀
    <b class='flag-5'>閱讀</b>開源項目<b class='flag-5'>源碼</b>的實用技巧(下)

    如何去閱讀源碼,我總結(jié)了18條心法

    在一個優(yōu)秀的開源項目中,設(shè)計模式處處存在,所以在你開始閱讀源碼之前最好先了解一下常見的一些設(shè)計模式。當(dāng)你了解了一些設(shè)計模式以后,在源碼中遇到了相關(guān)的設(shè)計模式,你就可以快速明白代碼結(jié)構(gòu)的設(shè)計,從而以整體的視角去
    的頭像 發(fā)表于 07-17 16:00 ?658次閱讀
    如何去<b class='flag-5'>閱讀</b><b class='flag-5'>源碼</b>,我總結(jié)了18條心法

    獲取Linux內(nèi)核源碼的方法

    關(guān)鍵功能,今天小編就給各位小伙伴介紹一下如何獲取Linux內(nèi)核源碼。獲取Linux內(nèi)核源碼的渠道Linux有一個龐大的開源社區(qū),每個人都可以
    的頭像 發(fā)表于 12-13 09:49 ?537次閱讀
    獲取<b class='flag-5'>Linux</b>內(nèi)核<b class='flag-5'>源碼</b>的方法