A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

multiboot: Refactor duplicated functions to a separate file

The implementation of write_bootdata() and get_redirect_dir() was
copied verbatim in two different places, obviously a bad thing for
maintainability. This moves them to a new file multiboot.c as they
are only used for multiboot.

Change-Id: Id0279216e4dd019f8bf612a81d3835eff010e506

+165 -220
+1
apps/debug_menu.c
··· 128 128 129 129 #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) 130 130 #include "bootdata.h" 131 + #include "multiboot.h" 131 132 #include "rbpaths.h" 132 133 #include "pathfuncs.h" 133 134 #include "rb-loader.h"
+4
firmware/SOURCES
··· 51 51 target/hosted/rolo.c 52 52 #endif 53 53 54 + #if defined(HAVE_BOOTDATA) || defined(HAVE_MULTIBOOT) 55 + common/multiboot.c 56 + #endif 57 + 54 58 #ifdef HAVE_SDL 55 59 target/hosted/sdl/button-sdl.c 56 60 target/hosted/sdl/kernel-sdl.c
+113
firmware/common/multiboot.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * 9 + * Copyright (C) 2017, 2020 by William Wilgus 10 + * 11 + * This program is free software; you can redistribute it and/or 12 + * modify it under the terms of the GNU General Public License 13 + * as published by the Free Software Foundation; either version 2 14 + * of the License, or (at your option) any later version. 15 + * 16 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 17 + * KIND, either express or implied. 18 + * 19 + ****************************************************************************/ 20 + 21 + #include "system.h" 22 + #include "bootdata.h" 23 + #include "crc32.h" 24 + #include "loader_strerror.h" 25 + #include "file.h" 26 + #include <string.h> 27 + #include <stdio.h> 28 + 29 + /* Write bootdata into location in FIRMWARE marked by magic header 30 + * Assumes buffer is already loaded with the firmware image 31 + * We just need to find the location and write data into the 32 + * payload region along with the crc for later verification and use. 33 + * Returns payload len on success, 34 + * On error returns EKEY_NOT_FOUND 35 + */ 36 + int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume) 37 + { 38 + struct boot_data_t bl_boot_data; 39 + struct boot_data_t *fw_boot_data = NULL; 40 + int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t); 41 + int payload_len = EKEY_NOT_FOUND; 42 + 43 + /* search for boot data header prior to search_len */ 44 + for(int i = 0;i < search_len;i++) 45 + { 46 + fw_boot_data = (struct boot_data_t*) &buf[i]; 47 + if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 || 48 + fw_boot_data->magic[1] != BOOT_DATA_MAGIC1) 49 + continue; 50 + 51 + memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE); 52 + bl_boot_data.boot_volume = boot_volume; 53 + 54 + memset(fw_boot_data->payload, 0, fw_boot_data->length); 55 + /* determine maximum bytes we can write to firmware 56 + BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */ 57 + payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length); 58 + fw_boot_data->length = payload_len; 59 + /* copy data to FIRMWARE bootdata struct */ 60 + memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len); 61 + /* crc will be used within the firmware to check validity of bootdata */ 62 + fw_boot_data->crc = crc_32(fw_boot_data->payload, payload_len, 0xffffffff); 63 + break; 64 + 65 + } 66 + return payload_len; 67 + } 68 + 69 + #ifdef HAVE_MULTIBOOT 70 + /* Check in root of this <volume> for rockbox_main.<playername> 71 + * if this file empty or there is a single slash '/' 72 + * buf = '<volume#>/<rootdir>/<firmware(name)>\0' 73 + * If instead '/<*DIRECTORY*>' is supplied 74 + * addpath will be set to this DIRECTORY buf = 75 + * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' 76 + * On error returns Negative number or 0 77 + * On success returns bytes from snprintf 78 + * and generated path will be placed in buf 79 + * note: if supplied buffer is too small return will be 80 + * the number of bytes that would have been written 81 + */ 82 + int get_redirect_dir(char* buf, int buffer_size, int volume, 83 + const char* rootdir, const char* firmware) 84 + { 85 + int fd; 86 + int f_offset; 87 + char add_path[MAX_PATH]; 88 + /* Check in root of volume for rockbox_main.<playername> redirect */ 89 + snprintf(add_path, sizeof(add_path), "/<%d>/"BOOT_REDIR, volume); 90 + fd = open(add_path, O_RDONLY); 91 + if (fd < 0) 92 + return EFILE_NOT_FOUND; 93 + 94 + /*clear add_path for re-use*/ 95 + memset(add_path, 0, sizeof(add_path)); 96 + f_offset = read(fd, add_path,sizeof(add_path)); 97 + close(fd); 98 + 99 + for(int i = f_offset - 1;i > 0; i--) 100 + { 101 + /* strip control chars < SPACE or all if path doesn't start with '/' */ 102 + if (add_path[i] < 0x20 || add_path[0] != '/') 103 + add_path[i] = '\0'; 104 + } 105 + /* if '/add_path' is specified in rockbox_main.<playername> 106 + path is /<vol#>/add_path/rootdir/firmwarename 107 + if add_path is empty or '/' is missing from beginning 108 + path is /<vol#>/rootdir/firmwarename 109 + */ 110 + return snprintf(buf, buffer_size, "/<%d>%s/%s/%s", volume, add_path, 111 + rootdir, firmware); 112 + } 113 + #endif
+3 -90
firmware/common/rb-loader.c
··· 26 26 #include "loader_strerror.h" 27 27 #include "checksum.h" 28 28 29 - #if defined(HAVE_BOOTDATA) 30 - #include "bootdata.h" 31 - #include "crc32.h" 32 - 33 - /* Write bootdata into location in FIRMWARE marked by magic header 34 - * Assumes buffer is already loaded with the firmware image 35 - * We just need to find the location and write data into the 36 - * payload region along with the crc for later verification and use. 37 - * Returns payload len on success, 38 - * On error returns EKEY_NOT_FOUND 39 - */ 40 - int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume) 41 - { 42 - struct boot_data_t bl_boot_data; 43 - struct boot_data_t *fw_boot_data = NULL; 44 - int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t); 45 - int payload_len = EKEY_NOT_FOUND; 46 - 47 - /* search for boot data header prior to search_len */ 48 - for(int i = 0;i < search_len;i++) 49 - { 50 - fw_boot_data = (struct boot_data_t*) &buf[i]; 51 - if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 || 52 - fw_boot_data->magic[1] != BOOT_DATA_MAGIC1) 53 - continue; 54 - 55 - memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE); 56 - bl_boot_data.boot_volume = boot_volume; 57 - 58 - memset(fw_boot_data->payload, 0, fw_boot_data->length); 59 - /* determine maximum bytes we can write to firmware 60 - BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */ 61 - payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length); 62 - fw_boot_data->length = payload_len; 63 - /* copy data to FIRMWARE bootdata struct */ 64 - memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len); 65 - /* crc will be used within the firmware to check validity of bootdata */ 66 - fw_boot_data->crc = crc_32(fw_boot_data->payload, payload_len, 0xffffffff); 67 - break; 68 - 69 - } 70 - return payload_len; 71 - } 72 - #endif /* HAVE_BOOTDATA */ 73 - 74 - #ifdef HAVE_MULTIBOOT /* defined by config.h */ 75 - /* Check in root of this <volume> for rockbox_main.<playername> 76 - * if this file empty or there is a single slash '/' 77 - * buf = '<volume#>/<rootdir>/<firmware(name)>\0' 78 - * If instead '/<*DIRECTORY*>' is supplied 79 - * addpath will be set to this DIRECTORY buf = 80 - * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' 81 - * On error returns Negative number or 0 82 - * On success returns bytes from snprintf 83 - * and generated path will be placed in buf 84 - * note: if supplied buffer is too small return will be 85 - * the number of bytes that would have been written 86 - */ 87 - int get_redirect_dir(char* buf, int buffer_size, int volume, 88 - const char* rootdir, const char* firmware) 89 - { 90 - int fd; 91 - int f_offset; 92 - char add_path[MAX_PATH]; 93 - /* Check in root of volume for rockbox_main.<playername> redirect */ 94 - snprintf(add_path, sizeof(add_path), "/<%d>/"BOOT_REDIR, volume); 95 - fd = open(add_path, O_RDONLY); 96 - if (fd < 0) 97 - return EFILE_NOT_FOUND; 98 - 99 - /*clear add_path for re-use*/ 100 - memset(add_path, 0, sizeof(add_path)); 101 - f_offset = read(fd, add_path,sizeof(add_path)); 102 - close(fd); 103 - 104 - for(int i = f_offset - 1;i > 0; i--) 105 - { 106 - /* strip control chars < SPACE or all if path doesn't start with '/' */ 107 - if (add_path[i] < 0x20 || add_path[0] != '/') 108 - add_path[i] = '\0'; 109 - } 110 - /* if '/add_path' is specified in rockbox_main.<playername> 111 - path is /<vol#>/add_path/rootdir/firmwarename 112 - if add_path is empty or '/' is missing from beginning 113 - path is /<vol#>/rootdir/firmwarename 114 - */ 115 - return snprintf(buf, buffer_size, "/<%d>%s/%s/%s", volume, add_path, 116 - rootdir, firmware); 117 - } 118 - #endif /* HAVE_MULTIBOOT */ 29 + #if defined(HAVE_BOOTDATA) || defined(HAVE_MULTIBOOT) 30 + #include "multiboot.h" 31 + #endif 119 32 120 33 /* loads a firmware file from supplied filename 121 34 * file opened, checks firmware size and checksum
+4 -18
firmware/export/mi4-loader.h
··· 21 21 * 22 22 ****************************************************************************/ 23 23 24 + #ifndef __MI4_LOADER_H__ 25 + #define __MI4_LOADER_H__ 26 + 24 27 #include <stdint.h> 25 28 26 29 #define MI4_HEADER_SIZE 0x200 ··· 50 53 int load_mi4(unsigned char* buf, const char* firmware, unsigned int buffer_size); 51 54 const char *mi4_strerror(int8_t errno); 52 55 53 - #ifdef HAVE_MULTIBOOT /* defined by config.h */ 54 - /* Check in root of this <volume> for rockbox_main.<playername> 55 - * if this file empty or there is a single slash '/' 56 - * buf = '<volume#>/<rootdir>/<firmware(name)>\0' 57 - * If instead '/<*DIRECTORY*>' is supplied 58 - * addpath will be set to this DIRECTORY buf = 59 - * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' 60 - * On error returns Negative number or 0 61 - * On success returns bytes from snprintf 62 - * and generated path will be placed in buf 63 - * note: if supplied buffer is too small return will be 64 - * the number of bytes that would have been written 65 - */ 66 - 67 - /* TODO needs mapped back to debug_menu if root redirect ever becomes a reality */ 68 - int get_redirect_dir(char* buf, int buffer_size, int volume, 69 - const char* rootdir, const char* firmware); 70 - #endif 56 + #endif /* __MI4_LOADER_H__ */
+30
firmware/export/multiboot.h
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * 9 + * Copyright (C) 2017, 2020 by William Wilgus 10 + * 11 + * This program is free software; you can redistribute it and/or 12 + * modify it under the terms of the GNU General Public License 13 + * as published by the Free Software Foundation; either version 2 14 + * of the License, or (at your option) any later version. 15 + * 16 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 17 + * KIND, either express or implied. 18 + * 19 + ****************************************************************************/ 20 + 21 + #ifndef __MULTIBOOT_H__ 22 + #define __MULTIBOOT_H__ 23 + 24 + extern int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume); 25 + #ifdef HAVE_MULTIBOOT 26 + extern int get_redirect_dir(char* buf, int buffer_size, int volume, 27 + const char* rootdir, const char* firmware); 28 + #endif 29 + 30 + #endif /* __MULTIBOOT_H__ */
+1
firmware/include/dircache_redirect.h
··· 27 27 28 28 #if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) && !defined(BOOTLOADER) 29 29 #include "rb-loader.h" 30 + #include "multiboot.h" 30 31 #include "bootdata.h" 31 32 #include "crc32.h" 32 33 #endif
+4 -16
firmware/include/rb-loader.h
··· 18 18 * 19 19 ****************************************************************************/ 20 20 21 + #ifndef __RB_LOADER_H__ 22 + #define __RB_LOADER_H__ 23 + 21 24 int load_firmware(unsigned char* buf, const char* firmware, int buffer_size); 22 25 23 - #ifdef HAVE_MULTIBOOT /* defined by config.h */ 24 - /* Check in root of this <volume> for rockbox_main.<playername> 25 - * if this file empty or there is a single slash '/' 26 - * buf = '<volume#>/<rootdir>/<firmware(name)>\0' 27 - * If instead '/<*DIRECTORY*>' is supplied 28 - * addpath will be set to this DIRECTORY buf = 29 - * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' 30 - * On error returns Negative number or 0 31 - * On success returns bytes from snprintf 32 - * and generated path will be placed in buf 33 - * note: if supplied buffer is too small return will be 34 - * the number of bytes that would have been written 35 - */ 36 - int get_redirect_dir(char* buf, int buffer_size, int volume, 37 - const char* rootdir, const char* firmware); 38 - #endif 26 + #endif /* __RB_LOADER_H__ */
+4 -8
firmware/rolo.c
··· 41 41 #include "loader_strerror.h" 42 42 #if defined(MI4_FORMAT) 43 43 #include "mi4-loader.h" 44 - #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) 45 - #include "bootdata.h" 46 - #include "crc32.h" 47 - extern int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume); /*mi4-loader.c*/ 48 - #endif 49 44 #define LOAD_FIRMWARE(a,b,c) load_mi4(a,b,c) 50 45 #elif defined(RKW_FORMAT) 51 46 #include "rkw-loader.h" 52 47 #define LOAD_FIRMWARE(a,b,c) load_rkw(a,b,c) 53 48 #else 54 49 #include "rb-loader.h" 50 + #define LOAD_FIRMWARE(a,b,c) load_firmware(a,b,c) 51 + #endif 52 + 55 53 #if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) 54 + #include "multiboot.h" 56 55 #include "bootdata.h" 57 56 #include "crc32.h" 58 - extern int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume); /*rb-loader.c*/ 59 - #endif 60 - #define LOAD_FIRMWARE(a,b,c) load_firmware(a,b,c) 61 57 #endif 62 58 63 59 #if CONFIG_CPU == AS3525v2
+1 -88
firmware/target/arm/pp/mi4-loader.c
··· 30 30 #include "crc32.h" 31 31 #include "file.h" 32 32 #if defined(HAVE_BOOTDATA) 33 - #include "system.h" 34 - #include "bootdata.h" 35 - 36 - /* Write bootdata into location in FIRMWARE marked by magic header 37 - * Assumes buffer is already loaded with the firmware image 38 - * We just need to find the location and write data into the 39 - * payload region along with the crc for later verification and use. 40 - * Returns payload len on success, 41 - * On error returns EKEY_NOT_FOUND 42 - */ 43 - int write_bootdata(unsigned char* buf, int len, unsigned int boot_volume) 44 - { 45 - struct boot_data_t bl_boot_data; 46 - struct boot_data_t *fw_boot_data = NULL; 47 - int search_len = MIN(len, BOOT_DATA_SEARCH_SIZE) - sizeof(struct boot_data_t); 48 - int payload_len = EKEY_NOT_FOUND; 49 - 50 - /* search for boot data header prior to search_len */ 51 - for(int i = 0;i < search_len;i++) 52 - { 53 - fw_boot_data = (struct boot_data_t*) &buf[i]; 54 - if (fw_boot_data->magic[0] != BOOT_DATA_MAGIC0 || 55 - fw_boot_data->magic[1] != BOOT_DATA_MAGIC1) 56 - continue; 57 - 58 - memset(&bl_boot_data.payload, 0, BOOT_DATA_PAYLOAD_SIZE); 59 - bl_boot_data.boot_volume = boot_volume; 60 - 61 - memset(fw_boot_data->payload, 0, fw_boot_data->length); 62 - /* determine maximum bytes we can write to firmware 63 - BOOT_DATA_PAYLOAD_SIZE is the size the bootloader expects */ 64 - payload_len = MIN(BOOT_DATA_PAYLOAD_SIZE, fw_boot_data->length); 65 - fw_boot_data->length = payload_len; 66 - /* copy data to FIRMWARE bootdata struct */ 67 - memcpy(fw_boot_data->payload, &bl_boot_data.payload, payload_len); 68 - /* crc will be used within the firmware to check validity of bootdata */ 69 - fw_boot_data->crc = crc_32(fw_boot_data->payload, payload_len, 0xffffffff); 70 - break; 71 - 72 - } 73 - return payload_len; 74 - } 33 + #include "multiboot.h" 75 34 #endif /* HAVE_BOOTDATA */ 76 - 77 - #ifdef HAVE_MULTIBOOT /* defined by config.h */ 78 - /* Check in root of this <volume> for rockbox_main.<playername> 79 - * if this file empty or there is a single slash '/' 80 - * buf = '<volume#>/<rootdir>/<firmware(name)>\0' 81 - * If instead '/<*DIRECTORY*>' is supplied 82 - * addpath will be set to this DIRECTORY buf = 83 - * '/<volume#>/addpath/<rootdir>/<firmware(name)>\0' 84 - * On error returns Negative number or 0 85 - * On success returns bytes from snprintf 86 - * and generated path will be placed in buf 87 - * note: if supplied buffer is too small return will be 88 - * the number of bytes that would have been written 89 - */ 90 - int get_redirect_dir(char* buf, int buffer_size, int volume, 91 - const char* rootdir, const char* firmware) 92 - { 93 - int fd; 94 - int f_offset; 95 - char add_path[MAX_PATH]; 96 - /* Check in root of volume for rockbox_main.<playername> redirect */ 97 - snprintf(add_path, sizeof(add_path), "/<%d>/"BOOT_REDIR, volume); 98 - fd = open(add_path, O_RDONLY); 99 - if (fd < 0) 100 - return EFILE_NOT_FOUND; 101 - 102 - /*clear add_path for re-use*/ 103 - memset(add_path, 0, sizeof(add_path)); 104 - f_offset = read(fd, add_path,sizeof(add_path)); 105 - close(fd); 106 - 107 - for(int i = f_offset - 1;i > 0; i--) 108 - { 109 - /* strip control chars < SPACE or all if path doesn't start with '/' */ 110 - if (add_path[i] < 0x20 || add_path[0] != '/') 111 - add_path[i] = '\0'; 112 - } 113 - /* if '/add_path' is specified in rockbox_main.<playername> 114 - path is /<vol#>/add_path/rootdir/firmwarename 115 - if add_path is empty or '/' is missing from beginning 116 - path is /<vol#>/rootdir/firmwarename 117 - */ 118 - return snprintf(buf, buffer_size, "/<%d>%s/%s/%s", volume, add_path, 119 - rootdir, firmware); 120 - } 121 - #endif /* HAVE_MULTIBOOT */ 122 35 123 36 static inline unsigned int le2int(unsigned char* buf) 124 37 {