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