The previous blog in this series demonstrated how to add a custom OAL IOCTL to the BSP. In particular it implemented the IOCTL_HAL_GET_HIVE_CLEAN_FLAG IOCTL so that it returns a fixed value to the OS when called. In this blog, that code is extended to call the BSP boot args using a custom boot arg. A fixed value is returned by boot args  in this case. A later blog will pass that arg from eboot.

Context: This discussion is with respect to the Texas Instruments AM335X MPU as used with BeagleBone Black (BBB) and the Variscite VAR-SOM-AM33. This material was developed mainly with the latter but the BBB was also used in parts.

Previous Blog: TI AM335X Windows Embedded Compact Bootloader and Custom OAL IOTCLs


Relevant Files

  • <WERCOOT>\Platform\<BSP>\SRC\inc\ioctl_tab.h (Covered in previous blog)
    • Declare the IOTL
    • Add the IOCTL and its function name(as implemented in ioctl.c
  • <WECROOT>\Platform\<BSP>\SRC\OAL\oallib\iotlc.c (Covered in previous blog and extended here).
    • Implement the IOCTL with call to Args instead of "static" values.
  • C:\WINCE700\platform\common\src\soc\<BSP TI Common SOC Dir, eg COMMON_TI_V1_VSC>\COMMON_TI\INC\oalex.h
    • Add the custom arg
  • <WECROOT>\Platform\<BSP>\SRC\BSP_Common\args\args.c
    • Implement the custom arg

Add the Custom Arg

1. Insert the custom arg OAL_ARGS_QUERY_CLEAR_HIVE in oalex.h at the end of the list as highlighted in yellow::


#define OAL_ARGS_QUERY_ETHADDR_CPGMAC1  (BSP_ARGS_QUERY + 13)
#define OAL_ARGS_QUERY_SDRAMSZIE        (BSP_ARGS_QUERY + 14)
#define OAL_ARGS_QUERY_CLEAR_HIVE       (BSP_ARGS_QUERY + 15)

// must match the BOOT_CFG_OALFLAGS_... defines
#define OAL_ARGS_OALFLAGS_RETAILMSG_ENABLE  (1 << 0)


Note that custom args are defined from BSP_ARGS_QUERY. "This is the base value used to define BSP-specific arguments. Values smaller than this value (64) are reserved for the OAL library. The hardware platform implementation can use values beginning with BSP_ARGS_QUERY".

Implement the Custom Arg

WE will again use a fixed value in this blog but further up the tree.

2. In args.c find the declaration of the static global variable s_bInitialized and  insert the additional static global variable s_bClearHive initialized to TRUE as highlighted in yellow below:


static BOOL     = FALSE;

static BOOL     s_bClearHive = TRUE; //FALSE


3. In args.c insert the following switch case for arg type in OALArgsQuery():   


case OAL_ARGS_QUERY_SDRAMSZIE:
  pData = &pArgs->RamSize;
   break;

case OAL_ARGS_QUERY_CLEAR_HIVE:
   pData = (VOID *) &s_bClearHive;
   break;

     default:
         pData = NULL;
         break;


Get the Custom Arg from OAL IOCTL

4.Implement the new version of the the IOCTL using the code as below:
The key changes from the previous blog the calls to args is highlighted in red. Other changes are highlighted in yellow.


BOOL OALIoctlHalGetHivewCleanFlag(UINT32 code, VOID *pInBuffer, UINT32 inSize, VOID *pOutBuffer,
    UINT32 outSize, UINT32 *pOutSize)
{
   //case IOCTL_HAL_GET_HIVE_CLEAN_FLAG:
   BOOL fRet= TRUE;
   FILE * pFile= NULL;
   if ( (!pInBuffer) || ( inSize != sizeof(DWORD))
     || (!pOutBuffer) || (outSize != sizeof(DWORD)))
   {
         //SetLastError(ERROR_INVALID_PARAMETER);
         //No linkage for SetLstError()" ToDo
         RETAILMSG(1, (L"OEM: Not cleaning system/user hive\r\n"));
         fRet = FALSE;
    }
    else
    {
       DWORD *pdwFlags = (DWORD*)pInBuffer;
       BOOL  *pfClean  = (BOOL*) pOutBuffer;
       VOID  *OALData = NULL;
       if (*pdwFlags == HIVECLEANFLAG_SYSTEM) {
         *pfClean = TRUE;
          OALData= OALArgsQuery(OAL_ARGS_QUERY_CLEAR_HIVE);
          if (OALData == NULL)
          {
              *pfClean = FALSE;
              RETAILMSG(1, (L"OEM: OAL Args ERROR. NOT Clearing System Registry Hive\r\n"));
              fRet = FALSE;
          }
          else
          {
              BOOL  *pRetVal  = (BOOL*) OALData;
              BOOL retVal = *pRetVal;
              *pfClean = retVal;

              if (retVal )
                  RETAILMSG(1, (L"OEM: Clearing system hive\r\n"));
              else
                  RETAILMSG(1, (L"OEM: NOT Clearing system hive\r\n"));
          }

       } else if (*pdwFlags == HIVECLEANFLAG_USERS) {
         *pfClean = TRUE;
          OALData= OALArgsQuery(OAL_ARGS_QUERY_CLEAR_HIVE);
          if (OALData == NULL)
          {
              *pfClean = FALSE;
              RETAILMSG(1, (L"OEM: OAL Args ERROR. NOT Clearing User Registry Hive\r\n"));
              fRet = FALSE;
          }
          else
          {
              BOOL  *pRetVal  = (BOOL*) OALData;
              BOOL retVal = *pRetVal;
              *pfClean = retVal;

              if (retVal)
                  RETAILMSG(1, (L"OEM: Clearing User Regsitry Hive\r\n"));
              else
                  RETAILMSG(1, (L"OEM: NOT Clearing User Registry Hive\r\n"));
          }

       }
    }
    return fRet;
}


6. Rebuild the OS and test. Typical output::

16404 PID:400002 TID:5a0002 OEM: Clearing system hive
16405 PID:400002 TID:5a0002 FSREG: OEM forcing clean system hive!
16405 PID:400002 TID:5a0002 FSREG: Mounting clean system hive
16468 PID:400002 TID:5a0002 FSREG: Taking down boot registry.  Any open keys will be invalid.
16491 PID:400002 TID:5a0002 OEM: Clearing User Regsitry Hive
16492 PID:400002 TID:5a0002 FSREG: OEM forcing user hive cleanup!
16543 PID:400002 TID:5a0002 FSVOL: Using system database volume "NAND_Flash\Windows\Registry\default.vol"
16549 PID:400002 TID:5a0002 OEM: Clearing system hive
16550 PID:400002 TID:5a0002 FSVOL: OEM forcing clean system db volume!

7. In args.c change s_bClearHive  to be initialized to FALSE, rebuild and rerun. Typical ouput:

13884 PID:400002 TID:5a0002 OEM: NOT Clearing system hive
13907 PID:400002 TID:5a0002 FSREG: Mounted existing system hive
13907 PID:400002 TID:5a0002 FSREG: Taking down boot registry.  Any open keys will be invalid.
13911 PID:400002 TID:5a0002 OEM: NOT Clearing User Registry Hive
13933 PID:400002 TID:5a0002 FSVOL: Using system database volume "NAND_Flash\Windows\Registry\default.vol"
13934 PID:400002 TID:5a0002 OEM: NOT Clearing system hive

Discussion

These args are passed in RAM from eboot to the OS boot. eboot reads them from from flash or initializes them if not present there. The eboot menu permits temporary changes to them to made by the user through its menus.  Once changed, the user can make them permanent if they save the changes. An alternative would be for an OS function to directly change the stored flag in flash.To add OAL_ARGS_QUERY_CLEAR_HIVE to args passed between eboot and the OS we need to extend some structures as in the next blog in this series.