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
 | 
			
		||||
	depends on USE_BLOBS
 | 
			
		||||
	string "Path for utils to combine SBL_ELF and bootblock"
 | 
			
		||||
	default "util/ipqheader"
 | 
			
		||||
	default "util/qualcomm"
 | 
			
		||||
	help
 | 
			
		||||
	  Path for utils to combine SBL_ELF and bootblock
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 | 
			
		||||
#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 {
 | 
			
		||||
	u32	mbn_type;
 | 
			
		||||
 
 | 
			
		||||
@@ -62,14 +62,14 @@ ifeq ($(CONFIG_USE_BLOBS),y)
 | 
			
		||||
# Add MBN header to allow SBL3 to start coreboot bootblock
 | 
			
		||||
$(objcbfs)/bootblock.mbn: $(objcbfs)/bootblock.raw.bin
 | 
			
		||||
	@printf "    ADD MBN    $(subst $(obj)/,,$(@))\n"
 | 
			
		||||
	./util/ipqheader/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp
 | 
			
		||||
	./util/qualcomm/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp
 | 
			
		||||
	@mv $@.tmp $@
 | 
			
		||||
 | 
			
		||||
# Create a complete bootblock which will start up the system
 | 
			
		||||
$(objcbfs)/bootblock.bin: $(call strip_quotes,$(CONFIG_SBL_BLOB)) \
 | 
			
		||||
			   $(objcbfs)/bootblock.mbn
 | 
			
		||||
	@printf "    MBNCAT     $(subst $(obj)/,,$(@))\n"
 | 
			
		||||
	@util/ipqheader/mbncat.py -o $@.tmp $^
 | 
			
		||||
	@util/qualcomm/mbncat.py -o $@.tmp $^
 | 
			
		||||
	@mv $@.tmp $@
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 | 
			
		||||
#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 {
 | 
			
		||||
	u32	mbn_type;
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
# GENERAL DESCRIPTION
 | 
			
		||||
#   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
 | 
			
		||||
# modification, are permitted provided that the following conditions are
 | 
			
		||||
@@ -44,6 +44,7 @@
 | 
			
		||||
#
 | 
			
		||||
# 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
 | 
			
		||||
# 02/11/15   ck        Fixed missing elf type check in ZI OOB feature
 | 
			
		||||
# 11/04/14   ck        Updated calls to mbn_tools functions
 | 
			
		||||
@@ -205,6 +206,11 @@ def main():
 | 
			
		||||
  else:
 | 
			
		||||
    zi_oob_enabled = True
 | 
			
		||||
 | 
			
		||||
  if options.elf_inp_xbl_sec:
 | 
			
		||||
    is_ext_mbn_v5 = True
 | 
			
		||||
  else:
 | 
			
		||||
    is_ext_mbn_v5 = False
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  mbn_type = 'elf'
 | 
			
		||||
  header_format = 'reg'
 | 
			
		||||
@@ -237,7 +243,8 @@ def main():
 | 
			
		||||
	     is_elf2_64_bit,
 | 
			
		||||
       is_elf_xbl_sec_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
 | 
			
		||||
@@ -262,6 +269,7 @@ def main():
 | 
			
		||||
				target_hash,
 | 
			
		||||
				target_hash_hd,
 | 
			
		||||
                         	image_header_secflag,
 | 
			
		||||
				is_ext_mbn_v5,
 | 
			
		||||
				elf_file_name = source_elf)
 | 
			
		||||
    if rv:
 | 
			
		||||
       raise RuntimeError, "Failed to create image header for hash segment"
 | 
			
		||||
@@ -296,7 +304,8 @@ def merge_elfs(env,
 | 
			
		||||
               is_elf2_64_bit,
 | 
			
		||||
               is_elf_xbl_sec_64_bit,
 | 
			
		||||
	             is_out_elf_64_bit,
 | 
			
		||||
	             zi_oob_enabled):
 | 
			
		||||
	             zi_oob_enabled,
 | 
			
		||||
	             is_ext_mbn_v5):
 | 
			
		||||
 | 
			
		||||
  [elf_header1, phdr_table1] = \
 | 
			
		||||
    mbn_tools.preprocess_elf_file(elf_in_file_name1)
 | 
			
		||||
@@ -654,6 +663,11 @@ def merge_elfs(env,
 | 
			
		||||
      new_phdr.p_paddr  = phys_virt_addr
 | 
			
		||||
      new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec)
 | 
			
		||||
      new_phdr.p_memsz  = new_phdr.p_filesz
 | 
			
		||||
      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
 | 
			
		||||
    else:
 | 
			
		||||
@@ -663,18 +677,23 @@ def merge_elfs(env,
 | 
			
		||||
      new_phdr = mbn_tools.Elf32_Phdr('\0' * ELF32_PHDR_SIZE)
 | 
			
		||||
      new_phdr.p_type   = 0x1 #
 | 
			
		||||
      new_phdr.p_offset = segment_offset
 | 
			
		||||
      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
 | 
			
		||||
 | 
			
		||||
      if phys_virt_addr > 0xFFFFFFFF:
 | 
			
		||||
        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()
 | 
			
		||||
      new_phdr.p_vaddr  = phys_virt_addr
 | 
			
		||||
      new_phdr.p_paddr  = phys_virt_addr
 | 
			
		||||
 | 
			
		||||
      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()
 | 
			
		||||
      new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec)
 | 
			
		||||
      new_phdr.p_memsz  = new_phdr.p_filesz
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
# GENERAL DESCRIPTION
 | 
			
		||||
#    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
 | 
			
		||||
# modification, are permitted provided that the following conditions are
 | 
			
		||||
@@ -41,6 +41,7 @@
 | 
			
		||||
#
 | 
			
		||||
# 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.
 | 
			
		||||
# 03/18/13   dhaval  Add support for hashing elf segments with SHA256 and
 | 
			
		||||
#                    sync up to mpss, adsp mbn-tools
 | 
			
		||||
@@ -166,6 +167,7 @@ MI_PBT_HASH_SEGMENT                   = 0x2
 | 
			
		||||
MI_PBT_BOOT_SEGMENT                   = 0x3
 | 
			
		||||
MI_PBT_L4BSP_SEGMENT                  = 0x4
 | 
			
		||||
MI_PBT_SWAPPED_SEGMENT                = 0x5
 | 
			
		||||
MI_PBT_XBL_SEC_SEGMENT                = 0x5
 | 
			
		||||
MI_PBT_SWAP_POOL_SEGMENT              = 0x6
 | 
			
		||||
MI_PBT_PHDR_SEGMENT                   = 0x7
 | 
			
		||||
 | 
			
		||||
@@ -902,6 +904,7 @@ def image_header(env, gen_dict,
 | 
			
		||||
                      code_file_name,
 | 
			
		||||
                      output_file_name,
 | 
			
		||||
                      secure_type,
 | 
			
		||||
                      is_ext_mbn_v5,
 | 
			
		||||
                      header_format = 'reg',
 | 
			
		||||
                      requires_preamble = False,
 | 
			
		||||
                      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_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 requires_preamble is True:
 | 
			
		||||
         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]
 | 
			
		||||
      if curr_phdr.p_paddr > last_paddr:
 | 
			
		||||
         # 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_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