现在android 的可执行程序终于可以在nxp8473--cortex-a9平台运行了,其中直接的原因是: 由于宏定义errno造成的-------非法访问内存地址 bionic/libc/bionic/libc_init_common.c void __libc_init_common(uintptr_t *elfdata) { int argc = *elfdata; char** argv = (char**)(elfdata + 1); char** envp = argv + argc + 1; pthread_attr_t thread_attr; static pthread_internal_t thread; static void* tls_area[BIONIC_TLS_SLOTS]; /* setup pthread runtime and maint thread descriptor */ unsigned stacktop = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; unsigned stacksize = 128 * 1024; unsigned stackbottom = stacktop - stacksize; pthread_attr_init(&thread_attr); pthread_attr_setstack(&thread_attr, (void*)stackbottom, stacksize); _init_thread(&thread, gettid(), &thread_attr, (void*)stackbottom); __init_tls(tls_area, &thread); /* clear errno - requires TLS area */ errno = 0; /* set program name */ __progname = argv[0] ? argv[0] : "<unknown>"; /* setup environment pointer */ environ = envp; /* setup system properties - requires environment */ __system_properties_init(); } 下面来对errno进行扩展 bionic/libc/include/errno.h /* internal function returning the address of the thread-specific errno */ extern volatile int* __errno(void); /* a macro expanding to the errno l-value */ #define errno (*__errno()) bionic/libc/bionic/__errno.c volatile int* __errno( void ) { return &((volatile int*)__get_tls())[TLS_SLOT_ERRNO]; } 看来最终原因是在__get_tls()上: bionic/libc/private/bionic_tls.h /* get the TLS */ #ifdef __arm__ /* Linux kernel helpers for its TLS implementation */ /* For performance reasons, avoid calling the kernel helper * Note that HAVE_ARM_TLS_REGISTER is build-specific * (it must match your kernel configuration) */ # ifdef HAVE_ARM_TLS_REGISTER # define __get_tls() / ({ register unsigned int __val asm("r0"); / asm ("mrc p15, 0, r0, c13, c0, 3" : "=r"(__val) ); / (volatile void*)__val; }) # else /* !HAVE_ARM_TLS_REGISTER */ # define __get_tls() ( *((volatile void **) 0xffff0ff0) ) # endif #else extern void* __get_tls( void ); #endif 由上面的说明可知道这和kernel 的配置有关系 所以我就找nxp kernel 有关TLS 有关的配置因此也就找到了 CONFIG_HAS_TLS_REG=y,而android下面编译时没有加HAVE_ARM_TLS_REGISTER宏定 义所以只选择了 # define __get_tls() ( *((volatile void **) 0xffff0ff0) ) 从而结果出现了非法访问内存出现了段错误 因此我把nxp kernel 的配置又重新做了一遍把CONFIG_HAS_TLS_REG去掉 这样生成的kernel镜像可以跑android的可执行程序。 上诉仅仅是一个解决的方法,
另一个解决方法就是把CONFIG_HAS_TLS_REG选上同时android 下的编译宏定义要进行声明 ARCH_ARM_HAVE_TLS_REGISTER := true
TARGET_ARCH_VARIANT := armv7-a这样也是可行的。
---------------------转载请指出出处--------------------------------http://hi.youkuaiyun.com/linweig