I am using a PPC750 and vxWorks. I am trying to copy a function outside of the text/data/bss segment into an unused portion of RAM and jump to it. The function to be copied contains no library calls or function calls. The executing function then copies a vxworks image from another location in user defined memory over top of the existing running image and jumps to it. Is this valid? People are telling me it should work but does not. When it jumps to the copied function in unused RAM I get the error "invalid instruction" and the task suspends. Listing the original function in the text segment, and the copied function in the unused portion of RAM show they are identical.
Can anyone help?
l copyImageAndBoot copyImageAndBoot 002ebf70 9421ffe0 stwu r1,-32(r1) 002ebf74 7c0802a6 mfspr r0,LR 002ebf78 93e1001c stw r31,28(r1) 002ebf7c 90010024 stw r0,36(r1) 002ebf80 7c3f0b78 or r31,r1,r1 002ebf84 907f0008 stw r3,8(r31) 002ebf88 3d20002f lis r9,0x2f # 47 002ebf8c 3869bfc8 addi r3,r9,0xbfc8 #
-16440 002ebf90 809f0008 lwz r4,8(r31) 002ebf94 38a00000 li r5,0x0 # 0 value = 0 = 0x0 l 0x00400000 00400000 9421ffe0 stwu r1,-32(r1) 00400004 7c0802a6 mfspr r0,LR 00400008 93e1001c stw r31,28(r1) 0040000c 90010024 stw r0,36(r1) 00400010 7c3f0b78 or r31,r1,r1 00400014 907f0008 stw r3,8(r31) 00400018 3d20002f lis r9,0x2f # 47 0040001c 3869bfc8 addi r3,r9,0xbfc8 #
-16440 00400020 809f0008 lwz r4,8(r31) 00400024 38a00000 li r5,0x0 # 0 value = 0 = 0x0
------------------------------------------------------- C O D E
------------------------------------------------------- #define MAX_BOOT_FUNC_SIZE 300 #define BOOT_FUNC_ADDRESS 0x00400000 #define VXWORKS_BOOT_ADDRESS 0x00010000 #define IMAGE_LOC ((unsigned char*)sysMemTop() + 0x8000)
typedef void (*ENTRYPOINT)(); typedef void (*COPYENTRYPOINT)(const void *);
void copyCodeAndRun(); void copyImageAndBoot(const void *src);
/* this function copies the copyImageAndBoot function outside of the existing running image and jumps to it
*/ void copyCodeAndRun() { COPYENTRYPOINT bootFunc = (COPYENTRYPOINT)BOOT_FUNC_ADDRESS;char *destPtr = (char *)BOOT_FUNC_ADDRESS; const char *srcPtr = (const char *)copyImageAndBoot; int i;
/* Copy the boot function to a place where it won't be overwritten by the new boot image. */ for( i = 0; i < MAX_BOOT_FUNC_SIZE; ++i ) destPtr[i] = srcPtr[i];
/* take control of CPU */ (void)intLock(); (void)taskLock();
/* execute copied code */ bootFunc( IMAGE_LOC );
}/* this function is copied to a location outside of the existing executing image. It then copies an alternate image over on top of the existing image and runs
*/ void copyImageAndBoot(const void *src) { ENTRYPOINT vxWorksBootAddr = (ENTRYPOINT)VXWORKS_BOOT_ADDRESS;/* Copy 5 MB in 4-byte chunks */ size_t length = (1024 * 1024 * 5) / 4; uint32_t *destPtr = (uint32_t *)VXWORKS_BOOT_ADDRESS; const uint32_t *srcPtr = (const uint32_t *)src;
/* Copy the new image over the current running image. */ while( length-- ) *destPtr++ = *srcPtr++;
/* Jump to the new image entry point. */ vxWorksBootAddr();