當前位置:首頁 » 編程軟體 » 交叉編譯busybox

交叉編譯busybox

發布時間: 2022-10-17 07:13:38

1. 如何建立android的C/C++交叉編譯環境

因此,構建android上C/C++的交叉編譯環境也就成為了一個很大的需求。特別是對於已經取得root許可權的機器,如果能直接運行按需編譯的二進制文件,那麼將可以做很多有意義和有趣的事情。 很不幸,Google沒有直接給出如何建立這個交叉編譯環境,但是我們可以藉助Google提供的強大的NDK (Native Development Tools)來達到這一目的。NDK的本來目標是編譯得到.so動態鏈接庫文件,然後通過JNI提供給上層的Java調用,從而實現C/C++程序的簡易遷移。而編譯.so和編譯成二進制可執行文件的過程是完全一樣的,這就給了我們可以發揮的空間。 有兩種方式獲取交叉編譯所需的工具鏈:git下prebuilt這個project或者直接去下載NDK,我這里arm-eabi的版本是最新的4.4.0。1 git clone git://android.git.kernel.org/platform/prebuilt.git 然後創建一個helloworld.c文件。1 2 3 4 5 6 //// root@delleon:~/android/myapp# cat helloworld.c#include int main(){printf("HelloWorld!n");return0;} 接下來創建Makefile文件。注意修改其中的NDK_DIR和SDKTOOL為自己的目錄,修改APP為自己的待編譯程序主文件名。另外注意自己的arm-eabi的版本,若有變化則也需要修改。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 #### root@delleon:~/android/myapp# cat Makefile APP=helloworld NDK_DIR := ~/android/android-ndk-r4 NDK_HOST := linux-x86 SDKTOOL := ~/android/android-sdk-linux_86/tools TOOLCHAIN_PREFIX :=$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/bin/arm-eabi- CC :=$(TOOLCHAIN_PREFIX)gcc CPP :=$(TOOLCHAIN_PREFIX)g++ LD :=$(CC) COMMON_FLAGS :=-mandroid -ffunction-sections -fdata-sections -Os -g --sysroot=$(NDK_DIR)/build/platforms/android-5/arch-arm -fPIC -fvisibility=hidden -D__NEW__ CFLAGS :=$(COMMON_FLAGS) CFLAGS +=-D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -DANDROID -DSK_RELEASE -DNDEBUG CFLAGS +=-UDEBUG -march=armv5te -mtune=xscale -msoft-float -mthumb-interwork -fpic -ffunction-sections -funwind-tables -fstack-protector -fmessage-length=0-Bdynamic CPPFLAGS :=$(COMMON_FLAGS)-fno-rtti -fno-exceptions -fvisibility-inlines-hidden LDFLAGS +=--sysroot=$(NDK_DIR)/build/platforms/android-5/arch-arm LDFLAGS +=-Bdynamic -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,noreloc LDFLAGS +=-L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0 LDFLAGS +=-L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/lib/gcc LDFLAGS +=-L$(NDK_DIR)/build/prebuilt/$(NDK_HOST)/arm-eabi-4.4.0/arm-eabi/lib LDFLAGS +=-nostdlib -lc -llog -lgcc --no-undefined -z $(NDK_DIR)/build/platforms/android-5/arch-arm/usr/lib/crtbegin_dynamic.o $(NDK_DIR)/build/platforms/android-5/arch-arm/usr/lib/crtend_android.o OBJS +=$(APP).o all:$(APP) $(APP):$(OBJS)$(LD)$(LDFLAGS)-o $@$^ %.o:%.c $(CC)-c $(CFLAGS)$

2. 我明明root了,可是還是裝不了busybox (手機是魅族,用自帶root)

首先我要告訴你,root過後,並不代表,獲取了許可權。需要獲取控制許可權的軟體APP。必須在,root裡面,設置通過許可權設置。才能正常使用該軟體的APP。如果你沒有授權的話,該軟體還是無法正常使用的。

3. busybox 1.16.1執行完make menuconfig設置了CROSS_COMPILE後執行make ARCH=arm

