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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章