Merge pull request #1251 from miek/firmware_info_struct

Add firmware info structure
This commit is contained in:
Michael Ossmann
2023-01-05 15:29:43 -05:00
committed by GitHub
10 changed files with 178 additions and 25 deletions

View File

@ -0,0 +1,52 @@
/*
* Copyright 2022 Great Scott Gadgets <info@greatscottgadgets.com>
*
* This file is part of HackRF.
*
* 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.
*/
#include "firmware_info.h"
#include "platform_detect.h"
#include "gpio_lpc.h"
#include "hackrf_core.h"
#include <libopencm3/lpc43xx/scu.h>
#include <libopencm3/lpc43xx/adc.h>
#ifdef JAWBREAKER
#define SUPPORTED_PLATFORM PLATFORM_JAWBREAKER
#elif HACKRF_ONE
#define SUPPORTED_PLATFORM PLATFORM_HACKRF1_OG
#elif RAD1O
#define SUPPORTED_PLATFORM PLATFORM_RAD1O
#else
#define SUPPORTED_PLATFORM 0
#endif
#ifdef DFU_MODE
#define DFU_MODE_VALUE 1
#else
#define DFU_MODE_VALUE 0
#endif
__attribute__((section(".firmware_info"))) const struct firmware_info_t firmware_info = {
.magic = "HACKRFFW",
.struct_version = 1,
.dfu_mode = DFU_MODE_VALUE,
.supported_platform = SUPPORTED_PLATFORM,
.version_string = VERSION_STRING,
};

View File

@ -0,0 +1,37 @@
/*
* Copyright 2022 Great Scott Gadgets <info@greatscottgadgets.com>
*
* This file is part of HackRF.
*
* 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.
*/
#ifndef FIRMWARE_INFO_H
#define FIRMWARE_INFO_H
#include <stdint.h>
struct firmware_info_t {
char magic[8];
uint16_t struct_version;
uint16_t dfu_mode;
uint32_t supported_platform;
char version_string[32];
} __attribute__((packed, aligned(1)));
extern const struct firmware_info_t firmware_info;
#endif

View File

@ -20,6 +20,7 @@
*/
#include "platform_detect.h"
#include "firmware_info.h"
#include "gpio_lpc.h"
#include "hackrf_core.h"
@ -218,19 +219,5 @@ board_rev_t detected_revision(void)
uint32_t supported_platform(void)
{
uint32_t binary_platform = 0;
#ifdef JAWBREAKER
binary_platform = PLATFORM_JAWBREAKER;
#endif
#ifdef HACKRF_ONE
binary_platform = PLATFORM_HACKRF1_OG;
#endif
#ifdef RAD1O
binary_platform = PLATFORM_RAD1O;
#endif
return binary_platform;
return firmware_info.supported_platform;
}

View File

@ -150,7 +150,7 @@ typedef struct usb_endpoint_t usb_endpoint_t;
struct usb_endpoint_t {
usb_setup_t setup;
uint8_t buffer[8]; // Buffer for use during IN stage.
uint8_t buffer[32]; // Buffer for use during IN stage.
const uint_fast8_t address;
usb_device_t* const device;
usb_endpoint_t* const in;

View File

@ -184,6 +184,7 @@ macro(DeclareTargets)
${PATH_HACKRF_FIRMWARE_COMMON}/gpio_lpc.c
${PATH_HACKRF_FIRMWARE_COMMON}/hackrf_ui.c
${PATH_HACKRF_FIRMWARE_COMMON}/platform_detect.c
${PATH_HACKRF_FIRMWARE_COMMON}/firmware_info.c
)
if(BOARD STREQUAL "RAD1O")

View File

