sdm845: Combine BB with QC-Sec for ROM boot
TEST=build & run Change-Id: I222a56f1c9b74856a1e1ff8132bab5e041672c5d Signed-off-by: T Michael Turney <mturney@codeaurora.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/25207 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
		
				
					committed by
					
						
						Julius Werner
					
				
			
			
				
	
			
			
			
						parent
						
							61309e39b3
						
					
				
				
					commit
					101098c41a
				
			@@ -47,7 +47,7 @@ config SBL_ELF
 | 
				
			|||||||
config SBL_UTIL_PATH
 | 
					config SBL_UTIL_PATH
 | 
				
			||||||
	depends on USE_BLOBS
 | 
						depends on USE_BLOBS
 | 
				
			||||||
	string "Path for utils to combine SBL_ELF and bootblock"
 | 
						string "Path for utils to combine SBL_ELF and bootblock"
 | 
				
			||||||
	default "util/ipqheader"
 | 
						default "util/qualcomm"
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Path for utils to combine SBL_ELF and bootblock
 | 
						  Path for utils to combine SBL_ELF and bootblock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <types.h>
 | 
					#include <types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* QCA firmware blob header gleaned from util/ipqheader/ipqheader.py */
 | 
					/* QCA firmware blob header gleaned from util/qualcomm/ipqheader.py */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mbn_header {
 | 
					struct mbn_header {
 | 
				
			||||||
	u32	mbn_type;
 | 
						u32	mbn_type;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,14 +62,14 @@ ifeq ($(CONFIG_USE_BLOBS),y)
 | 
				
			|||||||
# Add MBN header to allow SBL3 to start coreboot bootblock
 | 
					# Add MBN header to allow SBL3 to start coreboot bootblock
 | 
				
			||||||
$(objcbfs)/bootblock.mbn: $(objcbfs)/bootblock.raw.bin
 | 
					$(objcbfs)/bootblock.mbn: $(objcbfs)/bootblock.raw.bin
 | 
				
			||||||
	@printf "    ADD MBN    $(subst $(obj)/,,$(@))\n"
 | 
						@printf "    ADD MBN    $(subst $(obj)/,,$(@))\n"
 | 
				
			||||||
	./util/ipqheader/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp
 | 
						./util/qualcomm/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp
 | 
				
			||||||
	@mv $@.tmp $@
 | 
						@mv $@.tmp $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Create a complete bootblock which will start up the system
 | 
					# Create a complete bootblock which will start up the system
 | 
				
			||||||
$(objcbfs)/bootblock.bin: $(call strip_quotes,$(CONFIG_SBL_BLOB)) \
 | 
					$(objcbfs)/bootblock.bin: $(call strip_quotes,$(CONFIG_SBL_BLOB)) \
 | 
				
			||||||
			   $(objcbfs)/bootblock.mbn
 | 
								   $(objcbfs)/bootblock.mbn
 | 
				
			||||||
	@printf "    MBNCAT     $(subst $(obj)/,,$(@))\n"
 | 
						@printf "    MBNCAT     $(subst $(obj)/,,$(@))\n"
 | 
				
			||||||
	@util/ipqheader/mbncat.py -o $@.tmp $^
 | 
						@util/qualcomm/mbncat.py -o $@.tmp $^
 | 
				
			||||||
	@mv $@.tmp $@
 | 
						@mv $@.tmp $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <types.h>
 | 
					#include <types.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Qualcomm firmware blob header gleaned from util/ipqheader/ipqheader.py */
 | 
					/* Qualcomm firmware blob header gleaned from util/qualcomm/ipqheader.py */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mbn_header {
 | 
					struct mbn_header {
 | 
				
			||||||
	u32	mbn_type;
 | 
						u32	mbn_type;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
# GENERAL DESCRIPTION
 | 
					# GENERAL DESCRIPTION
 | 
				
			||||||
#   Concatentates XBL segments into one ELF image
 | 
					#   Concatentates XBL segments into one ELF image
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Copyright (c) 2016, The Linux Foundation. All rights reserved.
 | 
					# Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Redistribution and use in source and binary forms, with or without
 | 
					# Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
# modification, are permitted provided that the following conditions are
 | 
					# modification, are permitted provided that the following conditions are
 | 
				
			||||||
@@ -44,6 +44,7 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# when       who       what, where, why
 | 
					# when       who       what, where, why
 | 
				
			||||||
# --------   ---       ------------------------------------------------------
 | 
					# --------   ---       ------------------------------------------------------
 | 
				
			||||||
 | 
					# 03/26/18   tv        Added -e to enable extended MBNV5 support
 | 
				
			||||||
# 09/04/15   et        Added -x and -d to embed xbl_sec ELF
 | 
					# 09/04/15   et        Added -x and -d to embed xbl_sec ELF
 | 
				
			||||||
# 02/11/15   ck        Fixed missing elf type check in ZI OOB feature
 | 
					# 02/11/15   ck        Fixed missing elf type check in ZI OOB feature
 | 
				
			||||||
# 11/04/14   ck        Updated calls to mbn_tools functions
 | 
					# 11/04/14   ck        Updated calls to mbn_tools functions
 | 
				
			||||||
@@ -205,6 +206,11 @@ def main():
 | 
				
			|||||||
  else:
 | 
					  else:
 | 
				
			||||||
    zi_oob_enabled = True
 | 
					    zi_oob_enabled = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if options.elf_inp_xbl_sec:
 | 
				
			||||||
 | 
					    is_ext_mbn_v5 = True
 | 
				
			||||||
 | 
					  else:
 | 
				
			||||||
 | 
					    is_ext_mbn_v5 = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mbn_type = 'elf'
 | 
					  mbn_type = 'elf'
 | 
				
			||||||
  header_format = 'reg'
 | 
					  header_format = 'reg'
 | 
				
			||||||
@@ -237,7 +243,8 @@ def main():
 | 
				
			|||||||
	     is_elf2_64_bit,
 | 
						     is_elf2_64_bit,
 | 
				
			||||||
       is_elf_xbl_sec_64_bit,
 | 
					       is_elf_xbl_sec_64_bit,
 | 
				
			||||||
	     is_out_elf_64_bit,
 | 
						     is_out_elf_64_bit,
 | 
				
			||||||
	     zi_oob_enabled)
 | 
						     zi_oob_enabled,
 | 
				
			||||||
 | 
						     is_ext_mbn_v5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # Hash the image if user did not explicitly say not to
 | 
					  # Hash the image if user did not explicitly say not to
 | 
				
			||||||
@@ -262,6 +269,7 @@ def main():
 | 
				
			|||||||
				target_hash,
 | 
									target_hash,
 | 
				
			||||||
				target_hash_hd,
 | 
									target_hash_hd,
 | 
				
			||||||
                         	image_header_secflag,
 | 
					                         	image_header_secflag,
 | 
				
			||||||
 | 
									is_ext_mbn_v5,
 | 
				
			||||||
				elf_file_name = source_elf)
 | 
									elf_file_name = source_elf)
 | 
				
			||||||
    if rv:
 | 
					    if rv:
 | 
				
			||||||
       raise RuntimeError, "Failed to create image header for hash segment"
 | 
					       raise RuntimeError, "Failed to create image header for hash segment"
 | 
				
			||||||
@@ -296,7 +304,8 @@ def merge_elfs(env,
 | 
				
			|||||||
               is_elf2_64_bit,
 | 
					               is_elf2_64_bit,
 | 
				
			||||||
               is_elf_xbl_sec_64_bit,
 | 
					               is_elf_xbl_sec_64_bit,
 | 
				
			||||||
	             is_out_elf_64_bit,
 | 
						             is_out_elf_64_bit,
 | 
				
			||||||
	             zi_oob_enabled):
 | 
						             zi_oob_enabled,
 | 
				
			||||||
 | 
						             is_ext_mbn_v5):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  [elf_header1, phdr_table1] = \
 | 
					  [elf_header1, phdr_table1] = \
 | 
				
			||||||
    mbn_tools.preprocess_elf_file(elf_in_file_name1)
 | 
					    mbn_tools.preprocess_elf_file(elf_in_file_name1)
 | 
				
			||||||
