public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Gao, Liming" <liming.gao@intel.com>
To: david moheban <moheban79@gmail.com>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: WARNING: No source level debug
Date: Fri, 8 Sep 2017 05:29:03 +0000	[thread overview]
Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14D78BB4D@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <CADxnD1xw3YHKcwQRhzfmWgiTwTebTWecL2SUwGUS8BNmrLbGzA@mail.gmail.com>

Please check the debuglib instance. 

MdeModulePkg.dsc sets DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf. This library instance prints the debug message to Console. 
Nt32.dsc sets DebugLib|MdeModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf. This library instance prints the debug message to StatusCode. The StatusCode service prints the debug message into the different StatusCode handlers. NT32 has its WinNtOemHookStatusCodeHandler. So, you can see the message log. 

Thanks
Liming
>-----Original Message-----
>From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
>david moheban
>Sent: Friday, September 08, 2017 12:03 PM
>To: edk2-devel@lists.01.org
>Subject: [edk2] WARNING: No source level debug
>
>Hi,
>
>Was having trouble getting the debug messages to show in the debug log list
>in the developer window that launches the simulated shell window. I started
>out following the driver building edk2 lab pdf instructions in building one
>of the test drivers. In the lab they have you enter the debug macro such as
>"DEBUG (L"[mydriver] Feature unsupported\r\n") and when the Nt32Pkg is
>compiled by issuing build and thus 'build run' that Debug message shows up
>in the developer window and message logs.
>
>Later I tried my hand at making another driver and compiled it like this:
>'build -p mdemodulepkg\mdemodulepkg.dsc -m mydriver\mydriver.inf'.
>Next I
>tried to issue a 'build run -p mdemodulepkg\mdemodulepkg.dsc' and at first
>failed to run secmain vm until I copied the secmain utility manually to the
>mdemodule build directory and then that worked. The problem I noticed was
>that those 'Debug' messages werent going through with MdeModulePkg and
>were
>just appearing on the shell window as if you typed 'Print'.
>
>At first I thought maybe it was my driver code or the Inf file or header
>file was missing something but running 'build -p nt32pkg' allowed all my
>Debug macro messages to appear on the developer window debug logs and I
>didn't get this 'Warning: No source level debug' error message in the logs.
>
>Also I added to
>[PCDfixedAtBuild]
>gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000040.
>This only allowed debug messages showing up in the shell and not in the
>other developer window logs as it should be. Heres my driver code though
>the fault is not with the code as it works when compiled against Nt32Pkg:
>
>Inf File:
>
>[Defines]
>  INF_VERSION               = 0x00010005
>  BASE_NAME                 = EmptyDriver
>  FILE_GUID                 = 785a3ef0-9016-11e7-a9b3-acd1b8bf61e6
>  MODULE_TYPE               = UEFI_DRIVER
>  VERSION_STRING            = 1.0
>  ENTRY_POINT               = EmptyDriverDriverEntryPoint
>  UNLOAD_IMAGE              = EmptyDriverUnload
>  UEFI_HII_RESOURCE_SECTION = TRUE
>
>[Packages]
>  MdePkg/MdePkg.dec
>  MdeModulePkg/MdeModulePkg.dec
>  #IntelFrameworkPkg/IntelFrameworkPkg.dec
>  #IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
>
>[Packages]
>  MdePkg/MdePkg.dec
>  MdeModulePkg/MdeModulePkg.dec
>
>[Sources]
>  EmptyDriver.h
>  EmptyDriver.c
>  ComponentName.c
>  ComponentName.h
>
>  SimpleTextOutput.c
>  SimpleTextOutput.h
>
>[LibraryClasses]
>  UefiDriverEntryPoint
>  UefiBootServicesTableLib
>  MemoryAllocationLib
>  BaseMemoryLib
>  BaseLib
>  UefiLib
>  DevicePathLib
>  DebugLib
>
>[Protocols]
>  gEfiDriverBindingProtocolGuid
>  gEfiPciIoProtocolGuid
>  gEfiDriverSupportedEfiVersionProtocolGuid
>  gEfiHiiPackageListProtocolGuid
>  gEfiHiiDatabaseProtocolGuid
>  gEfiComponentName2ProtocolGuid
>  gEfiComponentNameProtocolGuid
>  gEfiHiiConfigAccessProtocolGuid
>  gEfiSimpleTextOutProtocolGuid
>  gEfiSerialIoProtocolGuid
>  gEfiSimpleTextInputExProtocolGuid
>
>[Guids]
>
>[Depex]
>AFTER gFvSimpleFileSystemDxeGuid
>
>
>
>Header File:
>
>
>#ifndef __EFI_EMPTY_DRIVER_H__
>#define __EFI_EMPTY_DRIVER_H__
>
>
>#include <Uefi.h>
>
>//
>// Libraries
>//
>#include <Library/UefiBootServicesTableLib.h>
>#include <Library/MemoryAllocationLib.h>
>#include <Library/BaseMemoryLib.h>
>#include <Library/BaseLib.h>
>#include <Library/UefiLib.h>
>#include <Library/DevicePathLib.h>
>#include <Library/DebugLib.h>
>#include <Library/PrintLib.h>
>
>
>
>//
>// UEFI Driver Model Protocols
>//
>#include <Protocol/DriverBinding.h>
>#include <Protocol/HiiDatabase.h>
>#include <Protocol/HiiPackageList.h>
>#include <Protocol/DriverSupportedEfiVersion.h>
>#include <Protocol/ComponentName2.h>
>#include <Protocol/ComponentName.h>
>#include <Protocol/HiiConfigAccess.h>
>#include <Protocol/SimpleFileSystem.h>
>
>//
>// Consumed Protocols
>//
>#include <Protocol/PciIo.h>
>#include <Protocol/SerialIo.h>
>
>//
>// Produced Protocols
>//
>#include <Protocol/SimpleTextOut.h>
>#include <Protocol/SimpleTextInEx.h>
>
>
>
>//
>// Guids
>//
>
>//
>// Driver Version
>//
>#define EMPTY_DRIVER_VERSION  0x00000000
>
>//
>// Protocol instances
>//
>extern EFI_DRIVER_BINDING_PROTOCOL  gEmptyDriverDriverBinding;
>extern EFI_COMPONENT_NAME2_PROTOCOL
>gEmptyDriverComponentName2;
>extern EFI_COMPONENT_NAME_PROTOCOL  gEmptyDriverComponentName;
>
>//
>// Include files with function prototypes
>//
>#include "DriverBinding.h"
>#include "ComponentName.h"
>#include "SimpleTextOutput.h"
>
>#endif
>
>
>driver.C file:
>**/
>
>#include "EmptyDriver.h"
>
>
>static CHAR16* FileMemPath = L"\\file.efi";
>
>EFI_HANDLE MainImageHandle = NULL;
>
>#define SafeFree(p) do { FreePool(p); p = NULL;} while(0)
>
>
>
>
>
>///
>/// Driver Support EFI Version Protocol instance
>///
>GLOBAL_REMOVE_IF_UNREFERENCED
>EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL
>gEmptyDriverDriverSupportedEfiVersion = {
>  sizeof (EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL),
>  0x0002001E
>};
>
>///
>/// Driver Binding Protocol instance
>///
>EFI_DRIVER_BINDING_PROTOCOL gEmptyDriverDriverBinding = {
>  EmptyDriverDriverBindingSupported,
>  EmptyDriverDriverBindingStart,
>  EmptyDriverDriverBindingStop,
>  EMPTY_DRIVER_VERSION,
>  NULL,
>  NULL
>};
>
>/**
>  Unloads an image.
>
>  @param  ImageHandle           Handle that identifies the image to be
>unloaded.
>
>  @retval EFI_SUCCESS           The image has been unloaded.
>  @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
>
>**/
>EFI_STATUS
>EFIAPI
>EmptyDriverUnload (
>  IN EFI_HANDLE  ImageHandle
>  )
>{
>  EFI_STATUS  Status;
>  EFI_HANDLE  *HandleBuffer;
>  UINTN       HandleCount;
>  UINTN       Index;
>
>  Status = EFI_SUCCESS;
>  //
>  // Retrieve array of all handles in the handle database
>  //
>  Status = gBS->LocateHandleBuffer (
>                  AllHandles,
>                  NULL,
>                  NULL,
>                  &HandleCount,
>                  &HandleBuffer
>                  );
>  if (EFI_ERROR (Status)) {
>    return Status;
>  }
>
>  //
>  // Disconnect the current driver from handles in the handle database
>  //
>  for (Index = 0; Index < HandleCount; Index++) {
>    Status = gBS->DisconnectController (HandleBuffer[Index], gImageHandle,
>NULL);
>  }
>
>  //
>  // Free the array of handles
>  //
>  FreePool (HandleBuffer);
>
>  //
>  // Uninstall protocols installed in the driver entry point
>  //
>  Status = gBS->UninstallMultipleProtocolInterfaces (
>                  ImageHandle,
>                  &gEfiDriverBindingProtocolGuid,
> &gEmptyDriverDriverBinding,
>                  &gEfiComponentNameProtocolGuid,
> &gEmptyDriverComponentName,
>                  &gEfiComponentName2ProtocolGuid,
>&gEmptyDriverComponentName2,
>                  NULL
>                  );
>  if (EFI_ERROR (Status)) {
>    return Status;
>  }
>
>  //
>  // Uninstall Driver Supported EFI Version Protocol onto ImageHandle
>  //
>  Status = gBS->UninstallMultipleProtocolInterfaces (
>                  ImageHandle,
>                  &gEfiDriverSupportedEfiVersionProtocolGuid,
>&gEmptyDriverDriverSupportedEfiVersion,
>                  NULL
>                  );
>  if (EFI_ERROR (Status)) {
>    return Status;
>  }
>
>  //
>  // Do any additional cleanup that is required for this driver
>  //
>
>  return EFI_SUCCESS;
>}
>
>/**
>  This is the declaration of an EFI image entry point. This entry point is
>  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers
>including
>  both device drivers and bus drivers.
>
>  @param  ImageHandle           The firmware allocated handle for the UEFI
>image.
>  @param  SystemTable           A pointer to the EFI System Table.
>
>  @retval EFI_SUCCESS           The operation completed successfully.
>  @retval Others                An unexpected error occurred.
>**/
>EFI_STATUS
>EFIAPI
>EmptyDriverDriverEntryPoint (
>  IN EFI_HANDLE        ImageHandle,
>  IN EFI_SYSTEM_TABLE  *SystemTable
>  )
>{
>//#pragma warning(disable:4101)
>   // #pragma warning(disable:4189)
>EFI_DEVICE_PATH *DevicePath;
>
>EFI_HANDLE  DriverHandle, *Handles = NULL;
>UINTN  HandleCount = 0, Index = 0;
>EFI_GUID  gsguid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
>EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* Volume;
>EFI_FILE_HANDLE Root;
>CHAR16 *DeviceStr = NULL;
>//EFI_BOOT_SERVICES *BS = NULL;
>
>    DEBUG ((EFI_D_INFO, "[EmptyDriver] About to start empty driver \r\n") );
>EFI_STATUS  Status;
>
>    //BS = SystemTable->BootServices;
>    MainImageHandle = ImageHandle;
>
>
>  Status = EFI_SUCCESS;
>
>  //
>  // Install UEFI Driver Model protocol(s).
>  //
>  Status = EfiLibInstallDriverBindingComponentName2 (
>             ImageHandle,
>             SystemTable,
>             &gEmptyDriverDriverBinding,
>             ImageHandle,
>             &gEmptyDriverComponentName,
>             &gEmptyDriverComponentName2
>             );
>  ASSERT_EFI_ERROR (Status);
>
>  //
>  // Install Driver Supported EFI Version Protocol onto ImageHandle
>  //
>  Status = gBS->InstallMultipleProtocolInterfaces (
>                  &ImageHandle,
>                  &gEfiDriverSupportedEfiVersionProtocolGuid,
>&gEmptyDriverDriverSupportedEfiVersion,
>                  NULL
>                  );
>  ASSERT_EFI_ERROR (Status);
>
>  Status = gBS->LocateHandleBuffer(ByProtocol, &gsguid,
>NULL, &HandleCount, &Handles);
>  ASSERT_EFI_ERROR (Status);
>
>  for (Index = 0; Index < HandleCount; Index++) {
>// Note: The Device Path obtained from DevicePathFromHandle() should NOT
>be
>freed!
>DevicePath = DevicePathFromHandle(Handles[Index]);
>DeviceStr = ConvertDevicePathToText(DevicePath, FALSE, FALSE);
>//DeviceStr = DevicePathToStr(DevicePath);
>if (DevicePathSubType(DevicePath) != HW_MEMMAP_DP) {
>continue;
>}
>else {
>break;
>}
>}
>DEBUG ((EFI_D_ERROR, "About to load  file \r\n") );
>/*
>if (Index >= HandleCount) {
>Status = EFI_NOT_FOUND;
>goto out;
>}
>*/
>Status = gBS->LocateHandleBuffer(ByProtocol,
>&gsguid,
>NULL,
>&HandleCount,
>&Handles);
>if (EFI_ERROR(Status)) {
>goto out;
>}
>Status = gBS->HandleProtocol(
>Handles[1],
>&gsguid,
>(void**)&Volume);
>Root = NULL;
>Status = Volume->OpenVolume(Volume, &Root);
>    if ((EFI_ERROR(Status)) || (Root == NULL)) {
>goto out;
>}
>DevicePath = FileDevicePath(Handles[1], FileMemPath);
>if (DevicePath == NULL) {
>Status = EFI_DEVICE_ERROR;
>goto out;
>}
>Status = gBS->LoadImage(FALSE, ImageHandle, DevicePath, NULL, 0,
>&DriverHandle);
>SafeFree(DevicePath);
>if (EFI_ERROR(Status)) {
>goto out;
>}
>Status = gBS->StartImage(DriverHandle, NULL, NULL);
>if (EFI_ERROR(Status)) {
>goto out;
>}
>
>out:
>SafeFree(Handles);
>
>  return Status;
>}
>
>/**
>  Tests to see if this driver supports a given controller. If a child
>device is provided,
>  it further tests to see if this driver supports creating a handle for the
>specified child device.
>
>  This function checks to see if the driver specified by This supports the
>device specified by
>  ControllerHandle. Drivers will typically use the device path attached to
>  ControllerHandle and/or the services from the bus I/O abstraction
>attached to
>  ControllerHandle to determine if the driver supports ControllerHandle.
>This function
>  may be called many times during platform initialization. In order to
>reduce boot times, the tests
>  performed by this function must be very small, and take as little time as
>possible to execute. This
>  function must not change the state of any hardware devices, and this
>function must be aware that the
>  device specified by ControllerHandle may already be managed by the same
>driver or a
>  different driver. This function must match its calls to AllocatePages()
>with FreePages(),
>  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
>  Because ControllerHandle may have been previously started by the same
>driver, if a protocol is
>  already in the opened state, then it must not be closed with
>CloseProtocol(). This is required
>  to guarantee the state of ControllerHandle is not modified by this
>function.
>
>  @param[in]  This                 A pointer to the
>EFI_DRIVER_BINDING_PROTOCOL instance.
>  @param[in]  ControllerHandle     The handle of the controller to test.
>This handle
>                                   must support a protocol interface that
>supplies
>                                   an I/O abstraction to the driver.
>  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a
>device path.  This
>                                   parameter is ignored by device drivers,
>and is optional for bus
>                                   drivers. For bus drivers, if this
>parameter is not NULL, then
>                                   the bus driver must determine if the bus
>controller specified
>                                   by ControllerHandle and the child
>controller specified
>                                   by RemainingDevicePath are both
>supported by this
>                                   bus driver.
>
>  @retval EFI_SUCCESS              The device specified by ControllerHandle
>and
>                                   RemainingDevicePath is supported by the
>driver specified by This.
>  @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle
>and
>                                   RemainingDevicePath is already being
>managed by the driver
>                                   specified by This.
>  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle
>and
>                                   RemainingDevicePath is already being
>managed by a different
>                                   driver or an application that requires
>exclusive access.
>                                   Currently not implemented.
>  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle
>and
>                                   RemainingDevicePath is not supported by
>the driver specified by This.
>**/
>EFI_STATUS
>EFIAPI
>EmptyDriverDriverBindingSupported (
>  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
>  IN EFI_HANDLE                   ControllerHandle,
>  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
>  )
>{
>
>  EFI_STATUS Status;
>EFI_SERIAL_IO_PROTOCOL *SerialIo;
>Status = gBS->OpenProtocol (
>ControllerHandle,
>&gEfiSerialIoProtocolGuid,
>(VOID **) &SerialIo,
>This->DriverBindingHandle,
>ControllerHandle,
>EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE
>);
>if (EFI_ERROR (Status)) {
>DEBUG ((EFI_D_INFO, "[EmptyDriver] Not  Supported \r\n") );
>return Status; // Bail out if OpenProtocol returns an error
>}
>// We're here because OpenProtocol was a success, so clean up
>gBS->CloseProtocol (
>ControllerHandle,
>&gEfiSerialIoProtocolGuid,
>This->DriverBindingHandle,
>ControllerHandle
>);
>
>DEBUG ((EFI_D_INFO,"[MyWizardDriver] Supported SUCCESS\r\n") );
>return EFI_SUCCESS;
>
>
>
>
>  //return EFI_UNSUPPORTED;
>}
>
>/**
>  Starts a device controller or a bus controller.
>
>  The Start() function is designed to be invoked from the EFI boot service
>ConnectController().
>  As a result, much of the error checking on the parameters to Start() has
>been moved into this
>  common boot service. It is legal to call Start() from other locations,
>  but the following calling restrictions must be followed, or the system
>behavior will not be deterministic.
>  1. ControllerHandle must be a valid EFI_HANDLE.
>  2. If RemainingDevicePath is not NULL, then it must be a pointer to a
>naturally aligned
>     EFI_DEVICE_PATH_PROTOCOL.
>  3. Prior to calling Start(), the Supported() function for the driver
>specified by This must
>     have been called with the same calling parameters, and Supported()
>must have returned EFI_SUCCESS.
>
>  @param[in]  This                 A pointer to the
>EFI_DRIVER_BINDING_PROTOCOL instance.
>  @param[in]  ControllerHandle     The handle of the controller to start.
>This handle
>                                   must support a protocol interface that
>supplies
>                                   an I/O abstraction to the driver.
>  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a
>device path.  This
>                                   parameter is ignored by device drivers,
>and is optional for bus
>                                   drivers. For a bus driver, if this
>parameter is NULL, then handles
>                                   for all the children of Controller are
>created by this driver.
>                                   If this parameter is not NULL and the
>first Device Path Node is
>                                   not the End of Device Path Node, then
>only the handle for the
>                                   child device specified by the first
>Device Path Node of
>                                   RemainingDevicePath is created by this
>driver.
>                                   If the first Device Path Node of
>RemainingDevicePath is
>                                   the End of Device Path Node, no child
>handle is created by this
>                                   driver.
>
>  @retval EFI_SUCCESS              The device was started.
>  @retval EFI_DEVICE_ERROR         The device could not be started due to a
>device error.Currently not implemented.
>  @retval EFI_OUT_OF_RESOURCES     The request could not be completed
>due
>to a lack of resources.
>  @retval Others                   The driver failded to start the device.
>
>**/
>EFI_STATUS
>EFIAPI
>EmptyDriverDriverBindingStart (
>  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
>  IN EFI_HANDLE                   ControllerHandle,
>  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
>  )
>{
>  return EFI_UNSUPPORTED;
>}
>
>/**
>  Stops a device controller or a bus controller.
>
>  The Stop() function is designed to be invoked from the EFI boot service
>DisconnectController().
>  As a result, much of the error checking on the parameters to Stop() has
>been moved
>  into this common boot service. It is legal to call Stop() from other
>locations,
>  but the following calling restrictions must be followed, or the system
>behavior will not be deterministic.
>  1. ControllerHandle must be a valid EFI_HANDLE that was used on a
>previous call to this
>     same driver's Start() function.
>  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a
>valid
>     EFI_HANDLE. In addition, all of these handles must have been created
>in this driver's
>     Start() function, and the Start() function must have called
>OpenProtocol() on
>     ControllerHandle with an Attribute of
>EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
>
>  @param[in]  This              A pointer to the
>EFI_DRIVER_BINDING_PROTOCOL instance.
>  @param[in]  ControllerHandle  A handle to the device being stopped. The
>handle must
>                                support a bus specific I/O protocol for the
>driver
>                                to use to stop the device.
>  @param[in]  NumberOfChildren  The number of child device handles in
>ChildHandleBuffer.
>  @param[in]  ChildHandleBuffer An array of child handles to be freed. May
>be NULL
>                                if NumberOfChildren is 0.
>
>  @retval EFI_SUCCESS           The device was stopped.
>  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a
>device error.
>
>**/
>EFI_STATUS
>EFIAPI
>EmptyDriverDriverBindingStop (
>  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
>  IN EFI_HANDLE                   ControllerHandle,
>  IN UINTN                        NumberOfChildren,
>  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
>  )
>{
>  return EFI_UNSUPPORTED;
>}
>_______________________________________________
>edk2-devel mailing list
>edk2-devel@lists.01.org
>https://lists.01.org/mailman/listinfo/edk2-devel


  reply	other threads:[~2017-09-08  5:26 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-08  4:02 WARNING: No source level debug david moheban
2017-09-08  5:29 ` Gao, Liming [this message]
  -- strict thread matches above, loose matches on Subject: below --
2017-09-08 17:33 david moheban
2017-09-11  3:03 ` Gao, Liming

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A89E2EF3DFEDB4C8BFDE51014F606A14D78BB4D@shsmsx102.ccr.corp.intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox