编译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 来执行。