none
How is data being marshaled in the kernel? RRS feed

  • Question

  • How is data being marshaled in the kernel?

     

    What is the maximum size of memory that is marshaled between user space and kernel space when calling into the OALLib?

     

    We added functionality to the OALLib to be able to update the bootloader in flash using a memory pointer. This works when called in eboot and when called from kernel space, but it throws an exception when called from user space.

     

    We updated oalioctl.cpp to allow our IOControls to be called from user space via KernelIOControl.

     

    We added an IO Control handler to the list in oemioctl.h.

    Source: Platform\DaVinci\Src\OAL\OalLib\Ioctl.c

    BOOL IoCtlHalLoadBootloaderFromBuffer( UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize )
    {
       DWORD LoadBootloaderFromBuffer( BYTE *pbyBuffer );
       DWORD *pdwReturn = (DWORD *)pOutBuffer;
       DWORD *pdwSize = (DWORD *)pOutSize;
     
     
       if( (pInpBuffer == NULL) || (inpSize != IMAGE_BOOT_BLDRIMAGE_FLASH_SIZE) || (pOutBuffer == NULL) || (outSize < sizeof( DWORD )) || (pOutSize == NULL) )
       {
          NKSetLastError(ERROR_INSUFFICIENT_BUFFER);
          return FALSE;
       }
       
       *pdwReturn = LoadBootloaderFromBuffer( (BYTE *)pInpBuffer );
       *pdwSize = sizeof( DWORD );
    
       return TRUE;
    }
    
    
    

     

    The pointer in the application is allocated with malloc and I can see the pointer getting marshaled. The pointer address being passed in is 0x180244E0 and received in the IOControl function as 0x1801EE44. Before calling the flash function, if I add a test to loop through the memory (buffer size is 256k), I can access the buffer with no problem up to 0x18025000. I have tried adjusting the pointer being passed in so that it is more aligned (0x18070000), but get the same marshaled address and the same data abort when the buffer is accessed at 0x18025000.

     

    Since this code is in the OALLib, I do not have access to most of the memory functions (CeAllocAsynchronousBuffer, VirtualAllocEx, ProbeForRead, MmMapIoSpace, etc.)  If I move the code to a driver and call DeviceIoControl, it does not have any problems with the buffer size. But we still have several functions that need to be called from KernelIoControl and now have concerns about what kind of limitations there are with the memory marshalling used by the kernel and possible future problems that might result from us not knowing what those limitations are. Small buffers seem to work fine, but what if they happen to be too close to a boundary?

     

     
    Tuesday, October 19, 2010 6:42 PM

All replies

  • Maybe the questions should be:

    1. What is the difference in data marshalling between KernelIoControl and DeviceIoControl when called from an user-mode application?
    2. What are the limitations on buffer sizes when using KernelIoControl?
    3. How can an IoControl function in the OalLib verify that a marshaled buffer is safe to access? (Or make it safe to access?)
    4. If a call from a user-mode application passes a reference to a DWORD to KernelIoControl for the OAL IO Control function to write data to, will there ever be a condition that it will cause a data abort error?
    Wednesday, October 20, 2010 2:41 PM
  • How about just one simple question then:

     

    Is data marshaled the same when an application calls KernelIoControl versus when an application calls DeviceIoControl?

    Thursday, October 21, 2010 6:02 PM
  • There is some sort of difference between KernelIoControl and DeviceIoControl.

    Its been a while so I'm a bit fuzzy; but on CE 6.0 IIRC if you set up your KernelIoControl to be accessible from user-space you could no longer call it from kernel-space due to some issue with how the memory was being mapped.

    I didn't have any issues with accessing it from user-space though.  We also sent raw data and didn't have any embedded pointers.  The input size matched the size of the input buffer, and the output size matched the size of our output buffer.  Our buffer size was only 4-bytes so a lot less than yours.

    Good luck,

    Thursday, October 21, 2010 6:25 PM