Samraksh / eMote

eMote OS -- Multiple Ports (using .NET MF v4.3)
0 stars 0 forks source link

multi-app switching #19

Open MichaelAtSamraksh opened 11 years ago

MichaelAtSamraksh commented 11 years ago

Support switching between multiple applications on reboot.

MichaelAtSamraksh commented 11 years ago

Switching between multiple deployment blocks is feasible but it wastes space and requires hardware-specific re-work of the loading system which could compilicate future porting efforts and storage systems. Also, I don't fully understand how adding multiple deployment areas will affect debugger operation through MFDeploy and Visual Studio yet. TinyCLR's startup iterates through all block storage devices and loads all assemblies stored in "BlockStorage::Deployment" block types, so that complicates simply using two separate deployment areas. There is a solution that should be cross-hardware compatible. The solution should be driver-independent. Therefore, I am inserting into CLRStartup.cpp's Settings::ContiguousBlockAssemblies(...) function a gatekeeper to check whether we want to skip loading an assembly based on the assembly's name. The check happens after the header has been read (to populate the assembly name), but before the assembly is linked into the global CLR TypeSystem. Skipped assemblies that are non-XIP will be unloaded right before continuing to the next assembly. This solution is compatible with having multiple deployment blocks (e.g. SD expansion). However, the config's storage requirement has changed - either the string or a hash needs to be kept in the config section to determine what assemblies to load (and also whether to use the gatekeeper and persist the gatekeeper through the next reboot - this allows naive usage and backwards-compatibility with debugging behavior). I am staying away from using the assembly's checksum for now because it is my understanding those are not currently used and also because using the assembly name allows the gatekeeper to report a human-readable list of available and deactivated assemblies. The next question is how to store the assemblies-- whether additional PE files may be laid out sequentially in memory or whether the PE files need to be added to a DAT database in the flash. Based on debugger protocol messages, I'm guessing there is a facility for either option but this will require additional reading. In the meantime, the metadataprocessor can create DAT files from multiple PE files for testing.

NivedAtSamraksh commented 11 years ago

Din't creating a separate region and calling it BlockStorage::Deployment2 work ?. I thought that is what we were planning to do.

mukundansridharan commented 11 years ago

Mike, Looks like you have changed the design that the 3 of us agreed on. Can you explain this new design sometime. Ping me on Skype. -Mukundan

MichaelAtSamraksh commented 10 years ago

So the short of it is: TinyCLR starts execution in the last PE in memory that has an entry point.

KennethAtSamraksh commented 10 years ago

I use to the boater starting in the first PE with an entry point … Any insights …

Kenneth

From: MichealAtSamraksh [mailto:notifications@github.com] Sent: Friday, February 21, 2014 5:23 PM To: Samraksh/MF Subject: Re: [MF] multi-app switching (#19)

So the short of it is: TinyCLR starts execution in the last PE in memory that has an entry point.

— Reply to this email directly or view it on GitHubhttps://github.com/Samraksh/MF/issues/19#issuecomment-35780166.

MichaelAtSamraksh commented 10 years ago

Ken, thanks for asking for clarification; maybe you are referring to TinyBooter which I haven't examined. In my tests, TinyCLR starts execution at the last PE with an entry point. This post should come in handy when we want to support concurrent app execution or modify wireless reprogramming. Here is the definitive long explanation:

  1. The behavior can be observed at a high level when ApplicationEntryPoint() calls CLRStartup.cpp's Load() function that firstly loads assemblies packaged with TinyCLR, and secondly calls LoadDeploymentAssemblies(BlockUsage::DEPLOYMENT). LoadDeploymentAssemblies(...) looks for XIP assemblies and continues loading all (4-byte aligned) contiguous assemblies in the deployment region.
  2. Then ApplicationEntryPoint() calls ClrStartup() which sets variable g_CLR_RT_TypeSystem.m_entryPoint by calling ClrStartup() --> Settings::Load() -- --> CLR_RT_TypeSystem::ResolveAll() -- -- --> CLR_RT_Assembly::Resolve_MethodDef() * Note, function ResolveAll() loops over all loaded assemblies in the order created in function LoadDeploymentAssemblies() which happens to be the order the assemblies are laid out in memory. * Note, variable m_entryPoint is overwritten each time Resolve_MethodDef() is fed a PE method that contains PE descriptor flag CLR_RECORD_METHODDEF::MD_EntryPoint. So actually, TinyCLR starts execution in the last method containing an MD_EntryPoint flag loaded from the deployment region in low to high address order. In the case of two PE files in the deployment region, each containing a method with MD_EntryPoint flag, the assembly with higher starting address will be executed.
  3. Then ClrStartup() calls g_CLR_RT_ExecutionEngine.Execute( NULL, params.MaxContextSwitches ). Execute() starts execution in the PE method that variable m_entryPoint indexes in the the method table.
    • For switching between applications at TinyCLR boot, we can search for methods with flag MD_EntryPoint and then choose which method to set m_entryPoint, based on additional criteria (like MFUpdate metadata or additional field in COFF header.)
    • Variable m_entryPoint is an index into the method definitions table (ask Mukundan for clarification.) Execute() calls CreateInstance() which assigns m_ftn = m_entryPoint and then the interpreter uses function DelegateFtn() to access CLR_RT_HeapBlock_Delegate.m_ftn( the entry point method's index) in various places like CLR_RT_ExecutionEngine::SpawnStaticConstructor() and CLR_RT_Thread::Execute_IL().
    • Also we might be able to include a default assembly in the TinyCLR that contains a method with an entry point that handles empty deployment regions more gracefully (i.e., switch to MFUpdate mode and send a message to the control plane network asking for an update.)

I first tested this around March 9, 2013, and I ran a quick test February 24, 2014 that confirms the behavior. MetaDataProcessor.exe can be used to pack multiple apps into a single 4-byte-aligned DAT to place the deployment region. MetaDataProcessor.exe follows the order specified in the create_database input parameter's "Bill of Materials" text file.