編譯android內核不優化
㈠ arm跑android和linux哪個效率更高,大概能夠高多少(cortex-a9)
Android和linux兩個不是同一個等級的東西,linux是內核,android是運行在linux之上的應用,或者叫操作系統因此,ARM平台,肯定是運行linux效率要高。
1.ARM架構,過去稱作進階精簡指令集機器(Advanced RISC Machine,更早稱作:Acorn RISC Machine),是一個32位精簡指令集(RISC)處理器架構,其廣泛地使用在許多嵌入式系統設計。由於節能的特點,ARM處理器非常適用於行動通訊領域,符合其主要設計目標為低耗電的特性。
2.ARM就當作一款超強的單片機,可以單機跑程序,也可加操作系統。如果要加操作系統,通常是指linux,當然還有別的可選,比如WinCE,uC/OS等等。
3.Android是用java編寫和應用操作系統,而Android的低層是Linux,因此,Linux的運行效率肯定比它的應用效率要高的。
㈡ android 怎麼不優化開機開啟
一 軟體准備:
blcr-0.8.2
android2.2froyo
android-goldfish-2.6.29
http://sourceforge.net/projects/android-dfb/pthread的補丁
編譯android和內核在這里不詳述,需要指出的有兩點。
1 編譯內核時候注意加入可載入模塊支持(Enable loadablemole support),預設的goldfish內核配置是不支持的。
2 需要對android的bionic的線程庫進行擴展,擴展方法是採用上述軟體的pthread文件替換相應線程庫文件。
二 編譯blcr的內核驅動模塊和應用直接使用android內建的編譯器即可對內核驅動進行編譯。編譯過程只要指定正確的編譯器路徑和內核路徑即可順利編譯。生成的內核可載入模塊分別是:
cr_mole/kbuild/blcr.ko
blcr_imports/kbuild/blcr_imports.ko
順利編譯blcr應用部分需要使用打過擴展補丁的pthread。補丁方法為直接取代bionic目錄下對應文件,並且修改bionic/libc/Android.mk,開啟對應的編譯開關,在libc_common_cflags加入-DUCLIBC_LINUXTHREAD_OLD_EXTENSTION宏。
Blcr文件也需要如下修改才能正常編譯和運行。
其中文件libcr/cr_libinit.c:
rc = __cri_ksigaction(signum, (act ?&ksa : NULL), (oact ? &oksa : NULL), (_NSIG/8), &errno);改動為:
rc = __cri_ksigaction(signum, (act ?&ksa : NULL), (oact ? &oksa : NULL), (_NSIG/4), &errno);
將_NSIG/8改動為_NSIG/4修改的原因為在bionic中定義NSIG=32,而內核為64,造成kernel/signal.c中rt_sigaction調用認為參數錯誤而返回錯誤。在android系統中對應非prelink的動態庫調用dlopen(NULL, RTLD_LAZY);(即查找自己)會異常,需要屏蔽cr_libinit.c函數cri_init對dlopen的調用。
在blcr工程中加入Android.mk,需要注意的是下面幾個文件需要編譯為arm而非預設的thumb指令:cr_async.c. cr_core.c cr_sig_sync.c cr_cs.c cr_syscall.c,否則編譯無法通過。
三 zygote加入checkpoint 支持 當系統啟動zygote服務時候先判斷是否存在checkpoint文件,如果有則調用cr_restart載入保存的checkpoint文件,否則按照正常的zygote流程進行。由於zygote是其他android的父進程,其生成的許多進程/線程都有socket等checkpoint無法恢復的限制因素,故不適合將checkpoint放到zygote啟動過後點,本文選擇在ZygoteInit.Java的main後面的preloadResources()完成後進行。這個過程剛好載入完畢耗時長的公用類而且基本沒有使用很多限制資源。原生的android在preload前有創建socket動作,可以調整到preloadResources後面,調整後的樣子如下(斜體代碼為調整順序部分):
CheckPoint cp=newCheckPoint();
try {
//Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
preloadClasses();
preloadResources();
cp.checkPoint("/data/zygote.blcr");
registerZygoteSocket();
其中CheckPoint 類是c擴展的java調用介面,通過jni調用checkpoint庫函數實現checkpoint動作,下文列出了jni部分內容。該部分僅為一個參考模板,產品化過程應該做更多異常處理和合理化調整工作。
android_blcr_checkpoint.cpp
#defineLOG_TAG "BLCR"
namespaceandroid {
staticint my_callback(void* arg)
{
int rc;
LOGV(__FUNCTION__);
rc = cr_checkpoint(0);
return 0;
}
staticvoid checkPoint(JNIEnv* env, jobject object,jstring file) {
LOGV(__FUNCTION__);
pid_t my_pid;
int rc,fd;
struct stat s;
cr_checkpoint_handle_t my_handle;
cr_callback_id_t cb_id;
FILE *f;
const jchar* str =env->GetStringCritical(file, 0);
String8 filename;
if (str) {
filename = String8(str,env->GetStringLength(file));
env->ReleaseStringCritical(file,str);
}
else {
LOGE("checkPoint,file nameis null");
return;
}
LOGI("checkPoint,filename=%s",filename);
//does the file exist?
f = fopen(filename, "r");
if(f==NULL) //create and save checkpointto it.
{
my_pid = cr_init();
if(my_pid<0)
{
LOGE("cr_initfailed,return:%d",my_pid);
return;
}
cb_id =cr_register_callback(my_callback, NULL, CR_SIGNAL_CONTEXT);
if (cb_id < 0)
{
LOGV("cr_register_callback() unexpectedly returned %d/n",cb_id);
return;
}
else
{
LOGV("cr_register_callback() correctly returned %d/n", cb_id);
}
/* Request a checkpoint of ourself */
fd =crut_checkpoint_request(&my_handle, filename);
if (fd < 0)
{
LOGE("crut_checkpoint_request() unexpectedly returned 0x%x/n",fd);
return ;
}
rc = stat(filename, &s);
if (rc) {
LOGE("stat() unexpectedly returned%d/n", rc);
return;
} else {
LOGV("stat(context.%d) correctlyreturned 0/n", my_pid);
}
if (s.st_size == 0) {
LOGE("context file unexpectedlyempty/n");
return;
} else {
LOGV("context.%d isnon-empty/n", my_pid);
}
/* Reap the checkpoint request */
rc = crut_checkpoint_wait(&my_handle,fd);
if (rc < 0) {
LOGE("crut_checkpoint_wait() #1unexpectedly returned 0x%x/n", rc);
return;
} }}
/*
* JNI registration.
*/
staticJNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{"checkPoint","(Ljava/lang/String;)V", (void *)checkPoint},
};
intregister_android_blcr_checkpoint(JNIEnv* env)
{
return jniRegisterNativeMethods(env,"android/blcr/CheckPoint",
gMethods, NELEM(gMethods));
}
}
為了正常使用上面的jni介面,需要把注冊函數注冊到frameworks/base/core/jni/ AndroidRuntime.cpp,在gRegJNI[]中加入REG_JNI(register_android_blcr_checkpoint)。同時創建CheckPoint.java 文件提供給java調用:
packageandroid.blcr;
publicclass CheckPoint {
public CheckPoint() {
}
public native void checkPoint(String fileName);
}
正常啟動blcr還需要修改init.rc,調整啟動zygote的方式。修改點包括載人blcr內核驅動:
insmod/system/lib/moles/blcr_imports.ko
insmod/system/lib/moles/blcr.ko
和啟動blcr服務方式,將
servicezygote /system/bin/app_process -Xzygote /system/bin --zygote--start-system-server
替換為:service zygote/system/bin/quick.sh -Xzygote /system/bin --zygote --start-system-server
其中quick.sh腳本內容為:
#!/system/bin/busybox sh
ec()
{
/system/bin/busybox echo $* >/dev/console;
}
if [ -f /data/zygote.blcr ]; then
ec"***************load saved zygote********************"
/system/bin/cr_restart -f /data/zygote.blcr ;
else
ec"optimised by blcr"
ec"**************start a new zygote******************"
ec"you can contact the author through Email:[email protected]"
ec"this is only an original demon version"
ec"release pid:$$."
/system/bin/cr_checkpoint
ec"release pid:$$."
/system/bin/cr_checkpoint
ec"release pid:$$."
/system/bin/app_process $*
fi
需要指出的是運行上面幾個不帶參數的cr_checkpoint目的為將後面的zygote的pid退後一些,以防下次checkpoint時候遇到pid沖突而導致checkpoint失敗。
加入該功能後當系統首次啟動會創建/data/zygote.blcr文件,由於需要checkpoint,導致比正常啟動時間慢較多。後續只要該文件存在,系統就會跨過類載入過程,進而加快啟動速度。
㈢ 請問學android開發有必要學編譯原理嗎
知道編譯就好,幫助不是很大,主要還是多學習android的sdk吧!
㈣ 整體編譯Android系統,大家用了多少時間
我自己實際編譯ICS4.0.4源碼情況:acer台式機,3.2Ghz cpu,4核,8GB/1600hz內存,整體編譯(含u-boot、kernel、boot.img和system.img)需要1小時10分鍾。編譯時,使用make -j8(因為硬體cpu是4線程的,故使用2倍線程數)。之後的增量編譯,一般需要5~10分鍾即可。
㈤ 關於android和x86的幾點疑問。 android基因linux內核,系統除了內核還有其他什麼
android 除了基於 Linux 內核,他的上層運行環境和相關函數庫,命令程序都是自己的。
其實 android 就是一個基於 Linux 內核的 JAVA 虛擬機環境。
實際 Android 程序都是基於 JAVA 虛擬機跑的解釋型語言程序。
但解釋型語言程序性能肯定不如本地二進製程序。所以 Android 還有一種 NDK 程序。
也就是 Android 裡面有部分本地二進製程序的內容。這樣本地程序方式運行,效率可以最高而且可以根據 CPU 功能做優化(比如 neon )。
指令集不同,但他的 JAVA 虛擬機是解釋型語言,基於 JAVA 語言的程序是可以無差別運行的。只要能保證 Android 上面的 JAVA 虛擬機可以在 x86 上面成功運行就行了。
但 Android 有個另外的問題,就是 JAVA 虛擬機是針對 ARM 做性能優化的,在 X86 上面,這種性能優化都沒了,需要另外在 x86 上面重新優化。但聽說 Android 的 JAVA 虛擬機的語言裡面,也有針對 ARM 硬體進行的修改設計,所以這種針對 ARM 性能優化的 JAVA 程序,在 X86 的系統上面性能也有損失。
所以 Android 出來很久後,在 x86 上面的運行效率都一直不怎麼樣。
而且現在還有 NDK 程序的出現, ARM 的二進製程序在 x86 上面是不能運行的。這些程序都不能運行。
不過 x86 有個優勢就是自己的性能很強,而且模擬器技術現在也很強了。在 x86 上面,可以藉助虛擬機(qemu 的 user mode 就值得看看)來運行 ARM 的二進製程序。
不過虛擬機其實還是有性能損失的。
所以未來,Android 的跨 CPU 架構依然還是問題。純 JAVA 程序好說,用了 NDK 的程序就是問題了。
不過 llvm 這個編譯器又給了另外一條路,既可以虛擬機方式運行,又可以編譯成本地程序而成為二進製程序來優化性能運行。或許 Android 會考慮使用這種方法或者類似的讓 NDK 程序可以跨 CPU 實現。代價是 Android 要自帶一個編譯器,體積也不小的。
MAC OS X 還有一種方法。在 MAC 放棄 IBM 的 Power CPU 而改用 Intel 的 CPU 後,他的程序都是裡面附帶兩套二進製程序,老的 G4 CPU 的機器,就用程序裡面的 power 指令集的程序代碼。新的 Intel CPU 的機器,就自動用裡面的 x86 指令來運行程序。從而實現完美的雙指令集運行。不過代價是這樣的程序都是兩套指令集的內容,體積翻倍。
目前來說,似乎用了 NDK 的程序還都不能用的。不排除現在某些 x86 的手機,使用了虛擬機技術來實現運行 NDK 程序。現在 Linux 下面的 qemu 的 usermode 配合內核的 binfmt_misc 功能,可以讓系統自動識別某個架構的程序,去調用 qemu 來執行。