Android Linux内核编译调试
對(duì)于在Windows上寫代碼寫習(xí)慣的人,調(diào)試是必不可少的手段,但是轉(zhuǎn)到Android以后,發(fā)現(xiàn)調(diào)試手段異常簡(jiǎn)陋,跟Windows簡(jiǎn)直不是一個(gè)級(jí)別,特別是Android的內(nèi)核調(diào)試,網(wǎng)上資料也相對(duì)較少,不過通過一段時(shí)間的倒騰,我終于找到了還算靠譜的調(diào)試方法.就是利用Emulator?+?Eclipse進(jìn)行Android?Linux內(nèi)核調(diào)試.
?
1.系統(tǒng)預(yù)裝環(huán)境
在目前為止,都是使用的最新版本的Android開發(fā)環(huán)境
?
Ubuntu?14.04?
Android?SDK(?adt-bundle-linux-x86_64-20140702?)
Android?NDK(?android-ndk32-r10b-linux-x86_64?)
?
安裝好這幾個(gè)環(huán)境以后,設(shè)置一下環(huán)境變量
?
export?PATH=$PATH:ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin
?
ANDROID_NDK_HOME鍵值為Android?NDK安裝目錄,設(shè)置這個(gè)環(huán)境變量的目的主要是為了使用gcc?4.6版本編譯linux內(nèi)核.?
?
export?PATH=$PATH:ANDROID_SDK_HOME/sdk/tools
?
ANDROID_SDK_HOME是Android?SDK的安裝目錄,設(shè)置這個(gè)環(huán)境變量的目的是方便使用emulator命令!
?
萬(wàn)事具備.使用前面安裝的Android?SDK創(chuàng)建一個(gè)虛擬的設(shè)備.并且確保?emulator?-avd?Device_Test這條命令可以啟動(dòng)Android?模擬器.先熱身下.?
?
2.Android?Linux內(nèi)核編譯
?
2.1?下載GoldFish?源碼
?
mkdir?kernel?
cd?kernel
git?clone?http://android.googlesource.com/kernel/goldfish.git
?
GoldFish是適配模擬器的內(nèi)核源碼,如果是要具體適配其他機(jī)型,請(qǐng)選擇其他源碼,這邊不展開了,詳情參考鏈接有說(shuō)明.?如果失敗了,換https.我換https是因?yàn)槭褂昧舜?/span>,現(xiàn)在google被墻,不使用代理搞不動(dòng)!
?
git?clone?https://android.googlesource.com/kernel/goldfish.git
?
?
下載過程看你的代理速度了,而且不能中斷.中斷了就要重新來(lái),特別的麻煩和惡心!所以我上傳了一份到百度云.?和上面goldfish出來(lái)的一樣.可以考慮去下載
?
http://pan.baidu.com/s/1i3yzhbv
?
下載或者解壓完成以后會(huì)在kernel目錄下會(huì)生成一個(gè)goldfish文件夾,進(jìn)入此目錄.查看所有分支
?
?
?
可以看到,?有很多的版本,?2.6.29和3.4我都測(cè)試過.?編譯和運(yùn)行沒有任何問題.?所以這邊我們拉2.6.29的源碼
?
git?checkout?remotes/origin/android-goldfish-2.6.29
?
?
然后目錄下就有很多文件了,說(shuō)明Android?Linux的源碼下載成功!
?
?
?
3.2?編譯GoldFish?源碼
?
編譯源碼之前,請(qǐng)確認(rèn)已經(jīng)將NDK的編譯工具設(shè)置到環(huán)境變量中.我們將使用上述這個(gè)目錄下的交叉編譯器arm-linux-androideabi-gcc
?
export?PATH=$PATH:ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin
?
然后在glodfish目錄下用gedit打開Makefile文件,找到這兩行文字:
?
#ARCH??=?$(SUBARCH)
#CROSS_COMPILE??=
?
修改成
ARCH??=?arm
CROSS_COMPILE??=?arm-linux-androideabi-
?
?
?
保存文件,?然后
?
make?goldfish_armv7_defconfig?
?
?
注:用$make?goldfish_defconfig這樣配置也可以編譯通過,模擬器也可以啟動(dòng),但是Android的開機(jī)畫機(jī)就顯示不了,$adb?shell也死活連不上,原因就是這個(gè)goldfish_defconfig這個(gè)配置文件問題.
?
Android?Linux的基本編譯就設(shè)置完成了.我們先make?一下
make
?
?
這就表示編譯成功了,Linux的源碼是Linux上少有的一鍵make過去的軟件,比編譯其他Linux應(yīng)用簡(jiǎn)單不少.當(dāng)然到這里編譯出來(lái)的這個(gè)zImage已經(jīng)可以運(yùn)行了,但是離我們用來(lái)做調(diào)試的還是有差距.我們還要開啟內(nèi)核調(diào)試和關(guān)閉優(yōu)化.?
?
3.3?開啟調(diào)試選項(xiàng)
開啟Linux內(nèi)核的調(diào)試選項(xiàng),?先安裝依賴性
sudo?apt-get?install?ncurses-dev
然后
make?menuconfig
?
?
進(jìn)入內(nèi)核配置界面,勾選下列選項(xiàng),同時(shí)關(guān)閉優(yōu)化
?
General?setup?—>?
[?]?Optimize?for?size,進(jìn)行開啟/關(guān)閉
?
[*]?Kernel?hacking?
?????[*]?Compile?the?kernel?with?debug?info?
?????[*]?KGDB:?kernel?debugging?with?remote?gdb?—>??????
[*]?Enable?dynamic?printk()?call?support?
?
關(guān)閉Linux內(nèi)核優(yōu)化比較麻煩.我通過和朋友討論,以及網(wǎng)絡(luò)搜索還沒有找到很好的解決辦法,原因是默認(rèn)的Linux內(nèi)核編譯是開啟-O2優(yōu)化的,這種模式之下會(huì)造成gdb和實(shí)際的源碼對(duì)不上,相信使用過windbg調(diào)試-O2的朋友都有這個(gè)經(jīng)歷,所以我們需要關(guān)閉Linux的-O2,不過目前還沒有很好的解決辦法下面這篇文章討論的解決辦法是.針對(duì)文件進(jìn)行關(guān)閉優(yōu)化.下面這兩篇文章的討論都非常有意義:
?
http://www.lenky.info/archives/2013/03/2238
?
http://www.ibm.com/developerworks/cn/linux/l-kdb/
?
這邊我們將-Os?和-O2都調(diào)成-O.針對(duì)具體文件關(guān)閉優(yōu)化,這邊就不搞了.具體到自己的調(diào)試任務(wù)的時(shí)候再看.?
?
?
?
再進(jìn)行編譯,?
make?-B
選項(xiàng)-B以強(qiáng)制所有內(nèi)核源文件全部重新編譯(因?yàn)槲仪懊婢幾g過一次了,為了保險(xiǎn)起見,就讓目標(biāo)文件全部重新生成吧)當(dāng)出現(xiàn)這個(gè)畫面,就表示編譯成功了
?
?
?
4.Android?Linux內(nèi)核調(diào)試
使用emulator?啟動(dòng)我們編譯的內(nèi)核試試
?
emulator?-verbose?-show-kernel?-kernel?~/kernel/goldfish/arch/arm/boot/zImage?-avd?Device_Test
?
?
沒錯(cuò),?啟動(dòng)的就是我們的內(nèi)核2.6.29?時(shí)間也對(duì)的上.說(shuō)明我們編譯的內(nèi)核是可以運(yùn)行的.下一步使用這條命令
?
emulator?-verbose?-show-kernel?-kernel?-netfast?~/kernel/goldfish/arch/arm/boot/zImage?-avd?Device_Test?-qemu?-gdb?tcp::1234,ipv4,?-S
?
這條命令會(huì)在tcp端口的1234監(jiān)聽.加了-S還會(huì)暫停下來(lái),等待著gdb鏈接上來(lái).這時(shí)候我們開啟NDK目錄下面的gdb.鏈上去然后
?
target?remote?localhost:1234?
?
?
還可以測(cè)試幾條命令,?看看源碼是否跟上了.?
?
?
到這里為止,基本上是用gdb連上emulator?進(jìn)行內(nèi)核調(diào)試應(yīng)該沒問題了.但是僅僅到這里那離windbg的調(diào)試還是差好幾條街.所以我們還是需要一個(gè)更好的調(diào)試方法.是用eclipse來(lái)作為調(diào)試的前端!
?
5.Eclipse前端
是用Eclipse作為前端的好處是,無(wú)論是在windows,在linux下面都沒有問題.可以在一臺(tái)windows的機(jī)器上,遠(yuǎn)程調(diào)試android內(nèi)核.所以為了截圖方便,我下面的操作都是在windows上弄的,在Linux上也是一樣!當(dāng)然要在windows上進(jìn)行調(diào)試,首先要將上面的gold目錄復(fù)制到windows的機(jī)器上,或者是共享給windows.這里就不展開了!
?
運(yùn)行Eclipse,點(diǎn)擊菜單Help->Install?New?Software…?在彈出的對(duì)話框里點(diǎn)擊Work?with:后面的下拉按鈕,選擇Kepler?–?http://download.eclipse.org/releases/kepler
?
不同的Eclipse版本選擇不一樣,與自己下載的版本一致一即可.然后在下面的選擇框中將以下選項(xiàng)安裝上
Programming?Languages?
C/C++?Autotools?support
C/C++?Visual?C++?Support
C/C++?Development?Tools
C/C++?Development?Tools?SDK
Linux?Tools
GDB?Tracepoint?Analysis
Mobile?and?Device?Development
C/C++?GDB?Hardware?Debugging
?
安裝好后自動(dòng)重啟Eclipse即可.再配置點(diǎn)擊菜單Window?->?Preferences在彈出的對(duì)話框中,點(diǎn)擊左邊的General->Workspace將右邊的Build?automatically復(fù)選框不選中.
再點(diǎn)擊對(duì)話框左邊的C/C++->Indexer,將右邊的Enable?indexer和Automatically?update?the?index兩復(fù)選框不選中.
?
接下來(lái)就簡(jiǎn)單了.創(chuàng)建一個(gè)工程,點(diǎn)擊菜單File->New->Project…在彈出的對(duì)話框中選擇C/C++->C?Project再點(diǎn)擊Next?>按鈕
?
?
其中Project?name:為工程名,可自定義.而Location:則為工程文件所在路徑,此處設(shè)置為我們下載的源碼路徑而Project?type:則設(shè)置為Makefile?project/Empty?Project,?Toolchains:則設(shè)置為Linux?GCC,如果是windows設(shè)置成Android?GCC最后點(diǎn)擊Finish即可.
?
接下來(lái)Windows和Linux都一樣,進(jìn)行DEBUG配置,在Project?Explorer里右擊剛創(chuàng)建的Linux_Kernel項(xiàng)目,在右鍵菜單中點(diǎn)擊Debug?As->Debug?Configurations…在彈出的對(duì)話框中雙擊GDB?Hardware?Debugging?然后配置調(diào)試選項(xiàng)如下圖
?
?
將C/C++?Application:欄設(shè)置為Linux?Kernel源碼編譯出來(lái)的vmlinux文件所在路徑(包含文件名),然后將Disable?auto?build選上,切換到Debugger頁(yè),修改配置如下截圖.
?
?
?
這里是設(shè)置gdb的路徑還有遠(yuǎn)程地址和端口.?Gdb的路徑在ndk安裝目錄下的如下路徑
?
\toolchains\arm-linux-androideabi-4.6\prebuilt\windows-x86_64\bin
?
遠(yuǎn)程地址,我的ubuntu機(jī)器是192.168.1.2這個(gè)隨機(jī)應(yīng)變即可.端口是我們運(yùn)行emulator命令定義的端口.搞定這個(gè)切換到Startup頁(yè)面
?
?
?
將Reset?and?Delay(seconds)和?Halt?還有Load?image復(fù)選框的勾都去掉.然后點(diǎn)擊Debug,這時(shí)候就停在第一條指令了
?
這時(shí)候還不能按F5,?F6單步.我們?cè)?/span>Execut窗口指定到main.c?然后在?start_kernel上下個(gè)斷點(diǎn)也可以再Console窗口敲命令break?start_kernel.?然后敲入命令C.?
?
?
這時(shí)候就停在了Linux內(nèi)核的入口函數(shù)start_kernel.也可以使用F5,F6了.寄存器顯示各方面都可以了.如果在Windows上,有一個(gè)毛病,源文件都要自己重新指定路徑.不然認(rèn)不到.?默認(rèn)都是編譯路徑/home/xxx什么的.要重新指定成Windows的盤符形式.不過在Linux上調(diào)試就沒有這個(gè)問題了!
?
?
?
這個(gè)調(diào)試差不多是搞起走了.如果是分析Android的源碼,看一看跟一下還是很不錯(cuò)的.不過還是有一個(gè)問題沒有解決,關(guān)于匯編和符號(hào)不對(duì)應(yīng)的問題.大家可以群策群力搞一下!
?
參考鏈接:
http://wenku.baidu.com/view/95c69448e518964bcf847c2f.html?
http://blog.csdn.net/flydream0/article/details/7070392?
http://www.lenky.info/archives/2013/03/2238?
http://blog.csdn.net/liushuaikobe/article/details/8646555
http://x-slam.com/da_jian_eclipse_qemu_gdb_diao_shi_linux_kernel_huan_jing?
?菊子曰:專業(yè)的博客管理軟件網(wǎng)友評(píng)論:
不建議修改Makefile文件.可以在make命令后面添加參數(shù)
make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- goldfish_armv7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-androideabi-
make的時(shí)候順便加上-j參數(shù),多線程編譯加快速度
make ARCH=arm CROSS_COMPILE=arm-linux-androideabi- -j8
emulator -verbose -show-kernel -kernel -netfast ~/kernel/goldfish/arch/arm/boot/zImage -avd Device_Test -qemu -gdb tcp::1234,ipv4, -S
命令有誤,修改如下:
emulator -verbose -show-kernel -netfast -kernel ~/kernel/goldfish/arch/arm/boot/zImage -avd Device_Test -qemu -gdb tcp::1234,ipv4 -S
你說(shuō)的對(duì), -netfast 和-kernel 要調(diào)換下順序, 可能是我寫文章的時(shí)候?qū)戝e(cuò)了!
今天為了研究linux的slub分配器.編譯了um來(lái)調(diào)試.但是由于linux內(nèi)核默認(rèn)情況下使用-O2,而最低要求需要-O1才能編譯成功.在打開優(yōu)化的情況下,調(diào)試起來(lái)源代碼會(huì)亂跳.為了解決這個(gè)問題,我折騰了幾分鐘.發(fā)現(xiàn)有三個(gè)地方需要修改就可以了
第一處 include/linux/compiler-gcc.h 在里面inline __inline這些定義之后都有 aways_inline的attribute,要把這個(gè)屬性刪除
另一處, 在menuconfig里,kernel hack里面不選中”Force gcc to inline functions marked inline”
當(dāng)然,最后,Makefile里面那個(gè)-O2要?jiǎng)h除掉,也就是不用任何優(yōu)化來(lái)編譯(貌似這個(gè)時(shí)候就是-O0)
之后用make ARCH=um 就可以編譯成功了. 我精簡(jiǎn)過的um編譯出來(lái)大概15M.(選擇了compile the kernel with debug info)
樓主你好,我是新手,按照你的步驟一步步進(jìn)行內(nèi)核調(diào)試。預(yù)裝環(huán)境與文章一致,linux內(nèi)核用的3.4,在進(jìn)行eclipse內(nèi)核調(diào)試時(shí),提示no source available for “0x0”,且 在executables中沒有init 的main函數(shù)。請(qǐng)問如何破解?
原文地址: http://www.joenchen.com/archives/1093
總結(jié)
以上是生活随笔為你收集整理的Android Linux内核编译调试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ftrace、kpatch、system
- 下一篇: linux 其他常用命令