你直接make看能否過,感覺很像交叉編譯器沒有指定上。
另外,你可以先不執行make menuconfig的,直接make一下看文件是否完整。
還有,搞了make menuconfig後,最好再執行一次make clean清一下垃圾文件。

4. 如何利用busybox製作根文件系統

選定 busybox-1.9.2.tar.bz2 這個版本, 以靜態方式編譯, 即生成的 busybox 不需要共享庫的支持就能運行。這樣做我們就不需要布署程序庫了。缺點是自己寫的 arm-linux 程序在這個根文件系統中是不能運行的,因為缺少共享程序庫的支持。不過不用擔心,通過在目標機里以掛接 NFS 的方式, 將宿主機的 arm-linux-gcc 編譯器的庫文件掛到 arm-linux 的 /lib 下, 就可完美的運行我們自己的程序了。
現在開始製作靜態鏈接庫的根文件系統。

1、准備根文件系統
首先准備製作工具BusyBox1.9.2。
准備交叉編譯工具arm-linux-gcc 3.3.2。
在機器上建立rootfs的文件夾
#mkdir rootfs
在rootfs中建立linux系統中典型的文件夾
#cd rootfs
#mkdir root home bin sbin etc dev usr lib tmp mnt sys proc
#mkdir usr/lib usr/bin
#pwd
/home/su/rootfs
2、解壓源碼
#tar xjf busybox-1.9.2.tar.bz2
#cd busybox-1.9.2
3、修改 Makefile,
#vi Makefile
將Makefile中的
CROSS_COMPILE ?=
改為
CROSS_COMPILE ?= /usr/local/arm/3.3.2/bin/arm-linux-
注:這個版本的 busybox 用 3.4.1 的 arm-linux-gcc 編譯有些問題, 用 3.3.2 版則可順利編譯。
4、定製 busybox
選擇busybox下全部的可執行程序
#make defconfig
進到配置選項
#make menuconfig
設置靜態編譯方式
Busybox Settings ---> Build Options ---> [*] Build BusyBox as a static binary (no shared libs)
Busybox Settings ---> Install Options ---> 中輸入建立根文件系統的文件所在的路徑/home/su/rootfs。
其它的默認。
確保 [*] Build BusyBox as a static binary (no shared libs) 被選中,保存退出
5、執行 make 編譯
#make
編譯出錯, 信息如下:
applets/applets.c:15:2: warning: #warning Static linking against glibc proces buggy executables
applets/applets.c:16:2: warning: #warning (glibc does not cope well with ld --gc-sections).
applets/applets.c:17:2: warning: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
applets/applets.c:18:2: warning: #warning Note that glibc is unsuitable for static linking anyway.
applets/applets.c:19:2: warning: #warning If you still want to do it, remove -Wl,--gc-sections
applets/applets.c:20:2: warning: #warning from scripts/trylink and remove this warning.
applets/applets.c:21:2: error: #error Aborting compilation.
make[1]: *** [applets/applets.o] Error 1
按照提示,修改文件 applets/applets.c 第 21 行, 將
#error Aborting compilation.
注釋掉:
執行 make 重新編譯
#make
編譯通過, busybox 被生成了, 然後執行
#make install
busybox 就被安裝到指定的路徑下了/home/su/rootfs,這時可發現rootfs下多了個liunxrc的文件,bin、sbin下也多了很多文件。用ls –l命令查看其中的一個文件,可發現其是鏈接到busybox的一個連接符,所以我們之後在目標機上運行的命令大多都會調用busybox這個文件的。
若之前忘了指定路徑,默認生成到臨時目錄busybox-1.9.2/_install 下了。
6、編寫配置/etc下的初始化程序(可省略)
最簡單的做法是把busybox-1.9.2/examples/bootfloppy/etc下的全部文件拷到目標文件的etc目錄下
#cd /home/su/busybox-1.9.2/examples/bootfloppy/etc
#cp –rf * /home/su/rootfs/etc
也可自己寫這些文件。
7、把rootfs做成鏡像
#mkcramfs rootfs rootfs.cramfs
8、把rootfs.cramfs燒寫到目標機中。
9、運行目標機
這時會遇到一個錯誤信息:
Can』t open tty2
Can』t open tty3
Can』t open tty4
解決辦法:把/rootfs/etc/ inittab 文件的第三行「tty2::askfirst:-bin/sh」刪除掉。
返回到第7步重做。

現實中,動態編譯的方法更適合工程的需要,所以一般是採用動態的方法編譯根文件系統的。若選擇動態編譯的辦法,大體方法還是一樣的,存在一些不同之處是:
不同之處之一是:
進到配置選項
#make menuconfig
選擇動態方式
Busybox Settings ---> Build Options ---> [*] Build Shared libbusybox
不同之處之二是:
上面靜態編譯出現的出錯信息不會出現了,所以不需對程序做任何修改,但還是必須用arm-linux-gcc 3.3.2編譯,否則還是會有麻煩。
不同之處之三是(最大的不同之處):
編譯完成後,需進到rootfs目錄的lib中,往裡面添加一些庫文件
#cd /home/su/rootfs/lib
這里有點麻煩,我怎麼知道需要什麼庫文件的支持呢?
最簡單的辦法是把arm-linux-gcc 3.3.2下的整個lib庫拷進來,簡單省事。但是這么做存在一個問題,做出的根文件系統非常大。
另一個辦法是:
#cd /home/su/rootfs/bin
#arm-linux-readelf busybox | grep shared
這樣就可以顯示出系統運行起來需要什麼庫文件,再把相應的庫文件拷到/home/su/rootfs/lib下。一般而言,系統庫用到兩個:動態鏈接器ld-linux.so和c函數庫Glibc,Glibc包括:
ld-linux:動態鏈接庫,必需
libc: 標准c函數庫,必需
libm: 數學庫,一般需要
libdl: 用於動態裝載共享庫,較少用到
libcrypt: 加密附加庫,需要認證的程序用到,較少用
libpthread: POSIX線程庫,一般需要
如果需要某個函數庫,我們可以將這些庫和對應的符號鏈接拷到目標根文件系統的/lib目錄下。簡單起見,應該使用-d選項或-a選項調用cp命令,這樣可保留完整的符號鏈接信息。
例:
#cp –a libc.so.6 /home/su/rootfs/lib/
為了減少運行時庫的大小,我們應該使用交叉編譯版本即arm-linux-gcc 3.3.2的strip工具來處理根文件系統的庫文件,把二進制文件中的包含的符號表和調試信息刪除掉。
例:
#arm-linux-strip /home/su/rootfs/lib/*.so

注意:
使用busybox做文件系統時,運行make命令,系統會馬上顯示:
沒有/dev/null這個文件
但是還是能最終編譯出根文件系統,問題出在重啟linux系統,機器進不去了。提示出錯,信息如下:
/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 173:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 184:/dev/null: read-only file system
/etc/rc.d/rc.sysinit: line 200:/dev/null: read-only file system
.
.
.
***An error occured ring the file system check.
***Dropping you to a shell;the system will reboot
***when you leave the shell
Give root password for maintenance
(or type Control-D to continue):
解決辦法:
按提示輸入root用戶的密碼,回車,可看到
(Repair filesystem)1#:
依次輸入命令:
(Repair filesystem)1# mount -n -o remount,rw /
(Repair filesystem)1# rm -f /dev/null
(Repair filesystem)1# mknod -m 0666 /dev/null c 1 3
(Repair filesystem)1# reboot
問題解決。

5. 交叉編譯busybox顯示libc.so.6丟失!

拷貝C 庫
交叉應用程序的開發需要用到交叉編譯的鏈接庫,我們在移植應用程序到我們的目標板的時
候,需要把交叉編譯的鏈接庫也一起移植到目標板上,這里我們用到的交叉工具鏈的路徑是
/usr/local/arm/...../,鏈接庫的目錄是/usr/local/arm/...../arm-linux/lib,將其中部分庫文件及符號鏈接拷貝到root_nfs(你創建的busybox的根目錄)文件夾下的lib文件夾中。
部分庫文件及符號鏈接有:ld-2.3.2.so,ld-linux.so.2,libc-2.3.2.so,libc.so.6

