diff --git a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
index 246820a08..558dac7b2 100644
--- a/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
+++ b/BaseTools/Source/C/VfrCompile/VfrUtilityLib.cpp
@@ -3280,7 +3280,7 @@ CVfrStringDB::GetVarStoreNameFormStringId (
   UINT8       BlockType;
   EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
   
-  if (mStringFileName == '\0' ) {
+  if (mStringFileName == NULL ) {
     return NULL;
   }
 
diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c
index 91de3658c..078dd1831 100644
--- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c
+++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.c
@@ -213,6 +213,14 @@ HandleBoot (
   // We don't really have any choice but to report success, because once we
   // boot we lose control of the system.
   SEND_LITERAL ("OKAY");
+  
+  Status = BootEfiBootableImg (mNumDataBytes, mDataBuffer);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "Unable to run kernel image as application: %r\n", Status));
+  } else {
+    DEBUG ((EFI_D_ERROR, "WARNING: Kernel image is unbootable application!\n"));
+    return;
+  }
 
   Status = BootAndroidBootImg (mNumDataBytes, mDataBuffer);
   if (EFI_ERROR (Status)) {
diff --git a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h
index f62660feb..791c03d1d 100644
--- a/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h
+++ b/EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.h
@@ -29,6 +29,12 @@ BootAndroidBootImg (
   IN  VOID    *Buffer
   );
 
+EFI_STATUS
+BootEfiBootableImg (
+  IN UINTN     BufferSize,
+  IN VOID      *Buffer
+  );
+
 EFI_STATUS
 ParseAndroidBootImg (
   IN  VOID    *BootImg,
diff --git a/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c
index d4e1904d7..206b0a34f 100644
--- a/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c
+++ b/EmbeddedPkg/Application/AndroidFastboot/Arm/BootAndroidBootImg.c
@@ -14,13 +14,21 @@
 
 #include "AndroidFastbootApp.h"
 
+#include <Protocol/Bds.h>
 #include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/DevicePathToText.h>
 
 #include <Library/BdsLib.h>
 #include <Library/DevicePathLib.h>
 
 #include <Guid/ArmGlobalVariableHob.h>
 
+#include <Library/UefiBootServicesTableLib.h>
+
+#define NOBOOT L"VenHw(B549F005-4BD4-4020-A0CB-06F42BDA68C3)/HD(6,GPT,5C0F213C-17E1-4149-88C8-8B50FB4EC70E,0x7000,0x20000)/\\EFI\\BOOT\\NOBOOT.efi"
+
 // Device Path representing an image in memory
 #pragma pack(1)
 typedef struct {
@@ -124,3 +132,80 @@ BootAndroidBootImg (
   DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n"));
   return EFI_SUCCESS;
 }
+
+EFI_STATUS
+BootEfiBootableImg (
+  IN UINTN         BufferSize,
+  IN VOID          *Buffer
+  )
+{
+  EFI_STATUS                          Status;
+  CHAR8                               KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE];
+  VOID                               *Kernel;
+  UINTN                               KernelSize;
+  VOID                               *Ramdisk;
+  UINTN                               RamdiskSize;
+  EFI_HANDLE                          ImageHandle;
+  MEMORY_DEVICE_PATH                  ImageDevicePath;
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
+  EFI_DEVICE_PATH                    *BootDevicePath;
+  
+  Status = ParseAndroidBootImg (
+            Buffer,
+            &Kernel,
+            &KernelSize,
+            &Ramdisk,
+            &RamdiskSize,
+            KernelArgs
+            );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  DEBUG ((EFI_D_ERROR, "WARNING: Ignoring Ramdisk Argument.\n"));
+  
+  ImageDevicePath = MemoryDevicePathTemplate;
+  
+  ImageDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel;
+  ImageDevicePath.Node1.EndingAddress   = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize;
+  
+  Status = gBS->LoadImage (
+                  FALSE, 
+                  gImageHandle, 
+                  (EFI_DEVICE_PATH_PROTOCOL *) &ImageDevicePath, 
+                  Kernel, 
+                  KernelSize, 
+                  &ImageHandle
+                  );
+  if (EFI_ERROR (Status)) {
+    if (AsciiStrLen (KernelArgs) > 0) {
+
+      if (AsciiStrCmp (KernelArgs, "mode=32bit") == 0) {
+
+        Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
+        if (EFI_ERROR(Status)) {
+          DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathFromTextProtocol\n"));
+          
+          return EFI_SUCCESS;
+        }
+        
+        BootDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)NOBOOT);
+        
+        DEBUG ((EFI_D_ERROR, "Running NOBOOT.efi with kernel: 0x%lx (0x%lx)\n", Kernel, KernelSize));
+        BdsStartEfiApplication (gImageHandle, BootDevicePath, KernelSize, Kernel);
+
+        return EFI_SUCCESS;
+      }
+    }
+
+    return Status;
+  }
+
+  Status = gBS->StartImage (ImageHandle, 0, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "WARNING: The application terminated with: %r\n", Status));
+  }
+
+  gBS->UnloadImage(ImageHandle);
+  return EFI_SUCCESS;
+}
diff --git a/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.c b/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.c
index dc2da1044..472fea333 100644
--- a/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.c
+++ b/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.c
@@ -177,6 +177,12 @@ HiKeyEntryPoint (
   HiKeyInitBootDevice ();
   HiKeyInitPeripherals ();
 
+  // Try to install the Flat Device Tree (FDT). This function actually installs the
+  // UEFI Driver Binding Protocol.
+  Status = HiKeyFdtInstall (ImageHandle);
+  if (EFI_ERROR (Status))
+    return Status;
+
   Status = HiKeyBootMenuInstall ();
 
   return Status;
diff --git a/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf b/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf
index a16ecaa40..895bac682 100644
--- a/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf
+++ b/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/HiKeyDxe.inf
@@ -23,6 +23,7 @@
 [Sources.common]
   HiKeyDxe.c
   InitPeripherals.c
+  InstallFdt.c
   InstallBootMenu.c
 
 [Packages]
@@ -38,6 +39,7 @@
   CacheMaintenanceLib
   DebugLib
   DxeServicesTableLib
+  FdtLib
   IoLib
   PcdLib
   PrintLib
@@ -52,6 +54,7 @@
   gEfiEndOfDxeEventGroupGuid
   gEfiFileInfoGuid
   gEfiGlobalVariableGuid
+  gFdtTableGuid
   gArmPlatformUpdateFdtEventGuid
 
 [Protocols]
diff --git a/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InstallFdt.c b/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InstallFdt.c
new file mode 100644
index 000000000..7bcd0506c
--- /dev/null
+++ b/HisiPkg/HiKeyPkg/Drivers/HiKeyDxe/InstallFdt.c
@@ -0,0 +1,445 @@
+/** @file
+*
+*  Copyright (c) 2014-2015, ARM Limited. All rights reserved.
+*  Copyright (c) 2015, Linaro Limited. All rights reserved.
+*  Copyright (c) 2015, Hisilicon Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "HiKeyDxeInternal.h"
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/BdsLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Guid/ArmGlobalVariableHob.h>
+#include <Guid/ArmPlatformEvents.h>
+#include <Guid/EventGroup.h>
+#include <Guid/Fdt.h>
+#include <Guid/FileInfo.h>
+
+#include <libfdt.h>
+
+#define FDT_DEFAULT_FILENAME  L"hi6220-hikey.dtb"
+
+#define IS_DEVICE_PATH_NODE(node,type,subtype) (((node)->Type == (type)) && ((node)->SubType == (subtype)))
+
+// Hardware Vendor Device Path node for the HiKey block device. We use the HiKey block device if the user
+// has not specified another filesystem location into the UEFI Variable 'Fdt'.
+STATIC CONST struct {
+  VENDOR_DEVICE_PATH MmcGuid;
+  EFI_DEVICE_PATH    End;
+} mHiKeyBlockDevicePath = {
+  {
+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
+    { 0xB549F005, 0x4BD4, 0x4020, { 0xA0, 0xCB, 0x06, 0xF4, 0x2B, 0xDA, 0x68, 0xC3 } }
+  },
+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }
+};
+
+STATIC EFI_DEVICE_PATH* mFdtFileSystemDevicePath = NULL;
+STATIC CHAR16* mFdtFileName = NULL;
+
+STATIC BOOLEAN mFdtTableInstalled = FALSE;
+
+/**
+  See definition EFI_DRIVER_BINDING_PROTOCOL.Supported()
+**/
+EFI_STATUS
+EFIAPI
+HiKeyFdtSupported (
+  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+  IN        EFI_HANDLE                   ControllerHandle,
+  IN        EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath OPTIONAL
+  )
+{
+  EFI_STATUS                Status;
+  EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+  //
+  // Check if the Handle support the Simple File System Protocol
+  //
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiSimpleFileSystemProtocolGuid,
+                  NULL,
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Check if a DevicePath is attached to the handle
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  (VOID **)&DevicePath,
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Check if the Device Path is the one from the block device
+  if (CompareMem (mFdtFileSystemDevicePath, DevicePath, GetDevicePathSize (mFdtFileSystemDevicePath)) != 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, gImageHandle, ControllerHandle);
+  return Status;
+}
+
+/**
+  This function is used to print messages back to the user.
+
+  We use the Serial terminal for these messages as the gST->ConOut might not be initialized at this stage.
+
+  @param Message    Message to display to the user
+**/
+STATIC
+VOID
+PrintMessage (
+  IN CHAR8* Message,
+  ...
+  )
+{
+  UINTN   CharCount;
+  CHAR8   Buffer[100];
+  VA_LIST Marker;
+
+  VA_START (Marker, Message);
+  CharCount = AsciiVSPrint (Buffer, sizeof (Buffer), Message, Marker);
+  VA_END (Marker);
+
+  SerialPortWrite ((UINT8*)Buffer, CharCount);
+}
+
+/**
+  See definition EFI_DRIVER_BINDING_PROTOCOL.Start ()
+**/
+EFI_STATUS
+EFIAPI
+HiKeyFdtStart (
+  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+  IN        EFI_HANDLE                   ControllerHandle,
+  IN        EFI_DEVICE_PATH_PROTOCOL    *DevicePath OPTIONAL
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs;
+  EFI_FILE_PROTOCOL               *Fs;
+  EFI_FILE_PROTOCOL               *File;
+  UINTN                            Size;
+  EFI_PHYSICAL_ADDRESS             FdtBlob;
+  EFI_FILE_INFO                   *FileInfo;
+
+  if (mFdtTableInstalled) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  Status = gBS->OpenProtocol (
+                  ControllerHandle,
+                  &gEfiSimpleFileSystemProtocolGuid,
+                  (VOID**)&SimpleFs,
+                  gImageHandle,
+                  ControllerHandle,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Try to Open the volume and get root directory
+  Status = SimpleFs->OpenVolume (SimpleFs, &Fs);
+  if (EFI_ERROR (Status)) {
+    PrintMessage ("Warning: Fail to open file system that should contain FDT file.\n");
+    goto CLOSE_PROTOCOL;
+  }
+
+  File = NULL;
+  Status = Fs->Open (Fs, &File, mFdtFileName, EFI_FILE_MODE_READ, 0);
+  if (EFI_ERROR (Status)) {
+    PrintMessage ("Warning: Fail to load FDT file '%s'.\n", mFdtFileName);
+    goto CLOSE_PROTOCOL;
+  }
+
+  Size = 0;
+  File->GetInfo (File, &gEfiFileInfoGuid, &Size, NULL);
+  FileInfo = AllocatePool (Size);
+  Status = File->GetInfo (File, &gEfiFileInfoGuid, &Size, FileInfo);
+  if (EFI_ERROR (Status)) {
+    goto CLOSE_FILE;
+  }
+
+  // Get the file size
+  Size = FileInfo->FileSize;
+  FreePool (FileInfo);
+
+  // The FDT blob is attached to the Configuration Table. It is better to load it as Runtime Service Data
+  // to prevent the kernel to overwrite its data
+  Status = gBS->AllocatePages (AllocateAnyPages, EfiRuntimeServicesData, EFI_SIZE_TO_PAGES (Size), &FdtBlob);
+  if (!EFI_ERROR (Status)) {
+    Status = File->Read (File, &Size, (VOID*)(UINTN)(FdtBlob));
+    if (EFI_ERROR (Status)) {
+      gBS->FreePages (FdtBlob, EFI_SIZE_TO_PAGES (Size));
+    } else {
+      // Check the FDT header is valid. We only make this check in DEBUG mode in case the FDT header change on
+      // production device and this ASSERT() becomes not valid.
+      ASSERT (fdt_check_header ((VOID*)(UINTN)(FdtBlob)) == 0);
+
+      // Ensure the Size of the Device Tree is smaller than the size of the read file
+      ASSERT ((UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlob) <= Size);
+
+      // Install the FDT into the Configuration Table
+      Status = gBS->InstallConfigurationTable (&gFdtTableGuid, (VOID*)(UINTN)(FdtBlob));
+      if (!EFI_ERROR (Status)) {
+        mFdtTableInstalled = TRUE;
+      }
+    }
+  }
+
+CLOSE_FILE:
+  File->Close (File);
+
+CLOSE_PROTOCOL:
+  // We do not need the FileSystem protocol
+  gBS->CloseProtocol (
+         ControllerHandle,
+         &gEfiSimpleFileSystemProtocolGuid,
+         gImageHandle,
+         ControllerHandle);
+
+  return Status;
+}
+
+/**
+  See definition EFI_DRIVER_BINDING_PROTOCOL.Stop()
+**/
+EFI_STATUS
+EFIAPI
+HiKeyFdtStop (
+  IN        EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+  IN        EFI_HANDLE                   ControllerHandle,
+  IN        UINTN                        NumberOfChildren,
+  IN        EFI_HANDLE                  *ChildHandleBuffer OPTIONAL
+  )
+{
+  UINTN      Index;
+  VOID*      FdtBlob;
+  UINTN      FdtSize;
+
+  // Look for FDT Table
+  for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+    // Check for correct GUID type
+    if (CompareGuid (&gFdtTableGuid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+      FdtBlob = gST->ConfigurationTable[Index].VendorTable;
+      FdtSize = (UINTN)fdt_totalsize (FdtBlob);
+
+      // Uninstall the FDT Configuration Table
+      gBS->InstallConfigurationTable (&gFdtTableGuid, NULL);
+
+      // Free the memory
+      gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)FdtBlob, EFI_SIZE_TO_PAGES (FdtSize));
+
+      return EFI_SUCCESS;
+    }
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+//
+// Driver Binding Protocol for HiKey FDT support
+//
+EFI_DRIVER_BINDING_PROTOCOL mHiKeyFdtBinding = {
+  HiKeyFdtSupported,
+  HiKeyFdtStart,
+  HiKeyFdtStop,
+  0xa,
+  NULL,
+  NULL
+};
+
+/**
+  Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+
+  This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.
+
+  @param  Event        Event whose notification function is being invoked.
+  @param  Context      Pointer to the notification function's context.
+
+**/
+STATIC
+VOID
+EFIAPI
+LoadFdtOnEvent (
+  EFI_EVENT                               Event,
+  VOID                                    *Context
+  )
+{
+  EFI_DEVICE_PATH *DevicePathNode;
+  EFI_HANDLE       Handle;
+  EFI_STATUS       Status;
+  UINTN            VariableSize;
+  CHAR16*          FdtDevicePathStr;
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;
+  EFI_EVENT        ArmPlatformUpdateFdtEvent;
+
+  //
+  // Read the 'FDT' UEFI Variable to know where we should we read the blob from.
+  // The 'Fdt' variable contains either the full device path or only the filename of the FDT.
+  // If 'Fdt' only contains the filename then we assume its location is on the NOR Flash.
+  //
+  VariableSize     = 0;
+  Status = gRT->GetVariable (L"Fdt", &gArmGlobalVariableGuid, NULL, &VariableSize, mFdtFileSystemDevicePath);
+  if (Status == EFI_BUFFER_TOO_SMALL) {
+    // Get the environment variable value
+    mFdtFileSystemDevicePath = AllocatePool (VariableSize);
+    if (mFdtFileSystemDevicePath != NULL) {
+      Status = gRT->GetVariable (L"Fdt", &gArmGlobalVariableGuid, NULL, &VariableSize, mFdtFileSystemDevicePath);
+      if (EFI_ERROR (Status)) {
+        FreePool (mFdtFileSystemDevicePath);
+        ASSERT_EFI_ERROR (Status);
+        return;
+      }
+    } else {
+      ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+      return;
+    }
+  } else if (Status == EFI_NOT_FOUND) {
+    // If the 'Fdt' variable does not exist then we get the FDT location from the PCD
+    FdtDevicePathStr = (CHAR16*)PcdGetPtr (PcdFdtDevicePath);
+
+    Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return;
+    }
+
+    // Conversion of the Device Path string into EFI Device Path
+    mFdtFileSystemDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (FdtDevicePathStr);
+  }
+
+  if (mFdtFileSystemDevicePath != NULL) {
+    // Look for the FDT filename that should be contained into the FilePath device path node
+    DevicePathNode = mFdtFileSystemDevicePath;
+    while (!IsDevicePathEnd (DevicePathNode)) {
+      if (IS_DEVICE_PATH_NODE (DevicePathNode, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP)) {
+        // Extract the name from the File Path Node. The name of the Filename is the size of the
+        // device path node minus the size of the device path node header.
+        mFdtFileName = AllocateCopyPool (
+            DevicePathNodeLength (DevicePathNode) - sizeof(EFI_DEVICE_PATH_PROTOCOL),
+            ((FILEPATH_DEVICE_PATH*)DevicePathNode)->PathName);
+        if (mFdtFileName == NULL) {
+          ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+          return;
+        }
+
+        // We remove the FilePath device path node from the FileSystem Device Path
+        // because it will never match a device path installed by the FileSystem driver
+        SetDevicePathEndNode (DevicePathNode);
+        break;
+      }
+      DevicePathNode = NextDevicePathNode (DevicePathNode);
+    }
+
+    // The UEFI Variable might just contain the FDT filename. In this case we assume the FileSystem is
+    // the block device based one (ie: Fat).
+    // If it was only containing the FilePath device node then the previous condition should have
+    // replaced it by the End Device Path Node.
+    if (IsDevicePathEndType (mFdtFileSystemDevicePath)) {
+      mFdtFileSystemDevicePath = (EFI_DEVICE_PATH*)&mHiKeyBlockDevicePath;
+    }
+  } else {
+    // Fallback on the eMMC filesystem
+    mFdtFileSystemDevicePath = (EFI_DEVICE_PATH*)&mHiKeyBlockDevicePath;
+  }
+
+  // If the FDT FileName has been provided during the FileSystem identification
+  if (mFdtFileName == NULL) {
+    mFdtFileName = AllocateCopyPool (StrSize (FDT_DEFAULT_FILENAME), FDT_DEFAULT_FILENAME);
+    if (mFdtFileName == NULL) {
+      ASSERT_EFI_ERROR (Status);
+      return;
+    }
+  }
+
+  // Context is not NULL when this function is called for a gEfiEndOfDxeEventGroupGuid event
+  if (Context) {
+    // Install the Binding protocol to verify when the FileSystem that contains the FDT has been installed
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &gImageHandle,
+                    &gEfiDriverBindingProtocolGuid, &mHiKeyFdtBinding,
+                    NULL
+                    );
+    if (EFI_ERROR (Status)) {
+      ASSERT_EFI_ERROR (Status);
+      return;
+    }
+
+    // Register the event triggered when the 'Fdt' variable is updated.
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    LoadFdtOnEvent,
+                    NULL,
+                    &gArmPlatformUpdateFdtEventGuid,
+                    &ArmPlatformUpdateFdtEvent
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  //
+  // Force to connect the FileSystem that contains the FDT
+  //
+  BdsConnectDevicePath (mFdtFileSystemDevicePath, &Handle, NULL);
+}
+
+STATIC CONST BOOLEAN mIsEndOfDxeEvent = TRUE;
+
+EFI_STATUS
+HiKeyFdtInstall (
+  IN EFI_HANDLE                            ImageHandle
+  )
+{
+  EFI_STATUS Status;
+  EFI_EVENT  EndOfDxeEvent;
+
+  // Register the event handling function to set the End Of DXE flag.
+  // We wait until the end of the DXE phase to load the FDT to make sure
+  // all the required drivers (UEFI Variable, BlockIo) are dispatched
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  LoadFdtOnEvent,
+                  &mIsEndOfDxeEvent,
+                  &gEfiEndOfDxeEventGroupGuid,
+                  &EndOfDxeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/HisiPkg/HiKeyPkg/HiKey.dsc b/HisiPkg/HiKeyPkg/HiKey.dsc
index 06633245e..f5d66dc1f 100644
--- a/HisiPkg/HiKeyPkg/HiKey.dsc
+++ b/HisiPkg/HiKeyPkg/HiKey.dsc
@@ -440,3 +440,9 @@
   #
   MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
   ArmPlatformPkg/Bds/Bds.inf
+
+  #
+  # Hello World efi for Testing
+  #
+  MdeModulePkg/Application/HelloWorld/HelloWorld.inf
+  MdeModulePkg/Application/noboot/noboot.inf
diff --git a/MdeModulePkg/Application/noboot/efi-stub.S b/MdeModulePkg/Application/noboot/efi-stub.S
new file mode 100644
index 000000000..e8f2c8bc4
--- /dev/null
+++ b/MdeModulePkg/Application/noboot/efi-stub.S
@@ -0,0 +1,98 @@
+
+.section .text, "ax"
+
+.align 4
+__flush_dcache_area:
+
+/* Function to flush D-cache in specified range
+ * X0 contain start address
+ * X1 is size of the area */
+
+  mrs x3, ctr_el0
+  ubfm x3, x3, #16, #19
+  mov x2, #4
+  lsl x2, x2, x3
+  add x1, x0, x1
+  sub x3, x2, #1
+  bic x0, x0, x3
+1:dc civac, x0
+  add x0, x0, x2
+  cmp x0, x1
+  b.lo 1b
+  dsb sy
+  ret
+
+/* Good for debugging...
+ * Halt and print 'U' to serial port */
+UHALT:
+  mov   w1, #0x55
+  mov	x0, #0x5000                	// #12288
+  movk	x0, #0xF801, lsl #16
+  str	w1, [x0]
+9:
+  b 9b
+
+.global tail_efi_stub
+.align 4
+tail_efi_stub:
+
+/* We came here in EL2 with:
+ * X20 store the address of entry point to the kernel
+ * X21 size of the kernel image
+ * X22 location of FDT
+ * MMU with identity-mapped and I/D-cache on */
+
+  mov x0, x20
+  mov x1, x21
+  bl __flush_dcache_area
+  ic ialluis
+
+  adr x0, tail_efi_stub
+  adr x1, tail_efi_stub_end
+  sub x1, x1, x0
+  bl __flush_dcache_area
+
+  mrs x0, sctlr_el2
+  bic x0, x0, #1 << 0
+  bic x0, x0, #1 << 2
+  msr sctlr_el2, x0
+  isb
+
+/* Enable us to write to CPUACTLR_EL1
+ * in EL1 unsecured mode */
+
+  mrs x0, ACTLR_EL2
+  orr x0, x0, #1
+  msr ACTLR_EL2, x0
+
+/* Set total outstanding prefetchs
+ * bic x0, x0, #7 << 13 clear the bits
+ * mov x1, #0 << 13 disable the prefetcher 
+ * Valid numbers from 0-8 */
+
+
+/* Set the exection state of the lower exception level
+ * hcr_el2 = #(1 << 31) and spsr_el2 = #0x3c5 for 64-bit
+ * hcr_el2 = 0 and spsr_el2 = #0x1d3 for 32-bit
+ * We almost strat with everything off */
+
+  msr hcr_el2, xzr
+
+  mov x0, #0x0800
+  movk x0, #0x30d0, lsl #16
+  msr sctlr_el1, x0
+
+  mov x0, #0x33ff
+  msr cptr_el2, x0
+  msr hstr_el2, xzr
+
+  msr vttbr_el2, xzr
+
+  mov x0, #0x1d3
+  msr spsr_el2, x0
+  msr elr_el2, x20
+
+  mov x2, x22
+  eret
+
+tail_efi_stub_end:
diff --git a/MdeModulePkg/Application/noboot/noboot.c b/MdeModulePkg/Application/noboot/noboot.c
new file mode 100644
index 000000000..2bcab5199
--- /dev/null
+++ b/MdeModulePkg/Application/noboot/noboot.c
@@ -0,0 +1,140 @@
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+
+#include <Protocol/Bds.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/DevicePathToText.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define  KERNEL_START_ADDRESS   ((UINT8 *)0x1000)
+
+extern EFI_GUID gFdtTableGuid;
+
+EFI_STATUS 
+EFIAPI 
+MemoryMap (
+  IN EFI_SYSTEM_TABLE   *SystemTable,
+  OUT UINTN             *MemMapKey
+  )
+{
+  EFI_STATUS                    status = EFI_SUCCESS;
+  UINTN                         MemMapSize = sizeof(EFI_MEMORY_DESCRIPTOR) * 16;
+  UINTN                         MemMapSizeOut = MemMapSize;
+  UINTN                         MemMapDescriptorSize = 0;
+  UINT32                        MemMapDescriptorVersion = 0;
+  UINT8                        *buffer = NULL;
+
+  do {
+    buffer = AllocatePool (MemMapSize);
+    if ( buffer == NULL ) {
+      break;
+    }
+
+    status = gBS->GetMemoryMap (&MemMapSizeOut, 
+                               (EFI_MEMORY_DESCRIPTOR*)buffer, 
+                               MemMapKey, 
+                               &MemMapDescriptorSize, 
+                               &MemMapDescriptorVersion);
+
+    if (EFI_ERROR (status)) {
+      FreePool (buffer);
+      MemMapSize += sizeof (EFI_MEMORY_DESCRIPTOR) * 16;
+    }
+  } while (EFI_ERROR (status));
+
+  return status;
+}
+
+VOID *
+EFIAPI
+FindFdtBlob (
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  UINTN Index;
+  VOID *FdtBlob;
+
+  for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
+    if (CompareGuid (&gFdtTableGuid, &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
+      FdtBlob = SystemTable->ConfigurationTable[Index].VendorTable;
+      return FdtBlob;
+    }
+  }
+  return NULL;
+}
+
+/**
+  The user Entry Point for Application. The user code starts with this function
+  as the real entry point for the application.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  
+  @param[in] SystemTable    A pointer to the EFI System Table.
+  
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  VOID                               *Kernel;
+  UINTN                               KernelSize;
+  VOID                               *FdtBlob;
+  EFI_STATUS                          Status;
+  EFI_LOADED_IMAGE_PROTOCOL          *LoadedImage;
+  UINTN                               Index;
+  UINTN                               MemMapKey;
+  
+  Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  
+  Kernel = LoadedImage->LoadOptions;
+  KernelSize = LoadedImage->LoadOptionsSize;
+  Print (L"NOBOOT.efi moving kernel 0x%lx (0x%lx) to 0x%lx\n", Kernel, KernelSize, (UINTN)KERNEL_START_ADDRESS);
+
+  for (Index = 0; Index < KernelSize; Index++) {
+    *(KERNEL_START_ADDRESS + Index) = *(((UINT8 *)Kernel) + Index);
+  }
+  
+  Status = MemoryMap(SystemTable, &MemMapKey);
+  if (EFI_ERROR (Status)) {
+    Print (L"NOBOOT.efi unable to get MemMapKey!\n");
+    return Status;
+  }
+
+  Status = gBS->ExitBootServices (ImageHandle, MemMapKey);
+  if (EFI_ERROR (Status)) {
+    Print (L"NOBOOT.efi unable to get exit bootservices!\n");
+    return Status;
+  }
+
+  FdtBlob = FindFdtBlob(SystemTable);
+  if (FdtBlob == NULL) {
+    Print (L"NOBOOT.efi failed to find FDT\n");
+  }
+
+  asm volatile (
+    "mov x20, %0\n\t"
+    "mov x21, %1\n\t"
+    "mov x22, %2\n\t"
+    "bl tail_efi_stub" 
+    : 
+    : "r" (KERNEL_START_ADDRESS), "r" (KernelSize), "r" (FdtBlob)
+    : "x20" , "x21" , "x22"
+    );
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Application/noboot/noboot.inf b/MdeModulePkg/Application/noboot/noboot.inf
new file mode 100644
index 000000000..189e3bffb
--- /dev/null
+++ b/MdeModulePkg/Application/noboot/noboot.inf
@@ -0,0 +1,48 @@
+## @file
+#  Sample UEFI Application Reference EDKII Module.
+#
+#  This is a sample shell application that will print "UEFI Hello World!" to the
+#  UEFI Console based on PCD setting.
+#
+#  It demos how to use EDKII PCD mechanism to make code more flexible.
+#
+#  Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = noboot
+  FILE_GUID                      = 6987936E-ED34-44db-AE97-1FA5E4ED2116
+  MODULE_TYPE                    = UEFI_APPLICATION
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = UefiMain
+  VALID_ARCHITECTURES            = AARCH64
+
+
+[Sources]
+  noboot.c
+  efi-stub.S
+  
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  UefiApplicationEntryPoint
+  UefiLib
+
+[Guids]
+  gFdtTableGuid
+
+[Protocols] 
+  gEfiSimpleFileSystemProtocolGuid
+  gEfiLoadedImageProtocolGuid
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 4328eba8f..40ed04656 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -282,6 +282,8 @@
   ## Include/Protocol/VarErrorFlag.h
   gEdkiiVarErrorFlagGuid               = { 0x4b37fe8, 0xf6ae, 0x480b, { 0xbd, 0xd5, 0x37, 0xd9, 0x8c, 0x5e, 0x89, 0xaa } }
 
+  gFdtTableGuid                        = { 0xb1b621d5, 0xf19c, 0x41a5, { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } }
+
 [Ppis]
   ## Include/Ppi/AtaController.h
   gPeiAtaControllerPpiGuid       = { 0xa45e60d1, 0xc719, 0x44aa, { 0xb0, 0x7a, 0xaa, 0x77, 0x7f, 0x85, 0x90, 0x6d }}
