From c876d3bbefe0dc00c27ca0c12d29da5874946962 Mon Sep 17 00:00:00 2001 From: Dominik Riebeling Date: Wed, 15 Dec 2021 21:04:28 +0100 Subject: rbutil: Merge rbutil with utils folder. rbutil uses several components from the utils folder, and can be considered part of utils too. Having it in a separate folder is an arbitrary split that doesn't help anymore these days, so merge them. This also allows other utils to easily use libtools.make without the need to navigate to a different folder. Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21 --- utils/mkmpioboot/mkmpioboot.c | 243 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 utils/mkmpioboot/mkmpioboot.c (limited to 'utils/mkmpioboot/mkmpioboot.c') diff --git a/utils/mkmpioboot/mkmpioboot.c b/utils/mkmpioboot/mkmpioboot.c new file mode 100644 index 0000000000..ea619ed2f2 --- /dev/null +++ b/utils/mkmpioboot/mkmpioboot.c @@ -0,0 +1,243 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id:$ + * + * Copyright (C) 2010 by Marcin Bukat + * + * code taken mostly from mkboot.c + * Copyright (C) 2005 by Linus Nielsen Feltzing + * + * 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 +#include +#include +#include "mkmpioboot.h" + +#define OF_FIRMWARE_LEN 0x100000 /* size of the OF file */ +#define MPIO_STRING_OFFSET 0xfffe0 /* offset of the version string in OF */ +#define BOOTLOADER_MAX_SIZE 0x1f800 /* free space size */ + +struct mpio_model { + /* Descriptive name of this model */ + const char* model_name; + /* Model name used in the Rockbox header in ".mpio" files - these match the + -add parameter to the "scramble" tool */ + const char* rb_model_name; + /* Model number used to initialise the checksum in the Rockbox header in + ".mpio" files - these are the same as MODEL_NUMBER in config-target.h */ + const int rb_model_num; + /* Strings which indentifies OF version */ + const char* of_model_string; +}; + +static const struct mpio_model mpio_models[] = { + [MODEL_HD200] = + { "MPIO HD200", "hd20", 69, "HD200 HDD Audio Ver113005" }, + [MODEL_HD300] = + { "MPIO HD300", "hd30", 70, "HD300 HDD Audio Ver113006" }, +}; + + +/* MPIO HD200 and HD300 firmware is plain binary image + * 4 bytes of initial SP (loaded on reset) + * 4 bytes of initial PC (loaded on reset) + * binary image with entry point 0x00000008 + * + * We put our bootloader code at 0x000e0000 + * and patch reset vector to jump directly + * into our code on reset + */ + +static unsigned char image[OF_FIRMWARE_LEN]; + +static unsigned int get_uint32be(unsigned char* p) +{ + return ((p[0] << 24) | (p[1] << 16) | (p[2]<<8) | p[3]); +} + +static long checksum(unsigned char* buf, int model, unsigned long length) +{ + unsigned long chksum = model; + unsigned long i; + + if(buf == NULL) + return -1; + + for (i = 0; i < length; i++) + { + chksum += *buf++; + } + +return chksum; +} + +int mkmpioboot(const char* infile, const char* bootfile, const char* outfile, int origin) +{ + FILE *f; + int i; + int len; + int model_index; + unsigned long file_checksum; + unsigned char header[8]; + + memset(image, 0xff, sizeof(image)); + + /* First, read the mpio original firmware into the image */ + f = fopen(infile, "rb"); + if(!f) + { + fprintf(stderr, "[ERR] Can not open %s file for reading\n", infile); + return -1; + } + + i = fread(image, 1, OF_FIRMWARE_LEN, f); + if(i < OF_FIRMWARE_LEN) + { + fprintf(stderr, "[ERR] %s file read error\n", infile); + fclose(f); + return -2; + } + + fclose(f); + + /* Now check if we have OF file loaded based on presence + * of the version string in firmware + */ + + for(model_index = 0; model_index < NUM_MODELS; model_index++) + if (strcmp(mpio_models[model_index].of_model_string, + (char*)(image + MPIO_STRING_OFFSET)) == 0) + break; + + if(model_index == NUM_MODELS) + { + fprintf(stderr, "[ERR] Unknown MPIO original firmware version\n"); + return -3; + } + + fprintf(stderr, "[INFO] Loading original firmware file for %s\n", + mpio_models[model_index].model_name); + + /* Now, read the boot loader into the image */ + f = fopen(bootfile, "rb"); + if(!f) + { + fprintf(stderr, "[ERR] Can not open %s file for reading\n", bootfile); + return -4; + } + + fprintf(stderr, "[INFO] Loading Rockbox bootloader file\n"); + + /* get bootloader size + * excluding header + */ + fseek(f, 0, SEEK_END); + len = ftell(f) - 8; + + if (len > BOOTLOADER_MAX_SIZE) + { + fprintf(stderr, "[ERR] Bootloader doesn't fit in firmware file.\n"); + fprintf(stderr, "[ERR] This bootloader is %d bytes long\n", len); + fprintf(stderr, "[ERR] and maximum allowed size is %d bytes\n", + BOOTLOADER_MAX_SIZE); + return -5; + } + + /* Now check if the place we want to put + * our bootloader is free + */ + for(i=0;i