@@ -654,7 +663,12 @@ def merge_elfs(env,
 | 
				
			|||||||
      new_phdr.p_paddr  = phys_virt_addr
 | 
					      new_phdr.p_paddr  = phys_virt_addr
 | 
				
			||||||
      new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec)
 | 
					      new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec)
 | 
				
			||||||
      new_phdr.p_memsz  = new_phdr.p_filesz
 | 
					      new_phdr.p_memsz  = new_phdr.p_filesz
 | 
				
			||||||
      new_phdr.p_flags  = 0x5
 | 
					      if is_ext_mbn_v5 == True:
 | 
				
			||||||
 | 
						new_phdr.p_flags  = (0x5 |
 | 
				
			||||||
 | 
						  (mbn_tools.MI_PBT_XBL_SEC_SEGMENT <<
 | 
				
			||||||
 | 
						   mbn_tools.MI_PBT_FLAG_SEGMENT_TYPE_SHIFT));
 | 
				
			||||||
 | 
					      else:
 | 
				
			||||||
 | 
						new_phdr.p_flags  = 0x5
 | 
				
			||||||
      new_phdr.p_align  = 0x1000
 | 
					      new_phdr.p_align  = 0x1000
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
      # Converting from 64 to 32 elf requires data size validation
 | 
					      # Converting from 64 to 32 elf requires data size validation
 | 
				
			||||||
