From bd744059cf959c8b9086978b32660efef5925b7d Mon Sep 17 00:00:00 2001 From: William Wilgus Date: Thu, 20 Aug 2020 19:19:55 -0400 Subject: [PATCH] Multiboot Firmware Root Redirect Firmware now includes rudimentary redirect functionality but this only supports /.rockbox in the root of the device This patch allows loading external drive and directory into root namespace Root Redirects can now be put into different folders For instance placing '/_test' into SD1/rockbox_main. will redirect to /<1>/_test/.rockbox Debug menu>Bootdata now has root directory listed in addition to RAW Bootdata Redirect root work from Michael Sevakis g#1556 Redirect will be updated if code refactor is ever done Requires Multiboot bootloader (already in main) Change-Id: I697b3d0499f85e789c3020bc2133fbe0023f72a2 --- apps/debug_menu.c | 22 +++++++++++++-- firmware/common/disk.c | 18 +++++++++++- firmware/include/dircache_redirect.h | 42 ++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index b93fb45c8f..eae389d049 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -2451,10 +2451,26 @@ static bool dbg_boot_data(void) info.scroll_all = true; simplelist_info_init(&info, "Boot data", 1, NULL); simplelist_set_line_count(0); - simplelist_addline("Magic: %.8s", boot_data.magic); + crc = crc_32(boot_data.payload, boot_data.length, 0xffffffff); +#if defined(HAVE_MULTIBOOT) + char rootpath[VOL_MAX_LEN+2] = RB_ROOT_CONTENTS_DIR; + int boot_volume = 0; + if(crc == boot_data.crc) + { + boot_volume = boot_data.boot_volume; /* boot volume contained in uint8_t payload */ + get_redirect_dir(rootpath, sizeof(rootpath), boot_volume, "", ""); + rootpath[path_strip_trailing_separators(rootpath,NULL)] = '\0'; + } + simplelist_addline("Boot Volume: <%lu>", boot_volume); + simplelist_addline("Root:"); + simplelist_addline("%s", rootpath); + simplelist_addline(""); +#endif + simplelist_addline("Bootdata RAW:"); + if (crc != boot_data.crc) + simplelist_addline("Magic: %.8s", boot_data.magic); simplelist_addline("Length: %lu", boot_data.length); simplelist_addline("CRC: %lx", boot_data.crc); - crc = crc_32(boot_data.payload, boot_data.length, 0xffffffff); (crc == boot_data.crc) ? simplelist_addline("CRC: OK!") : simplelist_addline("CRC: BAD"); for (unsigned i = 0; i < boot_data.length; i += 4) @@ -2466,7 +2482,7 @@ static bool dbg_boot_data(void) info.hide_selection = true; return simplelist_show_list(&info); } -#endif +#endif /* defined(HAVE_BOOTDATA) && !defined(SIMULATOR) */ /****** The menu *********/ static const struct { diff --git a/firmware/common/disk.c b/firmware/common/disk.c index 3bd88f66a8..49137286a3 100644 --- a/firmware/common/disk.c +++ b/firmware/common/disk.c @@ -27,7 +27,7 @@ #include "disk_cache.h" #include "fileobj_mgr.h" #include "dir.h" -#include "rb_namespace.h" +#include "dircache_redirect.h" #include "disk.h" @@ -249,7 +249,23 @@ int disk_mount_all(void) for (int i = 0; i < NUM_VOLUMES; i++) vol_drive[i] = -1; /* mark all as unassigned */ +#if defined(HAVE_BOOTDATA) && !defined(SIMULATOR) && !defined(BOOTLOADER) + unsigned int crc = 0; + int boot_volume = 0; + crc = crc_32(boot_data.payload, boot_data.length, 0xffffffff); + if(crc == boot_data.crc) + { + boot_volume = boot_data.boot_volume; /* boot volume contained in uint8_t payload */ + } + #ifdef HAVE_HOTSWAP + if (storage_present(boot_volume)) + #endif + mounted += disk_mount(boot_volume); /* mount boot volume first */ for (int i = 0; i < NUM_DRIVES; i++) + if (i != boot_volume) +#else + for (int i = 0; i < NUM_DRIVES; i++) +#endif { #ifdef HAVE_HOTSWAP if (storage_present(i)) diff --git a/firmware/include/dircache_redirect.h b/firmware/include/dircache_redirect.h index 9a8de2fecd..e8cf8dc8f5 100644 --- a/firmware/include/dircache_redirect.h +++ b/firmware/include/dircache_redirect.h @@ -25,6 +25,12 @@ #include "dir.h" #include "dircache.h" +#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) +#include "rb-loader.h" +#include "bootdata.h" +#include "crc32.h" +#endif + /*** ** Internal redirects that depend upon whether or not dircache is made ** @@ -132,11 +138,47 @@ static inline void volume_onmount_internal(IF_MV_NONVOID(int volume)) #else const char *path = PATH_ROOTSTR; #endif + +#if defined(HAVE_MULTIBOOT) && !defined(SIMULATOR) + static char rtpath[VOL_MAX_LEN+2] = RB_ROOT_CONTENTS_DIR; + static bool redirected = false; + int boot_volume = 0; + unsigned int crc = 0; + + crc = crc_32(boot_data.payload, boot_data.length, 0xffffffff); + if (crc == boot_data.crc) + { + root_mount_path(path, 0); /*root could be different folder don't hide*/ + boot_volume = boot_data.boot_volume; /* boot volume contained in uint8_t payload */ + //root_mount_path(path, volume == boot_volume ? NSITEM_HIDDEN : 0); + if (!redirected && volume == boot_volume) + { + if (get_redirect_dir(rtpath, sizeof(rtpath), volume, "", "") < 0) + { /* Error occurred, card removed? Set root to default */ + root_mount_path(RB_ROOT_CONTENTS_DIR, NSITEM_CONTENTS); + } + else + redirected = true; + } + if (redirected && volume == boot_volume) + root_mount_path(rtpath, NSITEM_CONTENTS); + } /*CRC OK*/ + else + { + root_mount_path(path, RB_ROOT_VOL_HIDDEN(volume) ? NSITEM_HIDDEN : 0); + if (volume == path_strip_volume(RB_ROOT_CONTENTS_DIR, NULL, false)) + root_mount_path(RB_ROOT_CONTENTS_DIR, NSITEM_CONTENTS); + } +#else + root_mount_path(path, RB_ROOT_VOL_HIDDEN(volume) ? NSITEM_HIDDEN : 0); #ifdef HAVE_MULTIVOLUME if (volume == path_strip_volume(RB_ROOT_CONTENTS_DIR, NULL, false)) #endif root_mount_path(RB_ROOT_CONTENTS_DIR, NSITEM_CONTENTS); + +#endif /* HAVE_MULTIBOOT */ + #ifdef HAVE_DIRCACHE dircache_mount(); #endif