mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Warning for shared external code during build (#1881)
This commit is contained in:
parent
6a8650d484
commit
0f6a9277a8
12
firmware/application/external/external.cmake
vendored
12
firmware/application/external/external.cmake
vendored
@ -1,12 +1,12 @@
|
|||||||
set(EXTCPPSRC
|
set(EXTCPPSRC
|
||||||
|
|
||||||
#pacman
|
#pacman
|
||||||
external/pacman/main.cpp
|
# external/pacman/main.cpp
|
||||||
external/pacman/ui_pacman.cpp
|
# external/pacman/ui_pacman.cpp
|
||||||
|
|
||||||
#tetris
|
#tetris
|
||||||
external/tetris/main.cpp
|
# external/tetris/main.cpp
|
||||||
external/tetris/ui_tetris.cpp
|
# external/tetris/ui_tetris.cpp
|
||||||
|
|
||||||
#afsk_rx
|
#afsk_rx
|
||||||
external/afsk_rx/main.cpp
|
external/afsk_rx/main.cpp
|
||||||
@ -65,7 +65,7 @@ set(EXTCPPSRC
|
|||||||
)
|
)
|
||||||
|
|
||||||
set(EXTAPPLIST
|
set(EXTAPPLIST
|
||||||
pacman
|
# pacman
|
||||||
afsk_rx
|
afsk_rx
|
||||||
calculator
|
calculator
|
||||||
font_viewer
|
font_viewer
|
||||||
@ -79,5 +79,5 @@ set(EXTAPPLIST
|
|||||||
gpssim
|
gpssim
|
||||||
spainter
|
spainter
|
||||||
keyfob
|
keyfob
|
||||||
tetris
|
# tetris
|
||||||
)
|
)
|
||||||
|
42
firmware/application/external/external.ld
vendored
42
firmware/application/external/external.ld
vendored
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (C) 2023 Bernd Herzog
|
Copyright (C) 2023 Bernd Herzog
|
||||||
|
Copyright (C) 2024 Mark Thompson
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -16,22 +17,27 @@
|
|||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
/* external apps: regions can't overlap so addresses are corrected after build */
|
/*
|
||||||
ram_external_app_pacman (rwx) : org = 0xEEE90000, len = 32k
|
* External apps: regions can't overlap so addresses are corrected after build.
|
||||||
ram_external_app_afsk_rx (rwx) : org = 0xEEEA0000, len = 32k
|
* Picking uncommon address values for search & replace in binaries (no false positives) - 0xADB00000-0xADEF0000 seems to be good.
|
||||||
ram_external_app_calculator (rwx) : org = 0xEEEB0000, len = 32k
|
* Also need to consider processor memory map - reading 0xADxxxxxx generates a fault which may be better than unexpected behavior.
|
||||||
ram_external_app_font_viewer(rwx) : org = 0xEEEC0000, len = 32k
|
* External app address ranges below must match those in python file "external_app_info.py".
|
||||||
ram_external_app_blespam(rwx) : org = 0xEEED0000, len = 32k
|
*/
|
||||||
ram_external_app_analogtv(rwx) : org = 0xEEEE0000, len = 32k
|
ram_external_app_pacman (rwx) : org = 0xADB00000, len = 32k
|
||||||
ram_external_app_nrf_rx(rwx) : org = 0xEEEF0000, len = 32k
|
ram_external_app_afsk_rx (rwx) : org = 0xADB10000, len = 32k
|
||||||
ram_external_app_coasterp(rwx) : org = 0xEEF00000, len = 32k
|
ram_external_app_calculator (rwx) : org = 0xADB20000, len = 32k
|
||||||
ram_external_app_lge(rwx) : org = 0xEEF10000, len = 32k
|
ram_external_app_font_viewer(rwx) : org = 0xADB30000, len = 32k
|
||||||
ram_external_app_lcr(rwx) : org = 0xEEF20000, len = 32k
|
ram_external_app_blespam(rwx) : org = 0xADB40000, len = 32k
|
||||||
ram_external_app_jammer(rwx) : org = 0xEEF30000, len = 32k
|
ram_external_app_analogtv(rwx) : org = 0xADB50000, len = 32k
|
||||||
ram_external_app_gpssim(rwx) : org = 0xEEF40000, len = 32k
|
ram_external_app_nrf_rx(rwx) : org = 0xADB60000, len = 32k
|
||||||
ram_external_app_spainter(rwx) : org = 0xEEF50000, len = 32k
|
ram_external_app_coasterp(rwx) : org = 0xADB70000, len = 32k
|
||||||
ram_external_app_keyfob(rwx) : org = 0xEEF60000, len = 32k
|
ram_external_app_lge(rwx) : org = 0xADB80000, len = 32k
|
||||||
ram_external_app_tetris(rwx) : org = 0xEEF70000, len = 32k
|
ram_external_app_lcr(rwx) : org = 0xADB90000, len = 32k
|
||||||
|
ram_external_app_jammer(rwx) : org = 0xADBA0000, len = 32k
|
||||||
|
ram_external_app_gpssim(rwx) : org = 0xADBB0000, len = 32k
|
||||||
|
ram_external_app_spainter(rwx) : org = 0xADBC0000, len = 32k
|
||||||
|
ram_external_app_keyfob(rwx) : org = 0xADBD0000, len = 32k
|
||||||
|
ram_external_app_tetris(rwx) : org = 0xADBE0000, len = 32k
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTIONS
|
SECTIONS
|
||||||
@ -60,7 +66,6 @@ SECTIONS
|
|||||||
*(*ui*external_app*font_viewer*);
|
*(*ui*external_app*font_viewer*);
|
||||||
} > ram_external_app_font_viewer
|
} > ram_external_app_font_viewer
|
||||||
|
|
||||||
|
|
||||||
.external_app_blespam : ALIGN(4) SUBALIGN(4)
|
.external_app_blespam : ALIGN(4) SUBALIGN(4)
|
||||||
{
|
{
|
||||||
KEEP(*(.external_app.app_blespam.application_information));
|
KEEP(*(.external_app.app_blespam.application_information));
|
||||||
@ -91,14 +96,12 @@ SECTIONS
|
|||||||
*(*ui*external_app*lge*);
|
*(*ui*external_app*lge*);
|
||||||
} > ram_external_app_lge
|
} > ram_external_app_lge
|
||||||
|
|
||||||
|
|
||||||
.external_app_lcr : ALIGN(4) SUBALIGN(4)
|
.external_app_lcr : ALIGN(4) SUBALIGN(4)
|
||||||
{
|
{
|
||||||
KEEP(*(.external_app.app_lcr.application_information));
|
KEEP(*(.external_app.app_lcr.application_information));
|
||||||
*(*ui*external_app*lcr*);
|
*(*ui*external_app*lcr*);
|
||||||
} > ram_external_app_lcr
|
} > ram_external_app_lcr
|
||||||
|
|
||||||
|
|
||||||
.external_app_jammer : ALIGN(4) SUBALIGN(4)
|
.external_app_jammer : ALIGN(4) SUBALIGN(4)
|
||||||
{
|
{
|
||||||
KEEP(*(.external_app.app_jammer.application_information));
|
KEEP(*(.external_app.app_jammer.application_information));
|
||||||
@ -111,7 +114,6 @@ SECTIONS
|
|||||||
*(*ui*external_app*gpssim*);
|
*(*ui*external_app*gpssim*);
|
||||||
} > ram_external_app_gpssim
|
} > ram_external_app_gpssim
|
||||||
|
|
||||||
|
|
||||||
.external_app_spainter : ALIGN(4) SUBALIGN(4)
|
.external_app_spainter : ALIGN(4) SUBALIGN(4)
|
||||||
{
|
{
|
||||||
KEEP(*(.external_app.app_spainter.application_information));
|
KEEP(*(.external_app.app_spainter.application_information));
|
||||||
|
53
firmware/tools/check_for_shared_external_code.py
Normal file
53
firmware/tools/check_for_shared_external_code.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Mark Thompson
|
||||||
|
#
|
||||||
|
# This file is part of PortaPack.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from external_app_info import maximum_application_size
|
||||||
|
from external_app_info import external_apps_address_start
|
||||||
|
from external_app_info import external_apps_address_end
|
||||||
|
|
||||||
|
usage_message = """
|
||||||
|
PortaPack ROM image checker for possible shared external code addresses
|
||||||
|
|
||||||
|
Usage: <command> <input-file>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def read_image(path):
|
||||||
|
f = open(path, 'rb')
|
||||||
|
data = f.read()
|
||||||
|
f.close()
|
||||||
|
return data
|
||||||
|
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print(usage_message)
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
image = read_image(sys.argv[1])
|
||||||
|
image = bytearray(image)
|
||||||
|
|
||||||
|
for i in range(0, len(image), 4):
|
||||||
|
snippet = image[i:i+4]
|
||||||
|
val = int.from_bytes(snippet, byteorder='little')
|
||||||
|
offset = val & 0xFFFF
|
||||||
|
if (val >= external_apps_address_start) and (val < external_apps_address_end) and ((val & 0xFFFF) < maximum_application_size) and ((val & 0x3)==0):
|
||||||
|
print ("External code address", hex(val),"at offset", hex(i),"in", sys.argv[1])
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (C) 2023 Bernd Herzog
|
# Copyright (C) 2023 Bernd Herzog
|
||||||
|
# Copyright (C) 2024 Mark Thompson
|
||||||
#
|
#
|
||||||
# This file is part of PortaPack.
|
# This file is part of PortaPack.
|
||||||
#
|
#
|
||||||
@ -25,6 +26,9 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import struct
|
import struct
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from external_app_info import maximum_application_size
|
||||||
|
from external_app_info import external_apps_address_start
|
||||||
|
from external_app_info import external_apps_address_end
|
||||||
|
|
||||||
usage_message = """
|
usage_message = """
|
||||||
PortaPack external app image creator
|
PortaPack external app image creator
|
||||||
@ -34,8 +38,6 @@ See firmware/application/CMakeLists.txt > COMMAND ${EXPORT_EXTERNAL_APP_IMAGES}
|
|||||||
Usage: <command> <project source dir> <binary dir> <cmake objcopy path> <list of external image prefixes>
|
Usage: <command> <project source dir> <binary dir> <cmake objcopy path> <list of external image prefixes>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
maximum_application_size = 32*1024
|
|
||||||
|
|
||||||
if len(sys.argv) < 4:
|
if len(sys.argv) < 4:
|
||||||
print(usage_message)
|
print(usage_message)
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
@ -51,7 +53,7 @@ def write_image(data, path):
|
|||||||
f.write(data)
|
f.write(data)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def patch_image(image_data, search_address, replace_address):
|
def patch_image(path, image_data, search_address, replace_address):
|
||||||
if (len(image_data) % 4) != 0:
|
if (len(image_data) % 4) != 0:
|
||||||
print("file size not divideable by 4")
|
print("file size not divideable by 4")
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
@ -62,8 +64,8 @@ def patch_image(image_data, search_address, replace_address):
|
|||||||
snippet = image_data[x*4:4*(x+1)]
|
snippet = image_data[x*4:4*(x+1)]
|
||||||
val = int.from_bytes(snippet, byteorder='little')
|
val = int.from_bytes(snippet, byteorder='little')
|
||||||
|
|
||||||
# in firmware/application/external/external.ld the origin is set to something like search_address=0xEEE90000
|
# in firmware/application/external/external.ld the origin is set to something like search_address=0xADB00000
|
||||||
# if the value is above the search_address and inside a 40kb window (maximum size of an app) we replace it
|
# if the value is above the search_address and inside a 32kb window (maximum size of an app) we replace it
|
||||||
# with replace_address=(0x1008000 + m4 size) where the app will actually be located. The reason we do this instead just
|
# with replace_address=(0x1008000 + m4 size) where the app will actually be located. The reason we do this instead just
|
||||||
# using the right address in external.ld is gcc does not permit to use the same memory range multiple times.
|
# using the right address in external.ld is gcc does not permit to use the same memory range multiple times.
|
||||||
if val > search_address and (val - search_address) < maximum_application_size:
|
if val > search_address and (val - search_address) < maximum_application_size:
|
||||||
@ -74,7 +76,9 @@ def patch_image(image_data, search_address, replace_address):
|
|||||||
external_application_image += new_snippet
|
external_application_image += new_snippet
|
||||||
else:
|
else:
|
||||||
external_application_image += snippet
|
external_application_image += snippet
|
||||||
|
if (val >= external_apps_address_start) and (val < external_apps_address_end) and ((val & 0xFFFF) < maximum_application_size) and ((val & 0x3)==0):
|
||||||
|
print ("WARNING: External code address", hex(val), "at offset", hex(x*4), "in", path)
|
||||||
|
|
||||||
return external_application_image
|
return external_application_image
|
||||||
|
|
||||||
project_source_dir = sys.argv[1] #/portapack-mayhem/firmware/application
|
project_source_dir = sys.argv[1] #/portapack-mayhem/firmware/application
|
||||||
@ -90,7 +94,7 @@ for external_image_prefix in sys.argv[4:]:
|
|||||||
|
|
||||||
# COMMAND ${CMAKE_OBJCOPY} -v -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}_ext_pacman.bin --only-section=.external_app_pacman
|
# COMMAND ${CMAKE_OBJCOPY} -v -O binary ${PROJECT_NAME}.elf ${PROJECT_NAME}_ext_pacman.bin --only-section=.external_app_pacman
|
||||||
himg = "{}/external_app_{}.himg".format(binary_dir, external_image_prefix)
|
himg = "{}/external_app_{}.himg".format(binary_dir, external_image_prefix)
|
||||||
subprocess.run([cmake_objcopy, "-v", "-O", "binary", "{}/application.elf".format(binary_dir), himg, "--only-section=.external_app_{}".format(external_image_prefix)])
|
subprocess.run([cmake_objcopy, "-v", "-O", "binary", "{}/application.elf".format(binary_dir), himg, "--only-section=.external_app_{}".format(external_image_prefix)])
|
||||||
|
|
||||||
external_application_image = read_image(himg)
|
external_application_image = read_image(himg)
|
||||||
|
|
||||||
@ -101,7 +105,7 @@ for external_image_prefix in sys.argv[4:]:
|
|||||||
if (chunk_data[0] == 0 and chunk_data[1] == 0 and chunk_data[2] == 0 and chunk_data[3] == 0):
|
if (chunk_data[0] == 0 and chunk_data[1] == 0 and chunk_data[2] == 0 and chunk_data[3] == 0):
|
||||||
replace_address = 0x10080000
|
replace_address = 0x10080000
|
||||||
search_address = int.from_bytes(external_application_image[externalAppEntry_header_position:externalAppEntry_header_position+4], byteorder='little') & 0xFFFF0000
|
search_address = int.from_bytes(external_application_image[externalAppEntry_header_position:externalAppEntry_header_position+4], byteorder='little') & 0xFFFF0000
|
||||||
external_application_image = patch_image(external_application_image, search_address, replace_address)
|
external_application_image = patch_image(himg, external_application_image, search_address, replace_address)
|
||||||
external_application_image[memory_location_header_position:memory_location_header_position+4] = replace_address.to_bytes(4, byteorder='little')
|
external_application_image[memory_location_header_position:memory_location_header_position+4] = replace_address.to_bytes(4, byteorder='little')
|
||||||
|
|
||||||
checksum = 0
|
checksum = 0
|
||||||
@ -126,7 +130,7 @@ for external_image_prefix in sys.argv[4:]:
|
|||||||
|
|
||||||
replace_address = 0x10080000 + len(m4_image)
|
replace_address = 0x10080000 + len(m4_image)
|
||||||
search_address = int.from_bytes(external_application_image[externalAppEntry_header_position:externalAppEntry_header_position+4], byteorder='little') & 0xFFFF0000
|
search_address = int.from_bytes(external_application_image[externalAppEntry_header_position:externalAppEntry_header_position+4], byteorder='little') & 0xFFFF0000
|
||||||
external_application_image = patch_image(external_application_image, search_address, replace_address)
|
external_application_image = patch_image(himg, external_application_image, search_address, replace_address)
|
||||||
|
|
||||||
external_application_image[memory_location_header_position:memory_location_header_position+4] = replace_address.to_bytes(4, byteorder='little')
|
external_application_image[memory_location_header_position:memory_location_header_position+4] = replace_address.to_bytes(4, byteorder='little')
|
||||||
external_application_image[m4_app_offset_header_position:m4_app_offset_header_position+4] = app_image_len.to_bytes(4, byteorder='little')
|
external_application_image[m4_app_offset_header_position:m4_app_offset_header_position+4] = app_image_len.to_bytes(4, byteorder='little')
|
||||||
|
27
firmware/tools/external_app_info.py
Normal file
27
firmware/tools/external_app_info.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Mark Thompson
|
||||||
|
#
|
||||||
|
# This file is part of PortaPack.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, Inc., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
|
||||||
|
# external app address ranges below must match those in linker file "external.ld"
|
||||||
|
maximum_application_size = 32*1024
|
||||||
|
external_apps_address_start = 0xADB00000
|
||||||
|
external_apps_address_end = 0xADF00000
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
# Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
|
||||||
|
# Copyright (C) 2024 Mark Thompson
|
||||||
#
|
#
|
||||||
# This file is part of PortaPack.
|
# This file is part of PortaPack.
|
||||||
#
|
#
|
||||||
@ -22,6 +23,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from external_app_info import maximum_application_size
|
||||||
|
from external_app_info import external_apps_address_start
|
||||||
|
from external_app_info import external_apps_address_end
|
||||||
|
|
||||||
usage_message = """
|
usage_message = """
|
||||||
PortaPack SPI flash image generator
|
PortaPack SPI flash image generator
|
||||||
@ -81,10 +85,14 @@ pad_size = spi_size - 4 - len(spi_image)
|
|||||||
for i in range(pad_size):
|
for i in range(pad_size):
|
||||||
spi_image += spi_image_default_byte
|
spi_image += spi_image_default_byte
|
||||||
|
|
||||||
# quick "add up the words" checksum:
|
# quick "add up the words" checksum, and check for possible references to code in external apps
|
||||||
checksum = 0
|
checksum = 0
|
||||||
for i in range(0, len(spi_image), 4):
|
for i in range(0, len(spi_image), 4):
|
||||||
checksum += (spi_image[i] + (spi_image[i + 1] << 8) + (spi_image[i + 2] << 16) + (spi_image[i + 3] << 24))
|
snippet = spi_image[i:i+4]
|
||||||
|
val = int.from_bytes(snippet, byteorder='little')
|
||||||
|
checksum += val
|
||||||
|
if (val >= external_apps_address_start) and (val < external_apps_address_end) and ((val & 0xFFFF) < maximum_application_size) and ((val & 0x3)==0):
|
||||||
|
print ("WARNING: External code address", hex(val), "at offset", hex(i), "in", sys.argv[3])
|
||||||
|
|
||||||
final_checksum = 0
|
final_checksum = 0
|
||||||
checksum = (final_checksum - checksum) & 0xFFFFFFFF
|
checksum = (final_checksum - checksum) & 0xFFFFFFFF
|
||||||
|
Loading…
Reference in New Issue
Block a user