copy function and run it

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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();


Re: copy function and run it

Quoted text here. Click to load it

You must be sure that this part of memory is marked as executable
w.r.t. the MMU (I don't know about vxworks how to check or do this).

Quoted text here. Click to load it

Your code must be aware of the harvard architecture of PPC L1 caches
(i.e. without coherency of the L1 instruction cache):
Before jumping to the new code it must be flushed from the data caches,
e.g. using dcbf instructions, and the corresponding address range must
be invalidated in the instruction cache, using icbi instructions.
The jump will then cause loading of the new code into instruction cache
and execute it. Otherwise behaviour is undefined.

Quoted text here. Click to load it

Good.


I don't know, depends on vxworks behaviour....

Quoted text here. Click to load it

Do you have more error status of the CPU (exception number, srr0, srr1
registers) ?


Rob


Re: copy function and run it



Quoted text here. Click to load it

I am not particularly familiar with the specifics of VxWorks, however I
did the things similar to what you are trying to do. Yes, it is
possible, however it requires a lot of care.

1. Make sure your function is properly linked. I.e. the code is placed
at one location, and it is supposed to run from the other location.

2. There could be some agreement on the run time environment required to
execute a function. Make sure the environment is correct at the location
where the function is executed.

3. A compiler could have optimized your function away as a dead code.

4. It could be a problem with near/far memory access model depending on
your CPU.

5. Make sure that the location in the RAM is not used by anything else.
You should define it as the dedicated section in the linker file.



Vladimir Vassilevsky

DSP and Mixed Signal Design Consultant

http://www.abvolt.com

Site Timeline