衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

如何高效的閱讀Linux源碼

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

1.引言

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

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

2.工具安裝與使用

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

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支持的編程語言對應的文件擴展名

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

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

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

再根據提示輸入1 回車就跳轉到main函數所在的位置了,

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

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

搜索結果如下:

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

: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+] ,取出當前光標下的word作為tag的名字并進行跳轉。你需要查看main函數里的BOARD_InitPins()函數定義,直接在vim里,將光標移動到那里,然后ctrl+]就跳轉過去了

實現的效果和Keil里點擊Go to Definition 效果一致

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

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

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

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

上述第一個問題,我們通過2.2節的Nerdtree工具實現,第二個問題通過2.3節的Taglist工具實現,第三個問題通過2.4節的cscope工具實現。

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 網站下載壓縮包,將解壓縮的文件拷貝到~/.vim/中即可,下面是我~/.vim/中的文件:

如果沒有.vim 目錄的話,自己創建下即可。

2.2.2 Nerdtree使用

在使用前,現在~/.vimrc中添加以下兩句話:

map :NERDTreeToggle

nnoremap :NERDTreeFind

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

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

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

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

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

find gpio_led_output.c或

find g[TAB]

即可搜索文件

2.3 安裝配置Taglist

2.3.1 Taglist安裝

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

map :TlistToggle

let Tlist_Use_Right_Window = 1

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

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

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

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

map :vertical resize +1

map :vertical resize -1

:vertical resize 是用來調整當前窗口寬度的。

我們在最左側窗口中先按F5幾次,減小當前窗口寬度,

然后到最右側窗口中也按F5幾次,減小當前窗口寬度,

就變成這樣了:

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

Ctrl + + 為增大字體

2.4 cscope

2.4.1 cscope安裝配置

先看下ctags和cscope的區別: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 只能讓我們跳轉到某個 tag 的定義之處,但是無法讓我們知道這個 tag 還在哪里出現過,或者被哪個函數調用過,這時候就需要 cscope 來完成該功能了。安裝方式如下:sudo apt-get install cscope驗證是否安裝成功的方式可以輸入cscope --version

表示安裝成功

2.4.2 cscope使用

第1步:使用 cscope 生成數據庫文件

cscope -Rbkq

其中參數的含義:

-R 遞歸,對子目錄也建立數據庫

-b 只生成數據庫,不進入 scope 界面

-k 生成數據庫時,不搜索 /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 會直接跳轉到這個函數的定義處

cs find c BOARD_InitPins 會直接跳轉到調用這個函數的地方

cs find t BOARD_InitPins 會列出以下5個出現該函數的地方

通過選擇不同的數字,可以查看具體不同出現的位置。這個搜索結果和Keil里搜索的結果一樣:

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

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

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

3.Uboot實戰應用

先回到我們之前遇到的那個問題,我是如何在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減小下兩側窗口寬度,Ctrl+-縮小字體:botright copen 打開quickfix窗口第5步::cs find t 0x66666666我們找到16處,通過簡單分析就可以定位到第一個結果就是我們需要的。

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

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

我們再輸入:ts board_mmc_init 查看下該函數的定義,發現竟然有三處

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

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

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

4.結束語

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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11345

    瀏覽量

    210404
  • IDE
    IDE
    +關注

    關注

    0

    文章

    341

    瀏覽量

    46879
  • Uboot
    +關注

    關注

    4

    文章

    125

    瀏覽量

    28350
收藏 人收藏

    評論

    相關推薦

    Linux內核開發工具介紹

    進行嵌入式Linux產品開發,往往需要對內核進行裁剪和定制,以滿足嵌入式產品的功能和性能需求。本文介紹幾種閱讀Linux內核源碼的工具和方法。
    發表于 12-29 15:20 ?4750次閱讀
    <b class='flag-5'>Linux</b>內核開發工具介紹

    一文詳解Linux內核源碼組織結構

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

    Linux內核源碼之我見——內核源碼的分析方法

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

    下載編譯源碼的要點和搭建源碼閱讀環境的方法

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

    Linux內核源代碼(free)

    一些基本概念 操作系統的基本概念 I386系統的基本概念 Linux簡介 源碼閱讀和project環境 Linux 2.6.26 源碼
    發表于 01-08 17:41 ?26次下載

    幾個RT-Linux 源碼

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

    Linux內核閱讀心得體會

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

    需要掌握的Linux內核源碼分析方法

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

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

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

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

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

    ROC RK3566 PC Linux SDK源碼

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

    AIO 3568J Linux SDK源碼

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

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

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

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

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

    獲取Linux內核源碼的方法

    關鍵功能,今天小編就給各位小伙伴介紹一下如何獲取Linux內核源碼。獲取Linux內核源碼的渠道Linux有一個龐大的開源社區,每個人都可以
    的頭像 發表于 12-13 09:49 ?718次閱讀
    獲取<b class='flag-5'>Linux</b>內核<b class='flag-5'>源碼</b>的方法
    大发888游戏平台88| 百家乐官网公式软件| 百家乐模拟分析程序| 大发888娱乐城健账号| 百家乐官网太阳城娱乐城| 火箭百家乐官网的玩法技巧和规则 | 大发888代充平台| 百家乐官网赌博娱乐| 百家乐押注方法| 百家乐官网号论坛博彩正网| 百家乐屏风| 百家乐官网视频游戏世界| 百家乐玩揽法大全| 网上百家乐官网分析软件| 百家乐无损打法| 澳门百家乐官网路子分析| 7位百家乐扑克桌| 百家乐官网桌小| 大发888下载 客户端| 百家乐官网完美一对| 全讯网334466| 百家乐官网机器出千| 新2开户| 真人百家乐好不好玩| 真人百家乐官网口诀| 百家乐赢钱秘籍鹰| 缅甸百家乐官网玩家吗| 太阳城线上娱乐城| 大丰收百家乐官网的玩法技巧和规则 | 永年县| 百家乐平的概率| 百家乐官网真人娱乐城陈小春| 大发888娱乐城网址| 做生意开店铺风水大全| 海丰县| 永利百家乐娱乐网| 网上百家乐官网骗局| 棋牌小游戏| 百家乐赌机破解| 粤港澳百家乐官网娱乐场| 大赢家娱乐城信誉|