mirror of
https://github.com/CTCaer/hekate
synced 2024-12-22 11:21:23 +00:00
Add support for split inis in 'bootloader/ini'
- A new option was added to Launch. - These can be configured for autoboot
This commit is contained in:
parent
7e876388b4
commit
5328f89ffe
9 changed files with 518 additions and 105 deletions
1
Makefile
1
Makefile
|
@ -41,6 +41,7 @@ OBJS = $(addprefix $(BUILD)/$(TARGET)/, \
|
||||||
se.o \
|
se.o \
|
||||||
tsec.o \
|
tsec.o \
|
||||||
uart.o \
|
uart.o \
|
||||||
|
dirlist.o \
|
||||||
ini.o \
|
ini.o \
|
||||||
ianos.o \
|
ianos.o \
|
||||||
)
|
)
|
||||||
|
|
|
@ -39,6 +39,7 @@ extern int sd_unmount();
|
||||||
void set_default_configuration()
|
void set_default_configuration()
|
||||||
{
|
{
|
||||||
h_cfg.autoboot = 0;
|
h_cfg.autoboot = 0;
|
||||||
|
h_cfg.autoboot_list = 0;
|
||||||
h_cfg.bootwait = 3;
|
h_cfg.bootwait = 3;
|
||||||
h_cfg.customlogo = 0;
|
h_cfg.customlogo = 0;
|
||||||
h_cfg.verification = 2;
|
h_cfg.verification = 2;
|
||||||
|
@ -56,7 +57,7 @@ int create_config_entry()
|
||||||
|
|
||||||
LIST_INIT(ini_sections);
|
LIST_INIT(ini_sections);
|
||||||
|
|
||||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini"))
|
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||||
{
|
{
|
||||||
if (f_open(&fp, "bootloader/hekate_ipl.ini", FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
|
if (f_open(&fp, "bootloader/hekate_ipl.ini", FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -64,6 +65,9 @@ int create_config_entry()
|
||||||
f_puts("[config]\nautoboot=", &fp);
|
f_puts("[config]\nautoboot=", &fp);
|
||||||
itoa(h_cfg.autoboot, lbuf, 10);
|
itoa(h_cfg.autoboot, lbuf, 10);
|
||||||
f_puts(lbuf, &fp);
|
f_puts(lbuf, &fp);
|
||||||
|
f_puts("\nautoboot_list=", &fp);
|
||||||
|
itoa(h_cfg.autoboot_list, lbuf, 10);
|
||||||
|
f_puts(lbuf, &fp);
|
||||||
f_puts("\nbootwait=", &fp);
|
f_puts("\nbootwait=", &fp);
|
||||||
itoa(h_cfg.bootwait, lbuf, 10);
|
itoa(h_cfg.bootwait, lbuf, 10);
|
||||||
f_puts(lbuf, &fp);
|
f_puts(lbuf, &fp);
|
||||||
|
@ -123,7 +127,7 @@ int create_config_entry()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void config_autoboot()
|
void _config_autoboot_list()
|
||||||
{
|
{
|
||||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
gfx_con_setpos(&gfx_con, 0, 0);
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
@ -143,7 +147,112 @@ void config_autoboot()
|
||||||
|
|
||||||
if (sd_mount())
|
if (sd_mount())
|
||||||
{
|
{
|
||||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini"))
|
if (ini_parse(&ini_sections, "bootloader/ini", true))
|
||||||
|
{
|
||||||
|
// Build configuration menu.
|
||||||
|
ments[0].type = MENT_BACK;
|
||||||
|
ments[0].caption = "Back";
|
||||||
|
|
||||||
|
ments[1].type = MENT_CHGLINE;
|
||||||
|
|
||||||
|
u32 i = 2;
|
||||||
|
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||||
|
{
|
||||||
|
// Skip other ini entries for autoboot.
|
||||||
|
if (ini_sec->type == INI_CHOICE)
|
||||||
|
{
|
||||||
|
if (!strcmp(ini_sec->name, "config"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strlen(ini_sec->name) > 510)
|
||||||
|
ments[i].caption = ini_sec->name;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (h_cfg.autoboot != (i - 1) || !h_cfg.autoboot_list)
|
||||||
|
boot_text[(i - 1) * 512] = ' ';
|
||||||
|
|
||||||
|
else
|
||||||
|
boot_text[(i - 1) * 512] = '*';
|
||||||
|
memcpy(boot_text + (i - 1) * 512 + 1, ini_sec->name, strlen(ini_sec->name));
|
||||||
|
boot_text[strlen(ini_sec->name) + (i - 1) * 512 + 1] = 0;
|
||||||
|
ments[i].caption = &boot_text[(i - 1) * 512];
|
||||||
|
}
|
||||||
|
ments[i].type = ini_sec->type;
|
||||||
|
ments[i].data = &boot_values[i - 1];
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if ((i - 1) > max_entries)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i < 3)
|
||||||
|
{
|
||||||
|
EPRINTF("No launch configurations found.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&ments[i], 0, sizeof(ment_t));
|
||||||
|
menu_t menu = {ments, "Select a list entry to auto boot", 0, 0};
|
||||||
|
temp_autoboot = (u32 *)tui_do_menu(&gfx_con, &menu);
|
||||||
|
if (temp_autoboot != NULL)
|
||||||
|
{
|
||||||
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
|
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||||
|
h_cfg.autoboot_list = 1;
|
||||||
|
// Save choice to ini file.
|
||||||
|
if (!create_config_entry())
|
||||||
|
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||||
|
else
|
||||||
|
EPRINTF("\nConfiguration saving failed!");
|
||||||
|
gfx_puts(&gfx_con, "\nPress any key...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto out2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EPRINTF("Could not find or open 'hekate_ipl.ini'.\nMake sure it exists in SD Card!.");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:;
|
||||||
|
btn_wait();
|
||||||
|
out2:;
|
||||||
|
free(ments);
|
||||||
|
free(boot_values);
|
||||||
|
free(boot_text);
|
||||||
|
ini_free(&ini_sections);
|
||||||
|
|
||||||
|
sd_unmount();
|
||||||
|
|
||||||
|
if (temp_autoboot == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_autoboot()
|
||||||
|
{
|
||||||
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
|
u32 *temp_autoboot = NULL;
|
||||||
|
|
||||||
|
LIST_INIT(ini_sections);
|
||||||
|
|
||||||
|
u8 max_entries = 30;
|
||||||
|
|
||||||
|
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5));
|
||||||
|
u32 *boot_values = (u32 *)malloc(sizeof(u32) * max_entries);
|
||||||
|
char *boot_text = (char *)malloc(512 * max_entries);
|
||||||
|
|
||||||
|
for (u32 j = 0; j < max_entries; j++)
|
||||||
|
boot_values[j] = j;
|
||||||
|
|
||||||
|
if (sd_mount())
|
||||||
|
{
|
||||||
|
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||||
{
|
{
|
||||||
// Build configuration menu.
|
// Build configuration menu.
|
||||||
ments[0].type = MENT_BACK;
|
ments[0].type = MENT_BACK;
|
||||||
|
@ -158,7 +267,17 @@ void config_autoboot()
|
||||||
ments[2].caption = " Disable";
|
ments[2].caption = " Disable";
|
||||||
ments[2].data = &boot_values[0];
|
ments[2].data = &boot_values[0];
|
||||||
|
|
||||||
u32 i = 3;
|
ments[3].type = MENT_HANDLER;
|
||||||
|
if (h_cfg.autoboot_list)
|
||||||
|
ments[3].caption = "*More configs...";
|
||||||
|
else
|
||||||
|
ments[3].caption = " More configs...";
|
||||||
|
ments[3].handler = _config_autoboot_list;
|
||||||
|
ments[3].data = NULL;
|
||||||
|
|
||||||
|
ments[4].type = MENT_CHGLINE;
|
||||||
|
|
||||||
|
u32 i = 5;
|
||||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||||
{
|
{
|
||||||
// Skip other ini entries for autoboot.
|
// Skip other ini entries for autoboot.
|
||||||
|
@ -171,24 +290,24 @@ void config_autoboot()
|
||||||
ments[i].caption = ini_sec->name;
|
ments[i].caption = ini_sec->name;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (h_cfg.autoboot != (i - 2))
|
if (h_cfg.autoboot != (i - 4) || h_cfg.autoboot_list)
|
||||||
boot_text[(i - 2) * 512] = ' ';
|
boot_text[(i - 4) * 512] = ' ';
|
||||||
|
|
||||||
else
|
else
|
||||||
boot_text[(i - 2) * 512] = '*';
|
boot_text[(i - 4) * 512] = '*';
|
||||||
memcpy(boot_text + (i - 2) * 512 + 1, ini_sec->name, strlen(ini_sec->name));
|
memcpy(boot_text + (i - 4) * 512 + 1, ini_sec->name, strlen(ini_sec->name));
|
||||||
boot_text[strlen(ini_sec->name) + (i - 2) * 512 + 1] = 0;
|
boot_text[strlen(ini_sec->name) + (i - 4) * 512 + 1] = 0;
|
||||||
ments[i].caption = &boot_text[(i - 2) * 512];
|
ments[i].caption = &boot_text[(i - 4) * 512];
|
||||||
}
|
}
|
||||||
ments[i].type = ini_sec->type;
|
ments[i].type = ini_sec->type;
|
||||||
ments[i].data = &boot_values[i - 2];
|
ments[i].data = &boot_values[i - 4];
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (i > max_entries)
|
if ((i - 4) > max_entries)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < 4)
|
if (i < 6 && !h_cfg.autoboot_list)
|
||||||
{
|
{
|
||||||
EPRINTF("No launch configurations found.");
|
EPRINTF("No launch configurations found.");
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -203,6 +322,7 @@ void config_autoboot()
|
||||||
gfx_con_setpos(&gfx_con, 0, 0);
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
h_cfg.autoboot = *(u32 *)temp_autoboot;
|
||||||
|
h_cfg.autoboot_list = 0;
|
||||||
// Save choice to ini file.
|
// Save choice to ini file.
|
||||||
if (!create_config_entry())
|
if (!create_config_entry())
|
||||||
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
gfx_puts(&gfx_con, "\nConfiguration was saved!\n");
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
typedef struct _hekate_config
|
typedef struct _hekate_config
|
||||||
{
|
{
|
||||||
u32 autoboot;
|
u32 autoboot;
|
||||||
|
u32 autoboot_list;
|
||||||
u32 bootwait;
|
u32 bootwait;
|
||||||
u32 customlogo;
|
u32 customlogo;
|
||||||
u32 verification;
|
u32 verification;
|
||||||
|
|
|
@ -20,119 +20,162 @@
|
||||||
#include "ini.h"
|
#include "ini.h"
|
||||||
#include "../libs/fatfs/ff.h"
|
#include "../libs/fatfs/ff.h"
|
||||||
#include "../mem/heap.h"
|
#include "../mem/heap.h"
|
||||||
|
#include "../utils/dirlist.h"
|
||||||
|
|
||||||
static char *_strdup(char *str)
|
static char *_strdup(char *str)
|
||||||
{
|
{
|
||||||
char *res = malloc(strlen(str) + 1);
|
char *res = (char *)malloc(strlen(str) + 1);
|
||||||
strcpy(res, str);
|
strcpy(res, str);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ini_parse(link_t *dst, char *ini_path)
|
int ini_parse(link_t *dst, char *ini_path, bool is_dir)
|
||||||
{
|
{
|
||||||
u32 lblen;
|
u32 lblen;
|
||||||
|
u32 pathlen = strlen(ini_path);
|
||||||
|
u32 k = 0;
|
||||||
char lbuf[512];
|
char lbuf[512];
|
||||||
|
char *filelist = NULL;
|
||||||
FIL fp;
|
FIL fp;
|
||||||
ini_sec_t *csec = NULL;
|
ini_sec_t *csec = NULL;
|
||||||
|
|
||||||
if (f_open(&fp, ini_path, FA_READ) != FR_OK)
|
char *filename = (char *)malloc(256);
|
||||||
return 0;
|
|
||||||
|
memcpy(filename, ini_path, pathlen + 1);
|
||||||
|
|
||||||
|
if (is_dir)
|
||||||
|
{
|
||||||
|
filelist = dirlist(filename);
|
||||||
|
if (!filelist)
|
||||||
|
{
|
||||||
|
free(filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memcpy(filename + pathlen, "/", 2);
|
||||||
|
pathlen++;
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// Fetch one line.
|
if (is_dir)
|
||||||
lbuf[0] = 0;
|
|
||||||
f_gets(lbuf, 512, &fp);
|
|
||||||
lblen = strlen(lbuf);
|
|
||||||
|
|
||||||
// Remove trailing newline.
|
|
||||||
if (lbuf[lblen - 1] == '\n')
|
|
||||||
lbuf[lblen - 1] = 0;
|
|
||||||
|
|
||||||
if (lblen > 2 && lbuf[0] == '[') // Create new section.
|
|
||||||
{
|
{
|
||||||
if (csec)
|
if (filelist[k * 256])
|
||||||
{
|
{
|
||||||
list_append(dst, &csec->link);
|
memcpy(filename + pathlen, &filelist[k * 256], strlen(&filelist[k * 256]) + 1);
|
||||||
csec = NULL;
|
k++;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
u32 i;
|
break;
|
||||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != ']'; i++)
|
|
||||||
;
|
|
||||||
lbuf[i] = 0;
|
|
||||||
|
|
||||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
|
||||||
csec->name = _strdup(&lbuf[1]);
|
|
||||||
csec->type = INI_CHOICE;
|
|
||||||
list_init(&csec->kvs);
|
|
||||||
}
|
}
|
||||||
else if (lblen > 2 && lbuf[0] == '{') //Create new caption.
|
|
||||||
|
if (f_open(&fp, filename, FA_READ) != FR_OK)
|
||||||
{
|
{
|
||||||
if (csec)
|
free(filelist);
|
||||||
|
free(filename);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
// Fetch one line.
|
||||||
|
lbuf[0] = 0;
|
||||||
|
f_gets(lbuf, 512, &fp);
|
||||||
|
lblen = strlen(lbuf);
|
||||||
|
|
||||||
|
// Remove trailing newline.
|
||||||
|
if (lbuf[lblen - 1] == '\n')
|
||||||
|
lbuf[lblen - 1] = 0;
|
||||||
|
|
||||||
|
if (lblen > 2 && lbuf[0] == '[') // Create new section.
|
||||||
{
|
{
|
||||||
list_append(dst, &csec->link);
|
if (csec)
|
||||||
csec = NULL;
|
{
|
||||||
|
list_append(dst, &csec->link);
|
||||||
|
csec = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != ']'; i++)
|
||||||
|
;
|
||||||
|
lbuf[i] = 0;
|
||||||
|
|
||||||
|
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||||
|
csec->name = _strdup(&lbuf[1]);
|
||||||
|
csec->type = INI_CHOICE;
|
||||||
|
list_init(&csec->kvs);
|
||||||
}
|
}
|
||||||
|
else if (lblen > 2 && lbuf[0] == '{') //Create new caption.
|
||||||
u32 i;
|
|
||||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '}'; i++)
|
|
||||||
;
|
|
||||||
lbuf[i] = 0;
|
|
||||||
|
|
||||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
|
||||||
csec->name = _strdup(&lbuf[1]);
|
|
||||||
csec->type = INI_CAPTION;
|
|
||||||
csec->color = 0xFF0AB9E6;
|
|
||||||
}
|
|
||||||
else if (lblen > 2 && lbuf[0] == '#') //Create empty lines and comments.
|
|
||||||
{
|
|
||||||
if (csec)
|
|
||||||
{
|
{
|
||||||
list_append(dst, &csec->link);
|
if (csec)
|
||||||
csec = NULL;
|
{
|
||||||
|
list_append(dst, &csec->link);
|
||||||
|
csec = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '}'; i++)
|
||||||
|
;
|
||||||
|
lbuf[i] = 0;
|
||||||
|
|
||||||
|
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||||
|
csec->name = _strdup(&lbuf[1]);
|
||||||
|
csec->type = INI_CAPTION;
|
||||||
|
csec->color = 0xFF0AB9E6;
|
||||||
}
|
}
|
||||||
|
else if (lblen > 2 && lbuf[0] == '#') //Create empty lines and comments.
|
||||||
u32 i;
|
|
||||||
for (i = 0; i < lblen && lbuf[i] != '\n'; i++)
|
|
||||||
;
|
|
||||||
lbuf[i] = 0;
|
|
||||||
|
|
||||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
|
||||||
csec->name = _strdup(&lbuf[1]);
|
|
||||||
csec->type = INI_COMMENT;
|
|
||||||
}
|
|
||||||
else if (lblen <= 1)
|
|
||||||
{
|
|
||||||
if (csec)
|
|
||||||
{
|
{
|
||||||
list_append(dst, &csec->link);
|
if (csec)
|
||||||
csec = NULL;
|
{
|
||||||
|
list_append(dst, &csec->link);
|
||||||
|
csec = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
for (i = 0; i < lblen && lbuf[i] != '\n'; i++)
|
||||||
|
;
|
||||||
|
lbuf[i] = 0;
|
||||||
|
|
||||||
|
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||||
|
csec->name = _strdup(&lbuf[1]);
|
||||||
|
csec->type = INI_COMMENT;
|
||||||
}
|
}
|
||||||
|
else if (lblen < 2)
|
||||||
|
{
|
||||||
|
if (csec)
|
||||||
|
{
|
||||||
|
list_append(dst, &csec->link);
|
||||||
|
csec = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
csec = (ini_sec_t *)malloc(sizeof(ini_sec_t));
|
||||||
csec->name = NULL;
|
csec->name = NULL;
|
||||||
csec->type = INI_NEWLINE;
|
csec->type = INI_NEWLINE;
|
||||||
}
|
}
|
||||||
else if (csec->type == INI_CHOICE) //Extract key/value.
|
else if (csec->type == INI_CHOICE) //Extract key/value.
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '='; i++)
|
for (i = 0; i < lblen && lbuf[i] != '\n' && lbuf[i] != '='; i++)
|
||||||
;
|
;
|
||||||
lbuf[i] = 0;
|
lbuf[i] = 0;
|
||||||
|
|
||||||
ini_kv_t *kv = (ini_kv_t *)malloc(sizeof(ini_kv_t));
|
ini_kv_t *kv = (ini_kv_t *)malloc(sizeof(ini_kv_t));
|
||||||
kv->key = _strdup(&lbuf[0]);
|
kv->key = _strdup(&lbuf[0]);
|
||||||
kv->val = _strdup(&lbuf[i + 1]);
|
kv->val = _strdup(&lbuf[i + 1]);
|
||||||
list_append(&csec->kvs, &kv->link);
|
list_append(&csec->kvs, &kv->link);
|
||||||
}
|
}
|
||||||
} while (!f_eof(&fp));
|
} while (!f_eof(&fp));
|
||||||
|
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
|
||||||
|
} while (is_dir);
|
||||||
|
|
||||||
if (csec)
|
if (csec)
|
||||||
list_append(dst, &csec->link);
|
list_append(dst, &csec->link);
|
||||||
|
|
||||||
|
free(filename);
|
||||||
|
free(filelist);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ typedef struct _ini_sec_t
|
||||||
u32 color;
|
u32 color;
|
||||||
} ini_sec_t;
|
} ini_sec_t;
|
||||||
|
|
||||||
int ini_parse(link_t *dst, char *ini_path);
|
int ini_parse(link_t *dst, char *ini_path, bool is_dir);
|
||||||
void ini_free(link_t *dst);
|
void ini_free(link_t *dst);
|
||||||
ini_sec_t *ini_clone_section(ini_sec_t *cfg);
|
ini_sec_t *ini_clone_section(ini_sec_t *cfg);
|
||||||
void ini_free_section(ini_sec_t *cfg);
|
void ini_free_section(ini_sec_t *cfg);
|
||||||
|
|
|
@ -390,7 +390,7 @@ static int _config_kip1patch(launch_ctxt_t *ctxt, const char *value)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int valueLen = strlen(value);
|
int valueLen = strlen(value);
|
||||||
if (valueLen == 0)
|
if (!valueLen)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ctxt->kip1_patches == NULL)
|
if (ctxt->kip1_patches == NULL)
|
||||||
|
@ -435,10 +435,15 @@ static const cfg_handler_t _config_handlers[] = {
|
||||||
static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
|
static int _config(launch_ctxt_t *ctxt, ini_sec_t *cfg)
|
||||||
{
|
{
|
||||||
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
|
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg->kvs, link)
|
||||||
|
{
|
||||||
for(u32 i = 0; _config_handlers[i].key; i++)
|
for(u32 i = 0; _config_handlers[i].key; i++)
|
||||||
if (!strcmp(_config_handlers[i].key, kv->key) &&
|
{
|
||||||
!_config_handlers[i].handler(ctxt, kv->val))
|
if (!strcmp(_config_handlers[i].key, kv->key))
|
||||||
return 0;
|
if (!_config_handlers[i].handler(ctxt, kv->val))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,7 +672,7 @@ int hos_launch(ini_sec_t *cfg)
|
||||||
// Wait for secmon to get ready.
|
// Wait for secmon to get ready.
|
||||||
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
|
cluster_boot_cpu0(ctxt.pkg1_id->secmon_base);
|
||||||
while (!*mb_out)
|
while (!*mb_out)
|
||||||
;
|
usleep(1); // This only works when in IRAM or with a trained DRAM.
|
||||||
|
|
||||||
//TODO: pkg1.1 locks PMC scratches, we can do that too at some point.
|
//TODO: pkg1.1 locks PMC scratches, we can do that too at some point.
|
||||||
/*PMC(0x4) = 0x7FFFF3;
|
/*PMC(0x4) = 0x7FFFF3;
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include "power/bq24193.h"
|
#include "power/bq24193.h"
|
||||||
#include "config/config.h"
|
#include "config/config.h"
|
||||||
#include "ianos/ianos.h"
|
#include "ianos/ianos.h"
|
||||||
|
#include "utils/dirlist.h"
|
||||||
|
|
||||||
//TODO: ugly.
|
//TODO: ugly.
|
||||||
gfx_ctxt_t gfx_ctxt;
|
gfx_ctxt_t gfx_ctxt;
|
||||||
|
@ -1720,6 +1721,102 @@ out:
|
||||||
btn_wait();
|
btn_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ini_list_launcher()
|
||||||
|
{
|
||||||
|
u8 max_entries = 61;
|
||||||
|
char *payload_path = NULL;
|
||||||
|
|
||||||
|
ini_sec_t *cfg_sec = NULL;
|
||||||
|
LIST_INIT(ini_list_sections);
|
||||||
|
|
||||||
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
|
gfx_con_setpos(&gfx_con, 0, 0);
|
||||||
|
|
||||||
|
if (sd_mount())
|
||||||
|
{
|
||||||
|
if (ini_parse(&ini_list_sections, "bootloader/ini", true))
|
||||||
|
{
|
||||||
|
// Build configuration menu.
|
||||||
|
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
|
||||||
|
ments[0].type = MENT_BACK;
|
||||||
|
ments[0].caption = "Back";
|
||||||
|
ments[1].type = MENT_CHGLINE;
|
||||||
|
|
||||||
|
u32 i = 2;
|
||||||
|
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_list_sections, link)
|
||||||
|
{
|
||||||
|
if (!strcmp(ini_sec->name, "config") ||
|
||||||
|
ini_sec->type == INI_COMMENT || ini_sec->type == INI_NEWLINE)
|
||||||
|
continue;
|
||||||
|
ments[i].type = ini_sec->type;
|
||||||
|
ments[i].caption = ini_sec->name;
|
||||||
|
ments[i].data = ini_sec;
|
||||||
|
if (ini_sec->type == MENT_CAPTION)
|
||||||
|
ments[i].color = ini_sec->color;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if ((i - 1) > max_entries)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i > 2)
|
||||||
|
{
|
||||||
|
memset(&ments[i], 0, sizeof(ment_t));
|
||||||
|
menu_t menu = {
|
||||||
|
ments, "Launch ini configurations", 0, 0
|
||||||
|
};
|
||||||
|
cfg_sec = ini_clone_section((ini_sec_t *)tui_do_menu(&gfx_con, &menu));
|
||||||
|
if (!cfg_sec)
|
||||||
|
{
|
||||||
|
free(ments);
|
||||||
|
ini_free(&ini_list_sections);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
EPRINTF("No ini configurations found.");
|
||||||
|
free(ments);
|
||||||
|
//ini_free(&ini_list_sections); // This breaks hos_launch config parsing.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
EPRINTF("Could not find any ini\nin bootloader/ini folder!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cfg_sec)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
#ifdef MENU_LOGO_ENABLE
|
||||||
|
free(Kc_MENU_LOGO);
|
||||||
|
#endif //MENU_LOGO_ENABLE
|
||||||
|
|
||||||
|
payload_path = ini_check_payload_section(cfg_sec);
|
||||||
|
|
||||||
|
if (payload_path)
|
||||||
|
{
|
||||||
|
ini_free_section(cfg_sec);
|
||||||
|
//if (launch_payload(payload_path, false))
|
||||||
|
//{
|
||||||
|
EPRINTF("Failed to launch payload.");
|
||||||
|
free(payload_path);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
else if (!hos_launch(cfg_sec))
|
||||||
|
{
|
||||||
|
EPRINTF("Failed to launch firmware.");
|
||||||
|
btn_wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MENU_LOGO_ENABLE
|
||||||
|
Kc_MENU_LOGO = (u8 *)malloc(0x6000);
|
||||||
|
blz_uncompress_srcdest(Kc_MENU_LOGO_blz, SZ_MENU_LOGO_BLZ, Kc_MENU_LOGO, SZ_MENU_LOGO);
|
||||||
|
#endif //MENU_LOGO_ENABLE
|
||||||
|
|
||||||
|
out:
|
||||||
|
ini_free_section(cfg_sec);
|
||||||
|
|
||||||
|
btn_wait();
|
||||||
|
}
|
||||||
|
|
||||||
void launch_firmware()
|
void launch_firmware()
|
||||||
{
|
{
|
||||||
u8 max_entries = 61;
|
u8 max_entries = 61;
|
||||||
|
@ -1732,15 +1829,21 @@ void launch_firmware()
|
||||||
|
|
||||||
if (sd_mount())
|
if (sd_mount())
|
||||||
{
|
{
|
||||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini"))
|
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||||
{
|
{
|
||||||
// Build configuration menu.
|
// Build configuration menu.
|
||||||
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 3));
|
ment_t *ments = (ment_t *)malloc(sizeof(ment_t) * (max_entries + 5));
|
||||||
ments[0].type = MENT_BACK;
|
ments[0].type = MENT_BACK;
|
||||||
ments[0].caption = "Back";
|
ments[0].caption = "Back";
|
||||||
ments[1].type = MENT_CHGLINE;
|
ments[1].type = MENT_CHGLINE;
|
||||||
|
|
||||||
u32 i = 2;
|
ments[2].type = MENT_HANDLER;
|
||||||
|
ments[2].caption = "More configs...";
|
||||||
|
ments[2].handler = ini_list_launcher;
|
||||||
|
|
||||||
|
ments[3].type = MENT_CHGLINE;
|
||||||
|
|
||||||
|
u32 i = 4;
|
||||||
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, &ini_sections, link)
|
||||||
{
|
{
|
||||||
if (!strcmp(ini_sec->name, "config") ||
|
if (!strcmp(ini_sec->name, "config") ||
|
||||||
|
@ -1753,10 +1856,10 @@ void launch_firmware()
|
||||||
ments[i].color = ini_sec->color;
|
ments[i].color = ini_sec->color;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (i > max_entries)
|
if ((i - 3) > max_entries)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i > 2)
|
if (i > 4)
|
||||||
{
|
{
|
||||||
memset(&ments[i], 0, sizeof(ment_t));
|
memset(&ments[i], 0, sizeof(ment_t));
|
||||||
menu_t menu = {
|
menu_t menu = {
|
||||||
|
@ -1828,12 +1931,15 @@ void auto_launch_firmware()
|
||||||
|
|
||||||
ini_sec_t *cfg_sec = NULL;
|
ini_sec_t *cfg_sec = NULL;
|
||||||
LIST_INIT(ini_sections);
|
LIST_INIT(ini_sections);
|
||||||
|
LIST_INIT(ini_list_sections);
|
||||||
|
|
||||||
gfx_con.mute = true;
|
gfx_con.mute = true;
|
||||||
|
|
||||||
if (sd_mount())
|
if (sd_mount())
|
||||||
{
|
{
|
||||||
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini"))
|
auto_launch_update();
|
||||||
|
|
||||||
|
if (ini_parse(&ini_sections, "bootloader/hekate_ipl.ini", false))
|
||||||
{
|
{
|
||||||
u32 configEntry = 0;
|
u32 configEntry = 0;
|
||||||
u32 boot_entry_id = 0;
|
u32 boot_entry_id = 0;
|
||||||
|
@ -1851,6 +1957,8 @@ void auto_launch_firmware()
|
||||||
{
|
{
|
||||||
if (!strcmp("autoboot", kv->key))
|
if (!strcmp("autoboot", kv->key))
|
||||||
h_cfg.autoboot = atoi(kv->val);
|
h_cfg.autoboot = atoi(kv->val);
|
||||||
|
else if (!strcmp("autoboot_list", kv->key))
|
||||||
|
h_cfg.autoboot_list = atoi(kv->val);
|
||||||
else if (!strcmp("bootwait", kv->key))
|
else if (!strcmp("bootwait", kv->key))
|
||||||
h_cfg.bootwait = atoi(kv->val);
|
h_cfg.bootwait = atoi(kv->val);
|
||||||
else if (!strcmp("customlogo", kv->key))
|
else if (!strcmp("customlogo", kv->key))
|
||||||
|
@ -1869,6 +1977,7 @@ void auto_launch_firmware()
|
||||||
{
|
{
|
||||||
if (!strcmp("logopath", kv->key))
|
if (!strcmp("logopath", kv->key))
|
||||||
bootlogoCustomEntry = kv->val;
|
bootlogoCustomEntry = kv->val;
|
||||||
|
gfx_printf(&gfx_con, "\n%s=%s\n\n", kv->key, kv->val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1876,6 +1985,43 @@ void auto_launch_firmware()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (h_cfg.autoboot_list)
|
||||||
|
{
|
||||||
|
ini_free(&ini_sections);
|
||||||
|
list_init(&ini_sections);
|
||||||
|
ini_free_section(cfg_sec);
|
||||||
|
boot_entry_id = 1;
|
||||||
|
bootlogoCustomEntry = NULL;
|
||||||
|
|
||||||
|
if (ini_parse(&ini_list_sections, "bootloader/ini", true))
|
||||||
|
{
|
||||||
|
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec_list, &ini_list_sections, link)
|
||||||
|
{
|
||||||
|
if (ini_sec_list->type == INI_CHOICE)
|
||||||
|
{
|
||||||
|
if (!strcmp(ini_sec_list->name, "config"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (h_cfg.autoboot == boot_entry_id)
|
||||||
|
{
|
||||||
|
cfg_sec = ini_clone_section(ini_sec_list);
|
||||||
|
LIST_FOREACH_ENTRY(ini_kv_t, kv, &cfg_sec->kvs, link)
|
||||||
|
{
|
||||||
|
if (!strcmp("logopath", kv->key))
|
||||||
|
bootlogoCustomEntry = kv->val;
|
||||||
|
gfx_printf(&gfx_con, "\n%s=%s\n\n", kv->key, kv->val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
boot_entry_id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Add missing configuration entry.
|
// Add missing configuration entry.
|
||||||
if (!configEntry)
|
if (!configEntry)
|
||||||
create_config_entry();
|
create_config_entry();
|
||||||
|
@ -1969,6 +2115,8 @@ void auto_launch_firmware()
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ini_free(&ini_sections);
|
ini_free(&ini_sections);
|
||||||
|
if (h_cfg.autoboot_list)
|
||||||
|
ini_free(&ini_list_sections);
|
||||||
|
|
||||||
#ifdef MENU_LOGO_ENABLE
|
#ifdef MENU_LOGO_ENABLE
|
||||||
free(Kc_MENU_LOGO);
|
free(Kc_MENU_LOGO);
|
||||||
|
@ -1985,6 +2133,8 @@ void auto_launch_firmware()
|
||||||
out:
|
out:
|
||||||
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
gfx_clear_grey(&gfx_ctxt, 0x1B);
|
||||||
ini_free(&ini_sections);
|
ini_free(&ini_sections);
|
||||||
|
if (h_cfg.autoboot_list)
|
||||||
|
ini_free(&ini_list_sections);
|
||||||
ini_free_section(cfg_sec);
|
ini_free_section(cfg_sec);
|
||||||
|
|
||||||
sd_unmount();
|
sd_unmount();
|
||||||
|
@ -2581,7 +2731,7 @@ menu_t menu_tools = {
|
||||||
};
|
};
|
||||||
|
|
||||||
ment_t ment_top[] = {
|
ment_t ment_top[] = {
|
||||||
MDEF_HANDLER("Launch firmware", launch_firmware),
|
MDEF_HANDLER("Launch", launch_firmware),
|
||||||
MDEF_MENU("Launch options", &menu_options),
|
MDEF_MENU("Launch options", &menu_options),
|
||||||
MDEF_CAPTION("---------------", 0xFF444444),
|
MDEF_CAPTION("---------------", 0xFF444444),
|
||||||
MDEF_MENU("Tools", &menu_tools),
|
MDEF_MENU("Tools", &menu_tools),
|
||||||
|
|
74
bootloader/utils/dirlist.c
Normal file
74
bootloader/utils/dirlist.c
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 CTCaer
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "../libs/fatfs/ff.h"
|
||||||
|
#include "../mem/heap.h"
|
||||||
|
#include "../utils/types.h"
|
||||||
|
|
||||||
|
char *dirlist(char *directory)
|
||||||
|
{
|
||||||
|
u8 max_entries = 61;
|
||||||
|
|
||||||
|
int res = 0;
|
||||||
|
u32 i = 0, j = 0, k = 0;
|
||||||
|
DIR dir;
|
||||||
|
static FILINFO fno;
|
||||||
|
|
||||||
|
char *dir_entries = (char *)calloc(max_entries, 256);
|
||||||
|
char *temp = (char *)calloc(1, 256);
|
||||||
|
|
||||||
|
if (!f_opendir(&dir, directory))
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
res = f_readdir(&dir, &fno);
|
||||||
|
if (res || !fno.fname[0])
|
||||||
|
break;
|
||||||
|
if (!(fno.fattrib & AM_DIR))
|
||||||
|
{
|
||||||
|
memcpy(dir_entries + (k * 256), fno.fname, strlen(fno.fname) + 1);
|
||||||
|
k++;
|
||||||
|
if (k > (max_entries - 1))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
f_closedir(&dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < k - 1 ; i++)
|
||||||
|
{
|
||||||
|
for (j = i + 1; j < k; j++)
|
||||||
|
{
|
||||||
|
if (strcmp(&dir_entries[i * 256], &dir_entries[j * 256]) > 0)
|
||||||
|
{
|
||||||
|
memcpy(temp, &dir_entries[i * 256], strlen(&dir_entries[i * 256]) + 1);
|
||||||
|
memcpy(&dir_entries[i * 256], &dir_entries[j * 256], strlen(&dir_entries[j * 256]) + 1);
|
||||||
|
memcpy(&dir_entries[j * 256], temp, strlen(temp) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(temp);
|
||||||
|
|
||||||
|
return dir_entries;
|
||||||
|
}
|
19
bootloader/utils/dirlist.h
Normal file
19
bootloader/utils/dirlist.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 CTCaer
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms and conditions of the GNU General Public License,
|
||||||
|
* version 2, as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../utils/types.h"
|
||||||
|
|
||||||
|
char *dirlist(char *directory);
|
Loading…
Reference in a new issue