From 18b4f66d9ba06993707b9ab7f064ef9117b53ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Nass=20-=20PlugN?= Date: Sun, 14 Jan 2024 23:39:26 +0100 Subject: [PATCH] Boot order preference implemented via sd:/boot_order.txt, defaults to boot.firm --- stage2/arm9/source/fs.c | 58 +++++++++++++++++++++++++++++++++++++++ stage2/arm9/source/fs.h | 2 ++ stage2/arm9/source/main.c | 31 ++++++++++++++++++++- 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/stage2/arm9/source/fs.c b/stage2/arm9/source/fs.c index cc6bf96..c5611e0 100644 --- a/stage2/arm9/source/fs.c +++ b/stage2/arm9/source/fs.c @@ -82,3 +82,61 @@ bool fileWrite(const void *buffer, const char *path, u32 size) return false; } } + +bool fileExists(const char* path) +{ + FIL file; + if(f_open(&file, path, FA_READ) != FR_OK) return false; + f_close(&file); + return true; +} + +u32 fileReadLine(char *dest, const char *path, u32 lineNum, u32 maxSize) +{ + FIL fil; + FRESULT fr; + UINT br; + u32 totalRead = 0; + u32 currentLine = 0; + bool lineContentStarted = false; + bool endOfFile = false; + + fr = f_open(&fil, path, FA_READ); + if (fr != FR_OK) + return 0; + + while (!endOfFile) + { + char c; + fr = f_read(&fil, &c, 1, &br); + + if (fr != FR_OK || br == 0) + { + endOfFile = true; + if (currentLine != lineNum || !lineContentStarted) + break; + } + + if (c == '\n' || c == '\r') + { + if (currentLine == lineNum) + { + if (!lineContentStarted) + totalRead = 1; + break; + } + currentLine++; + lineContentStarted = false; + } + else if (currentLine == lineNum && totalRead < maxSize - 1) + { + dest[totalRead++] = c; + lineContentStarted = true; + } + } + + dest[totalRead] = '\0'; + f_close(&fil); + + return totalRead; +} diff --git a/stage2/arm9/source/fs.h b/stage2/arm9/source/fs.h index 128b44d..b4e3430 100644 --- a/stage2/arm9/source/fs.h +++ b/stage2/arm9/source/fs.h @@ -12,3 +12,5 @@ bool mountCtrNand(void); void unmountCtrNand(void); u32 fileRead(void *dest, const char *path, u32 size, u32 maxSize); bool fileWrite(const void *buffer, const char *path, u32 size); +bool fileExists(const char* path); +u32 fileReadLine(char *dest, const char *path, u32 lineNum, u32 maxSize); diff --git a/stage2/arm9/source/main.c b/stage2/arm9/source/main.c index df47939..fb3236b 100644 --- a/stage2/arm9/source/main.c +++ b/stage2/arm9/source/main.c @@ -33,9 +33,38 @@ static void invokeArm11Function(Arm11Operation op) while(*operation != ARM11_READY); } +const char *getFirmNameFromBootOrder(void) +{ + const char* bootOrder = NULL; + if (fileExists("boot_order.txt")) + bootOrder = "boot_order.txt"; + else if (fileExists("bootorder.txt")) + bootOrder = "bootorder.txt"; + + if (bootOrder) + { + static char line[2048]; + u32 lineNumber = 0; + u32 bytesRead; + + while ((bytesRead = fileReadLine(line, bootOrder, lineNumber, sizeof(line))) > 0) + { + line[bytesRead] = '\0'; + + if (fileExists(line)) + return line; + + lineNumber++; + } + } + + return "boot.firm"; +} + static FirmLoadStatus loadFirm(Firm **outFirm) { - static const char *firmName = "boot.firm"; + const char *firmName = getFirmNameFromBootOrder(); + Firm *firmHeader = (Firm *)0x080A0000; u32 rd = fileRead(firmHeader, firmName, 0x200, 0); if (rd != 0x200)