@@ -663,18 +677,23 @@ def merge_elfs(env,
 | 
				
			|||||||
      new_phdr = mbn_tools.Elf32_Phdr('\0' * ELF32_PHDR_SIZE)
 | 
					      new_phdr = mbn_tools.Elf32_Phdr('\0' * ELF32_PHDR_SIZE)
 | 
				
			||||||
      new_phdr.p_type   = 0x1 #
 | 
					      new_phdr.p_type   = 0x1 #
 | 
				
			||||||
      new_phdr.p_offset = segment_offset
 | 
					      new_phdr.p_offset = segment_offset
 | 
				
			||||||
      new_phdr.p_flags  = 0x5
 | 
					      if is_ext_mbn_v5 == True:
 | 
				
			||||||
 | 
						new_phdr.p_flags  = (0x5 |
 | 
				
			||||||
 | 
						  (mbn_tools.MI_PBT_XBL_SEC_SEGMENT <<
 | 
				
			||||||
 | 
						   mbn_tools.MI_PBT_FLAG_SEGMENT_TYPE_SHIFT));
 | 
				
			||||||
 | 
					      else:
 | 
				
			||||||
 | 
						new_phdr.p_flags  = 0x5
 | 
				
			||||||
      new_phdr.p_align  = 0x1000
 | 
					      new_phdr.p_align  = 0x1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if phys_virt_addr > 0xFFFFFFFF:
 | 
					      if phys_virt_addr > 0xFFFFFFFF:
 | 
				
			||||||
        if zi_oob_enabled == False or curr_phdr.p_filesz != 0:
 | 
					        if zi_oob_enabled == False or curr_phdr.p_filesz != 0:
 | 
				
			||||||
          print "ERROR: File xbl_sec VAddr or PAddr is too large for conversion."
 | 
					          print "ERROR: File xbl_sec VAddr or PAddr is too big for conversion."
 | 
				
			||||||
          exit()
 | 
					          exit()
 | 
				
			||||||
      new_phdr.p_vaddr  = phys_virt_addr
 | 
					      new_phdr.p_vaddr  = phys_virt_addr
 | 
				
			||||||
      new_phdr.p_paddr  = phys_virt_addr
 | 
					      new_phdr.p_paddr  = phys_virt_addr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if os.path.getsize(elf_in_file_xbl_sec) > 0xFFFFFFFF:
 | 
					      if os.path.getsize(elf_in_file_xbl_sec) > 0xFFFFFFFF:
 | 
				
			||||||
        print "ERROR: File xbl_sec Filesz is too large for conversion."
 | 
					        print "ERROR: File xbl_sec Filesz is too big for conversion."
 | 
				
			||||||
        exit()
 | 
					        exit()
 | 
				
			||||||
      new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec)
 | 
					      new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec)
 | 
				
			||||||
      new_phdr.p_memsz  = new_phdr.p_filesz
 | 
					      new_phdr.p_memsz  = new_phdr.p_filesz
 | 
				
			||||||
