編譯可在Android上啟動並執行qemu user mode,androidqemu

來源:互聯網
上載者:User

編譯可在Android上啟動並執行qemu user mode,androidqemu
前言

本文在Ubuntu 64位系統上對qemu項目進行交叉編譯,並且只編譯與qemu user mode有關的代碼。

下文中的”NDK”若無特殊說明均指”Android NDK”。

下文中”$NDK”表示的是NDK的根目錄。

 

步驟1. 下載並安裝Android NDK

下載並安裝Android NDK的過程在這裡不做介紹。

 

2. 下載qemu

 

3. 設定NDK工具的環境變數

為交叉編譯設定Android NDK環境變數:NDK、SYSROOT

 4. 編譯依賴庫

glib

編譯可在Android上啟動並執行glib庫

編譯參考資料:編譯可在Android上啟動並執行glib庫

libpng12

:https://sourceforge.net/projects/libpng/files/libpng12/

編譯參考資料:編譯可在Android上啟動並執行libffi庫

 

5. 建立pkg-config的軟連結

ln命令中的源路徑是pkg-config工具的源路徑。

如果不建立這個軟連結,當執行configure指令碼時會報下面的錯誤:

 

6. 修改configure

添加arm的PIE支援

找到下面的代碼:

將”i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD”更改為”i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD|arm-Linux”。

如果不這麼做的後果,使用”readelf -S qemu-arm”查看編譯出來的qemu-arm可執行檔的段,可以發現所有在運行時可載入段的地址均以0x60000000為基址。

在configure中有這麼一段代碼:

如果textseg_addr”這個命令列選項,這個命令列選項指定text段的基址。在指令碼的後面textseg_ldflags會被添加到ldflags中。

如果qemu-arm可載入段的基址為0x60000000,當qemu-arm在Android裝置上運行時將會發生”Segmentation fault”,詳情請參考Android上可執行ELF檔案中的段不能有基址。

 

7. 運行configure

 

命令列解析

configure指令碼會在終端輸出一些關鍵的資訊,如:用什麼編譯器,flags等。

 

PKG_CONFIG_PATH

上面命令中的PKG_CONFIG_PATH="$SYSROOT/usr/lib/pkgconfig"是必要的,如果不設定這個宏,configure指令碼輸出”CFLAGS”的內容見下:

 

關注”-I”後的路徑,首先說一下這個路徑是怎麼來的,configure指令碼中有下面的代碼:

 

“glib_cflags=$pkg_config --cflags $i“語句會獲得glib的包含目錄,看這篇文章的人如果電腦上安裝有glib2.0可以通過這個命令進行查看輸出內容:pkg-config –cflags glib-2.0。然而這個路徑並不是我想要的,因為我現在是交叉編譯,目標是ARM,所以我在這裡將一個新的pkgconfig目錄路徑設定到PKG_CONFIG_PATH宏,輸入下面的命令查看輸出內容:

 

輸出內容:

 

會發現此時”-I”後的路徑有了改變。

注意:pkgconfig是一個目錄,在這個目錄中包含了步驟5中安裝的依賴庫的資訊。

 

–target-list –cpu

–target-list arm-linux-user 意味著編譯出來的qemu程式用於user mode,可以執行arm指令,並且這個arm指令的可執行程式的執行環境基於linux系統。 
–cpu=arm 意味著編譯出的qemu程式只能在arm機器上執行。

 

–disable-system –disable-bsd-user

–disable-system:不編譯system mode的代碼。 
–disable-bsd-user:不編譯bsd user mode的代碼。

 

–cross-prefix

交叉編譯工具的首碼,在當前命令列中它的值為”arm-linux-androideabi-“,那麼configure指令碼會去尋找名為arm-linux-androideabi-gcc、arm-linux-androideabi-g++等工具。

 

–disable-tools

當命令列中有–disable-tools選項時,指令碼中的禁用want_tools宏將被設定為”no”,這個宏預設為”yes”。當want_tools宏為”yes”時,會對tools宏進行設定,下面是與want_tools有關的設定tools宏的代碼:

configure指令碼會將tools宏的內容寫入config-host.mak檔案。

 

–disable-guest-agent

當沒有這個選項時,編譯會報下面的錯誤:

為PC編譯qemu項目沒有這個命令選項時不會報這個錯誤,然而lockf函數在Android上並不存在,所以為Android編譯qemu項目時會報這個錯誤。

 

編譯錯誤排除ld: error: cannot find -lutil

將根目錄下的Makefile檔案中下面的內容注釋:

 

ifaddrs.h: No such file or directory

錯誤資訊

修複辦法:將這個連結中的源檔案都下載下來:android-ifaddrs,將下載下來的檔案拷貝到qga/目錄下。然後找到qga/Makefile.objs檔案,將”ifaddrs.o”插入”qga-obj-$(CONFIG_POSIX)”宏中。

 

mqueue.h: No such file or directory

錯誤資訊

修複辦法:將”#include <mqueue.h>”更改為”#include <linux/mqueue.h>”。

 

char __unused[128 - sizeof(target_sigset_t)];

錯誤資訊

修複辦法:將__unused更改為_unused。

 

syscall.c:4108:9: error: dereferencing pointer to incomplete type

錯誤資訊


修複辦法


改為

 

disas/arm-a64.cc:67: error: undefined reference to ‘__cxa_end_cleanup’

錯誤資訊


解決辦法 :在configure中找到下面的代碼:


將這些代碼注釋掉:

原因分析 :目前在Android NDK中沒有64位版本的object。

 

syscall.c中找不到符號

錯誤資訊

 解決辦法:在syscall.c檔案中寫下面的內容

 

編譯清理命令

執行下面兩個命令:

make clean

make distclean

 

編譯debug版

調用configure指令碼的命令列中添加”–enable-debug”命令選項。

 

作者:尋禹@阿里聚安全,更多技術文章,請訪問阿里聚安全部落格

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.