1
0
Fork 0
forked from len0rd/rockbox
foxbox/firmware/common/bootdata.c
Aidan MacDonald dc9d354ed2 multiboot: Add v1 boot protocol
v1 passes the drive and partition number of the boot volume
instead of using the volume number. The volume number isn't
reliable because the same filesystem might get a different
volume number once the firmware is loaded, which will cause
the firmware to use the wrong root volume and fail to locate
the correct .rockbox directory.

Using drive and partition numbers avoids this issue because
drive numbering is fixed and determined by the target.

Change-Id: I7e68b892d9424a1f686197a6122e139b438e5f7e
2024-03-31 16:57:19 +01:00

89 lines
2.4 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2022 by Aidan MacDonald
*
* 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
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "bootdata.h"
#include "crc32.h"
#include <stddef.h>
#ifdef BOOTLOADER
# error "not to be included in bootloader builds"
#endif
bool boot_data_valid;
static bool verify_boot_data_v0(void) INIT_ATTR;
static bool verify_boot_data_v0(void)
{
/* validate protocol version */
if (boot_data.version != 0)
return false;
/* validate length */
if (boot_data.length != 4)
return false;
return true;
}
static bool verify_boot_data_v1(void) INIT_ATTR;
static bool verify_boot_data_v1(void)
{
/* validate protocol version */
if (boot_data.version != 1)
return false;
/* validate length */
if (boot_data.length != 4)
return false;
return true;
}
struct verify_bd_entry
{
int version;
bool (*verify) (void);
};
static const struct verify_bd_entry verify_bd[] INITDATA_ATTR = {
{ 0, verify_boot_data_v0 },
{ 1, verify_boot_data_v1 },
};
void verify_boot_data(void)
{
/* verify payload with checksum - all protocol versions */
uint32_t crc = crc_32(boot_data.payload, boot_data.length, 0xffffffff);
if (crc != boot_data.crc)
return;
/* apply verification specific to the protocol version */
for (size_t i = 0; i < ARRAYLEN(verify_bd); ++i)
{
const struct verify_bd_entry *e = &verify_bd[i];
if (e->version == boot_data.version)
{
if (e->verify())
boot_data_valid = true;
return;
}
}
}