@@ -6,7 +6,7 @@
 | 
				
			|||||||
# GENERAL DESCRIPTION
 | 
					# GENERAL DESCRIPTION
 | 
				
			||||||
#    Contains all MBN Utilities for image generation
 | 
					#    Contains all MBN Utilities for image generation
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Copyright (c) 2016, The Linux Foundation. All rights reserved.
 | 
					# Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Redistribution and use in source and binary forms, with or without
 | 
					# Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
# modification, are permitted provided that the following conditions are
 | 
					# modification, are permitted provided that the following conditions are
 | 
				
			||||||
@@ -41,6 +41,7 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# when       who     what, where, why
 | 
					# when       who     what, where, why
 | 
				
			||||||
# --------   ---     ---------------------------------------------------------
 | 
					# --------   ---     ---------------------------------------------------------
 | 
				
			||||||
 | 
					# 03/22/18   thiru   Added support for extended MBNV5.
 | 
				
			||||||
# 06/06/13   yliong  CR 497042: Signed and encrypted image is corrupted. MRC features.
 | 
					# 06/06/13   yliong  CR 497042: Signed and encrypted image is corrupted. MRC features.
 | 
				
			||||||
# 03/18/13   dhaval  Add support for hashing elf segments with SHA256 and
 | 
					# 03/18/13   dhaval  Add support for hashing elf segments with SHA256 and
 | 
				
			||||||
#                    sync up to mpss, adsp mbn-tools
 | 
					#                    sync up to mpss, adsp mbn-tools
 | 
				
			||||||
@@ -166,6 +167,7 @@ MI_PBT_HASH_SEGMENT                   = 0x2
 | 
				
			|||||||
MI_PBT_BOOT_SEGMENT                   = 0x3
 | 
					MI_PBT_BOOT_SEGMENT                   = 0x3
 | 
				
			||||||
MI_PBT_L4BSP_SEGMENT                  = 0x4
 | 
					MI_PBT_L4BSP_SEGMENT                  = 0x4
 | 
				
			||||||
MI_PBT_SWAPPED_SEGMENT                = 0x5
 | 
					MI_PBT_SWAPPED_SEGMENT                = 0x5
 | 
				
			||||||
 | 
					MI_PBT_XBL_SEC_SEGMENT                = 0x5
 | 
				
			||||||
MI_PBT_SWAP_POOL_SEGMENT              = 0x6
 | 
					MI_PBT_SWAP_POOL_SEGMENT              = 0x6
 | 
				
			||||||