6. 如何在Android模擬器下添加busybox

【具體步驟】:
1) 下載 busybox 源代碼,並解包
$ wget -c http://www點busybox點net/downloads/busybox-1.7.0.tar.bz2
$ tar jxvf busybox-1.7.0.tar.bz2

2) 下載交叉編譯工具,並安裝
我下載的是: arm-2009q1-161-arm-none-eabi.bin
說明:要正確設置好 PATH 變數。
例如將 「 你的目錄 」/CodeSourcery/Sourcery_G++_Lite/bin 加到 PATH 路徑中。

3 )進入到 busybox 解壓後的源文件目錄中,修改 Makefile
將第 176 行改為:
CROSS_COMPILE ?=arm-none-linux-gnueabi-

4 )進行編譯選項配置
a 、
$ make menuconfig
Busybox Settings --->
Build Options --->
[*] Build BusyBox as a static binary(no shared libs)


說明:這個選項一定要選,這樣才能把 busybox 編譯成靜態鏈接的可執行文件,運行時可以獨立於其他庫。

b 、
Installation Options --->
[*] Don't use /usr

說明:這個也一定要選,否則 make install 後, busybox 將安裝在原來系統的 /usr 下,將你原有的命令都覆蓋了!

5 )配置好後可以編譯了,執行如下命令:
$ make
發現沒過多久,就報錯了,暈,錯誤內容如下:
applets/applets.c:20:2: warning: #warning Static linking against glibc proces buggy executables
applets/applets.c:21:2: warning: #warning (glibc does not cope well with ld --gc-sections).
applets/applets.c:22:2: warning: #warning See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
applets/applets.c:23:2: warning: #warning Note that glibc is unsuitable for static linking anyway.
applets/applets.c:24:2: warning: #warning If you still want to do it, remove -Wl,--gc-sections
applets/applets.c:25:2: warning: #warning from top-level Makefile and remove this warning.
applets/applets.c:26:2: error: #error Aborting compilation.
make[1]: *** [applets/applets.o] 錯誤 1
make: *** [applets] 錯誤 2
看到它給出了提示,說 glibc 庫不適和用來靜態編譯,最後給出解決方案就是將 applets/applets.c 中這部分內容給去掉,也就是 19-27 行。

然後再 make 進行編譯。
不多久又報錯了,看看具體錯誤:
.../compal/CodeSourcery/Sourcery_G++_Lite/bin/../arm-none-linux-gnueabi/libc/usr/include/linux/netfilter.h:56:17: error: field 'in' has incomplete type
.../CodeSourcery/Sourcery_G++_Lite/bin/../arm-none-linux-gnueabi/libc/usr/include/linux/netfilter.h:57:18: error: field 'in6' has incomplete type
ipsvd/tcpudp.c: In function 'tcpudpsvd_main':
ipsvd/tcpudp.c:314:10: warning: ignoring return value of 'write', declared with attribute warn_unused_result
make[1]: *** [ipsvd/tcpudp.o] 錯誤 1
make: *** [ipsvd] 錯誤 2
看到說在我們下載的交叉編譯庫中有個頭文件中的 in 及 in6 類型不對,解決的辦法就是:
在 .../arm-none-linux-gnueabi/libc/usr/include/linux/netfilter.h 的開頭
添加缺少的頭文件:
#include <netinet/in.h>

然後再進行編譯。(這次可以安全到最後了,呵呵)
結束後會在當前目錄下看到 busybox 這個可執行文件。

6 )編譯步驟已完成,下面就將 busybox 這個可執行文件放到 Android 模擬器下去
$ adb push busybox /system/xbin
說明:若是出現什麼 read-only file system 等等之類,執行如下命令即可:
$ adb remount
要是老是不行,那就重新啟動 adb
$ adb kill-server
$ adb start-server

