Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Compute a CRC32 of an ELF image and insert it into the
###############################################################################
# Date: 2019-06-06
# Author: Alexander Hogen
# code.ahogen@outlook.com
# https://github.com/ahogen
#
# !! NOTE: This is currently just a scratchpad for my work. THIS IS NOT DONE YET!
#
# The NXP LPC(546xx) microcontroller's bootloader supports verifying the
# image by checking a CRC32 value before starting to execute it. This
# script for GNU Debugger (GDB) reads a compiled ELF, computes a CRC32
# value, inserts the value into the boot block structure, and saves the
# modified ELF file for you. This was designed to be used as a part of the
# build process (e.g. in a Makefile).
#
# Refer to NXP document UM10912 rev 2.2 section 3.3.2.7 "Image qualification"
#
# SPDX-License-Identifier: MIT
# MIT License
#
# Copyright (c) 2019 Alexander Hogen
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
###############################################################################
################################################################################
# SETUP
################################################################################
set pagination off
set height 0
set width 0
show version
################################################################################
# CONSTANTS & GLOBALS
################################################################################
set var $BB_PTR = *((uint32_t *)0x00000028)
set var $CRC_LEN = *((uint32_t *)$BB_PTR + 3)
set var $CRC_ADDR = ((uint32_t *)$BB_PTR + 4)
set var $CRC_VAL = *($CRC_ADDR)
set var {uint32_t}$CRC_ADDR = 0x00000000
set var $CRC_ACTUAL = 0xa064d17e
################################################################################
# COMMAND DEFINITIONS
################################################################################
# A port of "crc32b" algorithm from Hacker's Delight to GDB syntax.
# https://www.hackersdelight.org/hdcodetxt/crc.c.txt
define crc32
set var $addr = (uint8_t *)$arg0
set var $num_words = $arg1
set var $crc = 0xFFFFFFFF
# OPTIONAL: Override seed value with third argument
if ($argc == 3)
set var $crc = $arg3
end
set var $i = 0
while ($i < $num_words)
set var $byte = $addr[$i]
set var $crc = $crc ^ $byte
set var $j = 0
while ($j < 8)
set var $mask = -($crc & 1)
set var $crc = ($crc >> 1) ^ (0xEDB88320 & $mask)
set var $j = $j + 1
end
set var $i = $i + 1
end
set var $crc = ~$crc
set var $retval = $crc
end
################################################################################
# MAIN SCRIPT
################################################################################
printf "CRC32 length: %d\n", $CRC_LEN
printf "CRC32 value address: 0x%x\n", $CRC_ADDR
printf "CRC32 current value: 0x%x\n", $CRC_VAL
printf "\n-- COMPUTE CRC (1/2)\n"
set var $retval = 0
crc32 0x0 $CRC_LEN
set var $CRC_VAL = $retval
printf "First CRC is == 0x%x (%u)\n", $retval, $retval
if ($CRC_ACTUAL == $CRC_VAL)
printf "OK\n"
else
printf "FAIL\n"
end
#printf "\n-- SKIP CRC WORD IN BOOT BLOCK\n"
#printf "\n-- COMPUTE CRC (2/2)\n"
printf "\n-- INJECT CRC32 INTO BOOT BLOCK\n"
show write
set confirm off
set {uint32_t}$CRC_ADDR = $CRC_VAL
#set var $CRC_REG= (volatile uint32_t *)$CRC_ADDR
#set var *$CRC_REG = $CRC_VAL
printf "CRC32 value at address 0x%x = 0x%x\n", $CRC_ADDR, *($CRC_ADDR)
if (*($CRC_ADDR) != $CRC_VAL)
printf "[ERROR]: Failed to write new CRC value to binary\n"
quit 2
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment