none
BusEnum and async loading of device drivers Data Alignment error. RRS feed

  • Question

  • I have been following the following link http://msdn.microsoft.com/en-us/library/dd187254.aspx and http://geekswithblogs.net/BruceEitman/archive/2008/11/12/windows-ce-enhanced--busenum.aspx to enhance the BusEnum in an attempt to get explorer to load earlier in the CE boot process. I am using WinCE6 R3 on an iMX25.

    I am having issues compiling and executing the newer code - I keep getting a Data Mis-alignment runtime errors with the changes implemented.

    The 1st thing I changed was the 

    const DWORD m_dwMaxInitReg
    

     value in the DefBus2.h by removing the const as I was receiving C4512: assignment operator could not be generated.

    It now compiles without any issues but when the code goes to execute ActivateAllChildDrivers() the first time, which had been working, I now get a data Misalignment error. I understand that on an ARM device that would imply that I have a function pointer or something similar that's address in not 32-bit aligned and the call is failing.

    But strangely the call it is making is

    DEBUGMSG(ZONE_ENUM,(TEXT("ActivateChild: Template reg path is %s\r\n"),pCurDevice->GetRegPath()));
    

    where pCurDevice->GetRegPath() is equal to 0xC0543A04 and pCurDevice->m_lpTemplateRegPath is equal to 0xD0047620 which are both 32-bit aligned, but when I put a breakpoint on the DEBUGMSG and then run into a breakpoint in GetRegPath() the member values of the class are all rubbish -> ie m_lpTemplateRegPath equals 0xbffff7ff which of course is completely not 32-bit aligned. When I look at the address of this in the GetRegPath breakpoint the value is completely different to the address of pCurDevice too.

    Would anyone know where have I gone wrong?

    PS I also attempted to set WARNISERROR=0 so the code compiles as the same as defbus.h in the public tree must have done the same but that didn't work either.

    In that situation the memory location for m_hAsyncLoadThread is the same as m_dwInitRegArray and the i receive the following error:

    RegReadActivationValues RegQueryValueEx(Drivers\BuiltIn\XXX\BusPrefix) returned 2
    Exception 'Data Abort' (4): Thread-Id=01f80002(pth=87d95000), Proc-Id=00400002(pprc=8291baa0) 'NK.EXE', VM-active=018a0002(pprc=87dfe8ac) 'shell.exe'
    PC=c021eb04(filesys.dll+0x0001eb04) RA=c021e950(filesys.dll+0x0001e950) SP=d079f348, BVA=00000000
    ERROR: C:\ymzki\private\winceos\COREOS\filesys\reg\reghive\..\regapi.c line 2206: FS: Hive Exception Handler
    DEVICE!RegInitActiveKey: RegSetValueEx(0x01f90003) returned 87.
    DEVICE!I_ActivateDeviceEx: couldn't activate: prefix XXX, index 1, dll XXXX.dll, context 0x730079
    
    It is actually attempting to set a registry value at the address of the sync thread which happens to not be 32-bit aligned...
    And in this situation I delayed the driver by 10secs as per the links above and I'm pretty certain the flash is ready.
    Wednesday, September 29, 2010 7:59 AM

Answers

  • Actually, there is a bug in this BusEnum2 driver.
    The BUSENUM2 only defined in BUSENUM2\BUSDEF\sources but not in BUSENUM2\BUSENUM\sources.
    The DeviceFolder is implemented in BUSENUM2\BUSDEF but the instance is created in BUSENUM2\BUSENUM\busenum.cpp, so the result is it allocates less memory than actual need.

    Add

    CDEFINES=$(CDEFINES) -DBUSENUM2

    into BUSENUM2\BUSENUM\sources should fix the problem.

     

    • Marked as answer by Barak14 Tuesday, October 5, 2010 3:29 AM
    Monday, October 4, 2010 9:44 PM

All replies

  • I am a little concerned that you cite my blog as a source of information about this.  My blog post was about back porting the busenum2 sample from CE 6 back to CE 5.

    I have not tested it against CE 6 R3, but your first test should have been to test busenum2 unchanged.  That would give you a baseline test.  Then make your changes, if needed at all.


    Bruce Eitman (eMVP)
    Senior Engineer
    Bruce.Eitman AT Eurotech DOT com
    My BLOG http://geekswithblogs.net/bruceeitman

    Eurotech Inc.
    www.Eurotech.com
    Friday, October 1, 2010 2:07 PM
    Moderator
  • Actually, there is a bug in this BusEnum2 driver.
    The BUSENUM2 only defined in BUSENUM2\BUSDEF\sources but not in BUSENUM2\BUSENUM\sources.
    The DeviceFolder is implemented in BUSENUM2\BUSDEF but the instance is created in BUSENUM2\BUSENUM\busenum.cpp, so the result is it allocates less memory than actual need.

    Add

    CDEFINES=$(CDEFINES) -DBUSENUM2

    into BUSENUM2\BUSENUM\sources should fix the problem.

     

    • Marked as answer by Barak14 Tuesday, October 5, 2010 3:29 AM
    Monday, October 4, 2010 9:44 PM
  • Thanks for the help, so easy to miss things like that.

    One thing I have noticed is that the PostInit is never called in the second instance of busenum so it doesn't actually do anything if you spawn it. I had to add the following for it to work at the end of AssignChildDriver():

    LPTSTR Async = L"Drivers\\BuiltIn\\AsyncBus";
      
    if ( strcmp((const char *)Async, (const char *)m_lpActiveRegPath ) == 0 )
      PostInit();
    else
      DEBUGMSG(ZONE_INIT,(TEXT("AssignChildDriver: %s\r\n"), m_lpActiveRegPath));
    
    return TRUE;
    
    }
    
    Other than that small change the delayed loading is working great.
    Wednesday, October 6, 2010 1:20 AM
  • The PostInit is the worker function of IOCTL_BUS_POSTINIT IOCTL handler, so instead of hardcode calling PostInit in AssignChildDriver, I would use the following registry to indicate device manager to send out post init ioctl call.

    [HKLM\Drivers\BuiltIn\AsyncBus]
        "BusIoctl"=dword:2a0048

    Also you may want to take a look at the IOCTL_BUS_POSTINIT handler in BUSENUM2\BUSDEF\defbus.cpp
    And more further, you can dig into the private\winceos\coreos\device\devcore\devload.c to trace how device manger dispatch these POST INIT codes.

    Wednesday, October 6, 2010 5:52 PM