要是碰到什麼內存不足等等,那原因就是你的那個 Android 模擬器是用 Eclipse 打開的。解決辦法就是,手動啟動你的 Android emulator 模擬器,具體如下:
$ android list avd # 注釋:列出你所有的模擬器
$ emulator -avd your_emulator_name -partition-size 256

注意:最好放在 /system/xbin 下面,這樣當你在模擬器里使用 busybox 時不需要指定絕對路徑了,否則的話誰都會瘋掉嘛,呵呵。

7 )輸入 adb shell 進入終端,執行看看
# busybox --help
BusyBox v1.7.0 (2011-04-22 20:53:21 CST) multi-call binary
Copyright (C) 1998-2006 Erik Andersen, Rob Landley, and others.
Licensed under GPLv2. See source distribution for full notice.



說明:表明我們的 busybox 已經可以執行了。但同時又有一個問題,每次輸入一個命令都要加上 busybox ,那麼人又要瘋掉了, -_-! 。解決辦法就是,我想到可以使用 alias 命令嘛,給我們所有輸入的東西都自動加上 busybox ,具體如下:
【方法 1 】:
將你所感興趣的命令集中在一個腳本中打包,例如建立內容如下的腳本:
#!/bin/sh
# set_alias1.sh (當然你名字可以隨便改,越短越好,但不要和命令重名)

alias ls='busybox ls'
alias find='busybox find'


保存好後,將其 push 到模擬器中的 /system/xbin 下面,然後用 adb shell 進入到模擬器終端後執行如下命令:
# . set_alias1.sh # 注釋:在當前進行中執行該腳本(一定要有 " 點 " )


【方法 2 】:
以上方法雖然能解決問題,但總覺得添加這么多東西也怪煩人的,寫個智能點的腳本:
xxx:~/code/shellcode$ cat set_alias.sh
#!/bin/bash
# set_alias.sh

pre_handle_result=$(busybox echo -n $(busybox --help) | busybox grep -v '^/t')
pre_cmds=${pre_handle_result##*[[, }
sec_cmds=$(busybox echo -n $pre_cmds | busybox sed 's/,//g')

for cmd in $sec_cmds
do
# alias cmds
alias $cmd="busybox $cmd"
done
然後將其 push 到模擬器中的 /system/xbin 下,執行過程如上。

7. 編譯移植busybox出錯,arm-linux-gcc版本4.3.3 busybox版本1.16.0 錯誤代碼如下:

找不到鏈接庫,不這些都是數學庫,加參數 -lm 應該就能解決。
但編譯過程這個東西應該是自己加。

busybox 一般都是靜態的,編譯靜態程序,很多時候需要他以來的函數庫也是靜態的。你這個問題應該是編譯環境不匹配。你編譯了 uclibc 並且正確安裝了沒?

不過話說,不過是個編譯,人家本來就支持 arm ,「移植」這兩個字應該是不需要用了。

8. linux arm :我利用busybox製作根文件系統,啟動並進入內核後,為啥子用不了arm-linux-gcc等指令呢

進入內核後?你的意思是你的文件系統以及正常啟動嘍?
arm的嵌入式Linux系統裡面並不會有交叉編譯器,除非你自己編譯製作一個。
你給的貼圖是你編譯busybox時指定交叉編譯器的設置,這和你的嵌入式系統裡面有沒有這個沒有關系。

熱點內容
如何評價一個伺服器的性能 發布:2025-05-17 23:40:53 瀏覽:270
淘寶客適合什麼伺服器 發布:2025-05-17 23:39:26 瀏覽:612
python循環文件 發布:2025-05-17 23:39:22 瀏覽:828
androidstudio更新 發布:2025-05-17 23:38:22 瀏覽:643
java項目面試 發布:2025-05-17 23:30:53 瀏覽:780
若主存儲器按位元組編址 發布:2025-05-17 23:30:46 瀏覽:24
kotlinandroid 發布:2025-05-17 23:19:09 瀏覽:974
雲編程英語 發布:2025-05-17 23:18:34 瀏覽:623
androidstudio導入類 發布:2025-05-17 23:15:36 瀏覽:237
私人電腦伺服器如何設置 發布:2025-05-17 23:14:48 瀏覽:366