MI_PBT_PHDR_SEGMENT                   = 0x7
 | 
					MI_PBT_PHDR_SEGMENT                   = 0x7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -902,6 +904,7 @@ def image_header(env, gen_dict,
 | 
				
			|||||||
                      code_file_name,
 | 
					                      code_file_name,
 | 
				
			||||||
                      output_file_name,
 | 
					                      output_file_name,
 | 
				
			||||||
                      secure_type,
 | 
					                      secure_type,
 | 
				
			||||||
 | 
					                      is_ext_mbn_v5,
 | 
				
			||||||
                      header_format = 'reg',
 | 
					                      header_format = 'reg',
 | 
				
			||||||
                      requires_preamble = False,
 | 
					                      requires_preamble = False,
 | 
				
			||||||
                      preamble_file_name = None,
 | 
					                      preamble_file_name = None,
 | 
				
			||||||
@@ -989,6 +992,12 @@ def image_header(env, gen_dict,
 | 
				
			|||||||
      boot_header.cert_chain_ptr = image_dest + code_size + signature_size
 | 
					      boot_header.cert_chain_ptr = image_dest + code_size + signature_size
 | 
				
			||||||
      boot_header.cert_chain_size = cert_chain_size
 | 
					      boot_header.cert_chain_size = cert_chain_size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if is_ext_mbn_v5 == True:
 | 
				
			||||||
 | 
					      	# If platform image integrity check is enabled
 | 
				
			||||||
 | 
						boot_header.flash_parti_ver = 5   # version
 | 
				
			||||||
 | 
						boot_header.image_src = 0         # sig_size_qc
 | 
				
			||||||
 | 
						boot_header.image_dest_ptr = 0    # cert_chain_size_qc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      # If preamble is required, output the preamble file and update the boot_header
 | 
					      # If preamble is required, output the preamble file and update the boot_header
 | 
				
			||||||
      if requires_preamble is True:
 | 
					      if requires_preamble is True:
 | 
				
			||||||
         boot_header = image_preamble(gen_dict, preamble_file_name, boot_header, num_of_pages)
 | 
					         boot_header = image_preamble(gen_dict, preamble_file_name, boot_header, num_of_pages)
 | 
				
			||||||
@@ -2051,7 +2060,7 @@ def get_hash_address(elf_file_name):
 | 
				
			|||||||
      curr_phdr = phdr_table[i]
 | 
					      curr_phdr = phdr_table[i]
 | 
				
			||||||
      if curr_phdr.p_paddr > last_paddr:
 | 
					      if curr_phdr.p_paddr > last_paddr:
 | 
				
			||||||
         # Skip the demand paging segment as it would be outside the physical RAM location
 | 
					         # Skip the demand paging segment as it would be outside the physical RAM location
 | 
				
			||||||
         if MI_PBT_SEGMENT_TYPE_VALUE(curr_phdr.p_flags) != MI_PBT_SWAPPED_SEGMENT:
 | 
					         if MI_PBT_SEGMENT_TYPE_VALUE(curr_phdr.p_flags) != MI_PBT_XBL_SEC_SEGMENT:
 | 
				
			||||||
            last_paddr = curr_phdr.p_paddr;
 | 
					            last_paddr = curr_phdr.p_paddr;
 | 
				
			||||||
            last_paddr_segment = i;
 | 
					            last_paddr_segment = i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										234
									
								
								util/qualcomm/qgpt.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										234
									
								
								util/qualcomm/qgpt.py
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,234 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/python
 | 
				
			||||||
 | 
					#============================================================================
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#/** @file qgpt.py
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# GENERAL DESCRIPTION
 | 
				
			||||||
 | 
					#   Generates QCom GPT header for wrapping Bootblock
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (c) 2018, The Linux Foundation. All rights reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
 | 
					# modification, are permitted provided that the following conditions are
 | 
				
			||||||
 | 
					# met:
 | 
				
			||||||
 | 
					#     * Redistributions of source code must retain the above copyright
 | 
				
			||||||
 | 
					#       notice, this list of conditions and the following disclaimer.
 | 
				
			||||||
 | 
					#     * Redistributions in binary form must reproduce the above
 | 
				
			||||||
 | 
					#       copyright notice, this list of conditions and the following
 | 
				
			||||||
 | 
					#       disclaimer in the documentation and/or other materials provided
 | 
				
			||||||
 | 
					#       with the distribution.
 | 
				
			||||||
 | 
					#     * Neither the name of The Linux Foundation nor the names of its
 | 
				
			||||||
 | 
					#       contributors may be used to endorse or promote products derived
 | 
				
			||||||
 | 
					#       from this software without specific prior written permission.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 | 
				
			||||||
 | 
					# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 | 
				
			||||||
 | 
					# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 | 
				
			||||||
 | 
					# ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 | 
				
			||||||
 | 
					# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
				
			||||||
 | 
					# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
				
			||||||
 | 
					# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 | 
				
			||||||
 | 
					# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | 
				
			||||||
 | 
					# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 | 
				
			||||||
 | 
					# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 | 
				
			||||||
 | 
					# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#**/
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					import math
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					import struct
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import tempfile
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from binascii import crc32
 | 
				
			||||||
 | 
					from optparse import OptionParser
 | 
				
			||||||
 | 
					from types import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def UpdateMBR(options, GPTBlobBuffer):
 | 
				
			||||||
 | 
					    i = 0x1BE
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 0] = 0x00                  # not bootable
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 1] = 0x00                  # head
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 2] = 0x01                  # sector
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 3] = 0x00                  # cylinder
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 4] = 0xEE                  # type
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 5] = 0xFF                  # head
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 6] = 0xFF                  # sector
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 7] = 0xFF                  # cylinder
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 8:i + 8 + 4] = [0x01, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i + 12:i + 16] = [0x00, 0x0f, 0x00, 0x00]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # magic byte for MBR partitioning - always at this location regardless of
 | 
				
			||||||
 | 
					    # options.sector
 | 
				
			||||||
 | 
					    GPTBlobBuffer[510:512] = [0x55, 0xAA]
 | 
				
			||||||
 | 
					    return i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def UpdatePartitionEntry(options, GPTBlobBuffer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    i = 2 * options.sector_size
 | 
				
			||||||
 | 
					    # GUID of Boot Block
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 16] = [0x2c, 0xba, 0xa0, 0xde, 0xdd, 0xcb, 0x05, 0x48,
 | 
				
			||||||
 | 
					        0xb4, 0xf9, 0xf4, 0x28, 0x25, 0x1c, 0x3e, 0x98]
 | 
				
			||||||
 | 
					    i += 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #This is to set Unique Partition GUID. Below Hex Value is : 00ChezaBootblock00
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 16] = [0x00, 0x43, 0x68, 0x65, 0x7a, 0x61, 0x42, 0x6f,
 | 
				
			||||||
 | 
					        0x6f, 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x00]
 | 
				
			||||||
 | 
					    i += 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # LBA of BootBlock Start Content
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 8] = [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # End LBA of BootBlock Content
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i] = options.end_lba & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+1] = (options.end_lba>>8) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+2] = (options.end_lba>>16) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+3] = (options.end_lba>>24) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+4] = (options.end_lba>>32) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+5] = (options.end_lba>>40) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+6] = (options.end_lba>>48) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+7] = (options.end_lba>>56) & 0xFF
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Attributes
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Label
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 17] = [0x62, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00,
 | 
				
			||||||
 | 
					        0x62, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x6b]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def UpdateGPTHeader(options, GPTBlobBuffer):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    i = options.sector_size
 | 
				
			||||||
 | 
					    # Signature and Revision and HeaderSize i.e. "EFI PART" and 00 00 01 00
 | 
				
			||||||
 | 
					    # and 5C 00 00 00
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 16] = [0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54,
 | 
				
			||||||
 | 
					        0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # CRC is zeroed out till calculated later
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 4] = [0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Reserved, set to 0
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 4] = [0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Current LBA
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 8] = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Backup LBA, No Backup Gpt Used
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # First Usuable LBA (qc_sec + bootblock location)
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 8] = [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Last Usuable LBA (qc_sec + bootblock end location)
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i] = options.end_lba & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+1] = (options.end_lba>>8) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+2] = (options.end_lba>>16) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+3] = (options.end_lba>>24) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+4] = (options.end_lba>>32) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+5] = (options.end_lba>>40) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+6] = (options.end_lba>>48) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+7] = (options.end_lba>>56) & 0xFF
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # GUID
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 16] = [0x32,0x1B,0x10,0x98,0xE2,0xBB,0xF2,0x4B,
 | 
				
			||||||
 | 
					        0xA0,0x6E,0x2B,0xB3,0x3D,0x00,0x0C,0x20]
 | 
				
			||||||
 | 
					    i += 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Partition Table Entry LBA
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 8] = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Number of Partition Entries
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 4] = [0x01, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Size of One Partition Entry
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i:i + 4] = [0x80, 0x00, 0x00, 0x00]
 | 
				
			||||||
 | 
					    i += 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # CRC of Partition Entry
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    PartEntry = GPTBlobBuffer[options.sector_size*2:options.sector_size*2 + 128]
 | 
				
			||||||
 | 
					    CalcEntryCRC = crc32(''.join(struct.pack("B", x) for x in PartEntry))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i] = CalcEntryCRC & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+1] = (CalcEntryCRC>>8) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+2] = (CalcEntryCRC>>16) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+3] = (CalcEntryCRC>>24) & 0xFF
 | 
				
			||||||
 | 
					    i += 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # CRC of Partition Table Header
 | 
				
			||||||
 | 
					    GPTHeader = GPTBlobBuffer[options.sector_size:options.sector_size + 92]
 | 
				
			||||||
 | 
					    CalcEntryCRC = crc32(''.join(struct.pack("B", x) for x in GPTHeader))
 | 
				
			||||||
 | 
					    i = options.sector_size + 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i] = CalcEntryCRC & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+1] = (CalcEntryCRC>>8) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+2] = (CalcEntryCRC>>16) & 0xFF
 | 
				
			||||||
 | 
					    GPTBlobBuffer[i+3] = (CalcEntryCRC>>24) & 0xFF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    usage = 'usage: %prog [OPTIONS] INFILE OUTFILE\n\n' + \
 | 
				
			||||||
 | 
					            'Packages IMAGE in a GPT format.'
 | 
				
			||||||
 | 
					    parser = OptionParser(usage)
 | 
				
			||||||
 | 
					    parser.add_option('-s', type="int", dest='sector_size', default=4096,
 | 
				
			||||||
 | 
					                      help='Sector size in bytes [Default:4096(4KB)]',
 | 
				
			||||||
 | 
					                      metavar='SIZE')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (options, args) = parser.parse_args()
 | 
				
			||||||
 | 
					    if len(args) != 2:
 | 
				
			||||||
 | 
					        print("Invalid arguments! Exiting...\n")
 | 
				
			||||||
 | 
					        parser.print_help()
 | 
				
			||||||
 | 
					        sys.exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if options.sector_size != 4096 and options.sector_size != 512:
 | 
				
			||||||
 | 
					        print("Invalid Sector Size")
 | 
				
			||||||
 | 
					        sys.exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options.inputfile = args[0]
 | 
				
			||||||
 | 
					    options.outputfile = args[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    with open(options.inputfile, 'r+') as fin:
 | 
				
			||||||
 | 
					      bb_buffer = fin.read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Round up to next sector if bootblock size not evenly divisible
 | 
				
			||||||
 | 
					    options.end_lba = ((len(bb_buffer) + options.sector_size - 1) /
 | 
				
			||||||
 | 
					      options.sector_size)
 | 
				
			||||||
 | 
					    # Add 3 sectors for MBR, GPT header and GPT partition entry
 | 
				
			||||||
 | 
					    options.end_lba += 3
 | 
				
			||||||
 | 
					    # Subtract one because this is last usable LBA, not amount of LBAs
 | 
				
			||||||
 | 
					    options.end_lba -= 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPTBlobBuffer = [0] * (options.sector_size*3) #Size of MBR+GPT+PART_ENTRY
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UpdateMBR(options, GPTBlobBuffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UpdatePartitionEntry(options, GPTBlobBuffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    UpdateGPTHeader(options, GPTBlobBuffer)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    with open(options.outputfile, 'wb') as fout:
 | 
				
			||||||
 | 
					      for b in GPTBlobBuffer:
 | 
				
			||||||
 | 
					        fout.write(struct.pack("B", b))
 | 
				
			||||||
 | 
					      fout.write(bb_buffer)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user