android 可执行程序终于可以在nxp8473--cortex-a9平台运行

 

现在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.csdn.net/linweig

 

你可能感兴趣的:(thread,android,properties,平台,Descriptor,returning)