@ -23,6 +23,7 @@
#include "usb_api_board_info.h"
#include "platform_detect.h"
#include "firmware_info.h"
#include <hackrf_core.h>
#include <rom_iap.h>
@ -32,8 +33,6 @@
#include <stddef.h>
#include <string.h>
char version_string[] = VERSION_STRING;
usb_request_status_t usb_vendor_request_read_board_id(
usb_endpoint_t* const endpoint,
const usb_transfer_stage_t stage)
@ -58,10 +57,15 @@ usb_request_status_t usb_vendor_request_read_version_string(
uint8_t length;
if (stage == USB_TRANSFER_STAGE_SETUP) {
length = (uint8_t) strlen(version_string);
length = (uint8_t) strlen(firmware_info.version_string);
// The USB peripheral doesn't seem to be able to read directly from flash,
// so copy the version string into ram first.
memcpy(&endpoint->buffer,
firmware_info.version_string,
sizeof(firmware_info.version_string));
usb_transfer_schedule_block(
endpoint->in,
version_string,
&endpoint->buffer,
length,
NULL,
NULL);

View File

@ -66,7 +66,7 @@ static struct option long_options[] = {
* If you're already running firmware that reports the wrong ID
* I can't help you, but you can use the -i optionto ignore (or DFU)
*/
int compatibility_check(uint8_t* data, int length, hackrf_device* device)
int compatibility_check_og(uint8_t* data, int length, hackrf_device* device)
{
int str_len, i, j;
bool match = false;
@ -88,7 +88,7 @@ int compatibility_check(uint8_t* data, int length, hackrf_device* device)
break;
default:
printf("Unsupported Board ID");
return 1;
return EXIT_FAILURE;
}
// Search for dev_str in uint8_t array of bytes that we're flashing
for (i = 0; i < length - str_len; i++) {
@ -102,11 +102,61 @@ int compatibility_check(uint8_t* data, int length, hackrf_device* device)
}
}
if (match) {
return 0;
return EXIT_SUCCESS;
}
}
}
return 1;
return EXIT_FAILURE;
}
#define FW_INFO_LOCATION 0x400
#define FW_MAGIC_OFFSET 0
#define FW_STRUCT_VERSION_OFFSET 8
#define FW_SUPPORTED_PLATFORMS_OFFSET 12
#define FROM_LE32(x) ((x)[0] | ((x)[1] << 8) | ((x)[2] << 16) | ((x)[3] << 24))
#define FROM_LE16(x) ((x)[0] | ((x)[1] << 8))
int compatibility_check(uint8_t* data, int length, hackrf_device* device)
{
uint8_t board_id;
hackrf_board_id_read(device, &board_id);
uint8_t* fw_info = data + FW_INFO_LOCATION;
if (strncmp((char*) fw_info + FW_MAGIC_OFFSET, "HACKRFFW", 8) != 0) {
// Couldn't find firmware info structure,
// revert to old compatibility check method if possible.
if (board_id != BOARD_ID_HACKRF1_R9) {
return compatibility_check_og(data, length, device);
}
return EXIT_FAILURE;
}
uint32_t platform_required = hackrf_board_id_platform(board_id);
if (platform_required == 0) {
fprintf(stderr,
"Could not find appropriate platform for board id %u (%s).\n",
board_id,
hackrf_board_id_name(board_id));
return EXIT_FAILURE;
}
uint32_t struct_version = FROM_LE16(fw_info + FW_STRUCT_VERSION_OFFSET);
if (struct_version == 1) {
uint32_t supported_platforms =
FROM_LE32(fw_info + FW_SUPPORTED_PLATFORMS_OFFSET);
if (platform_required & supported_platforms) {
return EXIT_SUCCESS;
} else {
return EXIT_FAILURE;
}
} else {
fprintf(stderr,
"Unrecognised firmware info structure version %u. This may require a newer hackrf_spiflash version.\n",
struct_version);
return EXIT_FAILURE;
}
}
int parse_u32(char* s, uint32_t* const value)

View File

@ -2204,6 +2204,26 @@ const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id)
}
}
extern ADDAPI uint32_t ADDCALL hackrf_board_id_platform(enum hackrf_board_id board_id)
{
switch (board_id) {
case BOARD_ID_JAWBREAKER:
return HACKRF_PLATFORM_JAWBREAKER;
case BOARD_ID_HACKRF1_OG:
return HACKRF_PLATFORM_HACKRF1_OG;
case BOARD_ID_RAD1O:
return HACKRF_PLATFORM_RAD1O;
case BOARD_ID_HACKRF1_R9:
return HACKRF_PLATFORM_HACKRF1_R9;
default:
return 0;
}
}
extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(
enum hackrf_usb_board_id usb_board_id)
{

View File

@ -412,6 +412,8 @@ extern ADDAPI const char* ADDCALL hackrf_error_name(enum hackrf_error errcode);
extern ADDAPI const char* ADDCALL hackrf_board_id_name(enum hackrf_board_id board_id);
extern ADDAPI uint32_t ADDCALL hackrf_board_id_platform(enum hackrf_board_id board_id);
extern ADDAPI const char* ADDCALL hackrf_usb_board_id_name(
enum hackrf_usb_board_id usb_board_id);