support for file based and sd partition based emusd
This commit is contained in:
@@ -41,7 +41,7 @@ OBJS += $(addprefix $(BUILDDIR)/$(TARGET)/, \
|
||||
bm92t36.o bq24193.o max17050.o max7762x.o max77620-rtc.o regulator_5v.o \
|
||||
touch.o joycon.o tmp451.o fan.o \
|
||||
usbd.o xusbd.o usb_descriptors.o usb_gadget_ums.o usb_gadget_hid.o \
|
||||
hw_init.o boot_storage.o sfd.o mbr_gpt.o emummc_file_based.o \
|
||||
hw_init.o boot_storage.o sfd.o mbr_gpt.o emummc_file_based.o file_based_storage.o \
|
||||
)
|
||||
|
||||
# Utilities.
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <utils/list.h>
|
||||
#include <utils/ini.h>
|
||||
#include <string.h>
|
||||
#include "gfx_utils.h"
|
||||
#include <stdlib.h>
|
||||
#include <utils/sprintf.h>
|
||||
|
||||
void load_emusd_cfg(emusd_cfg_t *emu_info){
|
||||
memset(emu_info, 0, sizeof(emusd_cfg_t));
|
||||
@@ -29,8 +32,10 @@ void load_emusd_cfg(emusd_cfg_t *emu_info){
|
||||
emu_info->enabled = atoi(kv->val);
|
||||
else if(!strcmp("sector", kv->key))
|
||||
emu_info->sector = strtol(kv->val, NULL, 16);
|
||||
/*else (!strcmp("id", kv->key))
|
||||
emu_info->id = strtol(kv->val, NULL, 16);*/
|
||||
else if(!strcmp("path", kv->key)){
|
||||
emu_info->path =(char*)malloc(strlen(kv->val)+1);
|
||||
strcpy(emu_info->path, kv->val);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -40,7 +45,7 @@ void load_emusd_cfg(emusd_cfg_t *emu_info){
|
||||
ini_free(&ini_sections);
|
||||
}
|
||||
|
||||
void save_emusd_cfg(u32 part_idx, u32 sector_start){
|
||||
void save_emusd_cfg(u32 part_idx, u32 sector_start, const char *path, u8 drive){
|
||||
boot_storage_mount();
|
||||
|
||||
char lbuf[16];
|
||||
@@ -53,7 +58,9 @@ void save_emusd_cfg(u32 part_idx, u32 sector_start){
|
||||
|
||||
// Add config entry.
|
||||
f_puts("[emusd]\nenabled=", &fp);
|
||||
if(sector_start){
|
||||
if((sector_start || path) && drive == DRIVE_SD) {
|
||||
f_puts("1", &fp);
|
||||
} else if((sector_start || path) && drive == DRIVE_EMMC){
|
||||
f_puts("4", &fp);
|
||||
}else{
|
||||
f_puts("0", &fp);
|
||||
@@ -66,13 +73,142 @@ void save_emusd_cfg(u32 part_idx, u32 sector_start){
|
||||
itoa(sector_start, lbuf, 16);
|
||||
f_puts(lbuf, &fp);
|
||||
}
|
||||
f_puts("\n", &fp);
|
||||
|
||||
if(path){
|
||||
f_puts("\npath=", &fp);
|
||||
f_puts(path, &fp);
|
||||
}
|
||||
|
||||
f_puts("\n", &fp);
|
||||
f_close(&fp);
|
||||
}
|
||||
|
||||
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name){
|
||||
sfd_init(&emmc_storage, sector_start, sector_size);
|
||||
static void update_base_path(char *path, int idx, int path_len) {
|
||||
if(idx < 10){
|
||||
path[path_len] = '0';
|
||||
itoa(idx, path + path_len + 1, 10);
|
||||
}else{
|
||||
itoa(idx, path + path_len, 10);
|
||||
}
|
||||
}
|
||||
|
||||
int create_emusd_file(u32 size_sct, u8 drive) {
|
||||
static const u32 file_max_scts = 0xfe000000 / 0x200;
|
||||
|
||||
char path[0x80];
|
||||
if (drive == DRIVE_SD){
|
||||
strcpy(path, "sd:emuSD/SD");
|
||||
f_mkdir("sd:emuSD");
|
||||
}else {
|
||||
strcpy(path, "emmc:emuSD/EMMC");
|
||||
f_mkdir("emmc:emuSD");
|
||||
}
|
||||
int path_len = strlen(path);
|
||||
|
||||
f_mkdir("emuSD");
|
||||
|
||||
for(int j = 0; j < 100; j++){
|
||||
update_base_path(path, j, path_len);
|
||||
if(f_stat(path, NULL) == FR_NO_FILE){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
f_mkdir(path);
|
||||
f_mkdir(path + (drive == DRIVE_SD ? 3 : 5));
|
||||
|
||||
u32 base_path_len = strlen(path);
|
||||
|
||||
strcat(path, "/SD");
|
||||
f_mkdir(path);
|
||||
|
||||
strcat(path, "/");
|
||||
path_len = strlen(path);
|
||||
|
||||
// allocate files for emusd
|
||||
u32 sct_left = size_sct;
|
||||
u32 idx = 0;
|
||||
|
||||
gfx_printf("sct left 0x%x\n", sct_left);
|
||||
while(sct_left) {
|
||||
update_base_path(path, idx, path_len);
|
||||
|
||||
u32 scts = MIN(sct_left, file_max_scts);
|
||||
|
||||
FIL f;
|
||||
int res = f_open(&f, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
if(res != FR_OK) {
|
||||
gfx_printf("open fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
FSIZE_t seek_bytes = (FSIZE_t)scts << 9;
|
||||
res = f_lseek(&f, seek_bytes);
|
||||
f_close(&f);
|
||||
|
||||
if(res != FR_OK){
|
||||
f_unlink(path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sct_left -= scts;
|
||||
idx++;
|
||||
}
|
||||
|
||||
|
||||
path[path_len] = '\0';
|
||||
|
||||
sfd_file_based_init(path);
|
||||
|
||||
u8 *buf = malloc(SZ_4M);
|
||||
u32 cluster_size = 65536;
|
||||
|
||||
int res = f_mkfs("sfd:", FM_FAT32, cluster_size, buf, SZ_4M);
|
||||
|
||||
while (res != FR_OK && cluster_size > 4096){
|
||||
cluster_size /= 2;
|
||||
res = f_mkfs("sfd:", FM_FAT32, cluster_size, buf, SZ_4M);
|
||||
}
|
||||
|
||||
if(res == FR_OK){
|
||||
FATFS fs;
|
||||
res = f_mount(&fs, "sfd:", 1);
|
||||
|
||||
if(res == FR_OK){
|
||||
gfx_printf("mount fail %d\n", res);
|
||||
char label[0x30];
|
||||
strcpy(label, "sfd:emusd");
|
||||
res = f_setlabel(label);
|
||||
}
|
||||
|
||||
f_mount(NULL, "sfd:", 0);
|
||||
}
|
||||
|
||||
sfd_end();
|
||||
|
||||
free(buf);
|
||||
|
||||
if(res != FR_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
path[base_path_len] = '\0';
|
||||
s_printf(path + base_path_len, drive == DRIVE_SD ? "/file_based" : "/file_emmc_based");
|
||||
FIL f;
|
||||
res = f_open(&f, path + (drive == DRIVE_SD ? 3 : 5), FA_WRITE | FA_CREATE_ALWAYS);
|
||||
f_close(&f);
|
||||
gfx_printf("%s %d\n", path, res);
|
||||
|
||||
path[base_path_len] = '\0';
|
||||
save_emusd_cfg(0, 0, path + (drive == DRIVE_SD ? 3 : 5), drive);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name, u8 drive){
|
||||
sdmmc_storage_t *storage = drive == DRIVE_SD ? &sd_storage : &emmc_storage;
|
||||
|
||||
sfd_init(storage, sector_start, sector_size);
|
||||
|
||||
u8 *buf = malloc(SZ_4M);
|
||||
FIL f;
|
||||
@@ -109,7 +245,7 @@ int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size
|
||||
mbr.partitions[0].size_sct = sector_size;
|
||||
mbr.partitions[0].type = 0x0c;
|
||||
|
||||
mkfs_error = sdmmc_storage_write(&emmc_storage, sector_mbr, 1, &mbr) ? FR_OK : FR_DISK_ERR;
|
||||
mkfs_error = sdmmc_storage_write(storage, sector_mbr, 1, &mbr) ? FR_OK : FR_DISK_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,5 +255,22 @@ int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size
|
||||
|
||||
sfd_end();
|
||||
|
||||
return mkfs_error;
|
||||
if(mkfs_error != FR_OK){
|
||||
return mkfs_error;
|
||||
}
|
||||
|
||||
char path[0x80];
|
||||
strcpy(path, "emuSD");
|
||||
f_mkdir(path);
|
||||
s_printf(path + strlen(path), "/RAW_%s%d", drive == DRIVE_SD ? "SD" : "EMMC", part_idx);
|
||||
f_mkdir(path);
|
||||
strcat(path, "/raw_emmc_based");
|
||||
|
||||
f_open(&f, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
f_write(&f, §or_mbr, 4, NULL);
|
||||
f_close(&f);
|
||||
|
||||
save_emusd_cfg(part_idx, sector_mbr, NULL, drive);
|
||||
|
||||
return FR_OK;
|
||||
}
|
||||
@@ -7,10 +7,11 @@ typedef struct _emusd_cfg_t{
|
||||
// 0: disabled, 1: enabled
|
||||
int enabled;
|
||||
u32 sector;
|
||||
char *path;
|
||||
} emusd_cfg_t;
|
||||
|
||||
void load_emusd_cfg(emusd_cfg_t *emu_info);
|
||||
void save_emusd_cfg(u32 part_idx, u32 sector_start);
|
||||
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name);
|
||||
|
||||
void save_emusd_cfg(u32 part_idx, u32 sector_start, const char *path, u8 drive);
|
||||
int create_emusd(int part_idx, u32 sector_mbr, u32 sector_start, u32 sector_size, const char *name, u8 drive);
|
||||
int create_emusd_file(u32 size_sct, u8 drive);
|
||||
#endif
|
||||
|
||||
@@ -864,7 +864,7 @@ static lv_res_t _create_mbox_emummc_create(lv_obj_t *btn)
|
||||
"Welcome to #C7EA46 emuMMC# creation tool!\n\n"
|
||||
"Please choose what type of emuMMC you want to create.\n"
|
||||
"#FF8000 File based# is saved as files in\nthe SD or eMMC FAT partition.\n"
|
||||
"#FF8000 Partition based# is saved as raw image in a\navailable SD or eMMC partition.");
|
||||
"#FF8000 Partition based# is saved as raw image in an\navailable SD or eMMC partition.");
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, _create_emummc_select_type_action);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@
|
||||
#include <storage/boot_storage.h>
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/emummc_file_based.h>
|
||||
#include <storage/file_based_storage.h>
|
||||
#include <storage/mbr_gpt.h>
|
||||
#include <storage/sd.h>
|
||||
#include <storage/sdmmc.h>
|
||||
@@ -380,6 +381,12 @@ static lv_res_t _create_mbox_ums_error(int error)
|
||||
case 8:
|
||||
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize file based emuMMC!#");
|
||||
break;
|
||||
case 9:
|
||||
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 Failed to initialize file based emuSD!#");
|
||||
break;
|
||||
case 10:
|
||||
lv_mbox_set_text(mbox, "#FF8000 USB Mass Storage#\n\n#FFFF00 No emuSD found active!#");
|
||||
break;
|
||||
}
|
||||
|
||||
lv_mbox_add_btns(mbox, mbox_btn_map, mbox_action);
|
||||
@@ -558,42 +565,103 @@ static lv_res_t _action_ums_emusd(lv_obj_t * btn){
|
||||
}
|
||||
|
||||
usb_ctxt_t usbs;
|
||||
sdmmc_storage_t *storage;
|
||||
emusd_cfg_t emu_info;
|
||||
|
||||
bool file_based = false;
|
||||
int error = !boot_storage_mount();
|
||||
char path[0x80];
|
||||
|
||||
if(!error){
|
||||
load_emusd_cfg(&emu_info);
|
||||
if(emu_info.enabled){
|
||||
if(!emmc_initialize(false)){
|
||||
error = 3;
|
||||
}else{
|
||||
mbr_t mbr = {0};
|
||||
|
||||
if(sdmmc_storage_read(&emmc_storage, emu_info.sector, 1, &mbr)){
|
||||
error = 0;
|
||||
usbs.offset = emu_info.sector;
|
||||
usbs.sectors = mbr.partitions[0].size_sct;
|
||||
usbs.type = MMC_EMMC;
|
||||
usbs.partition = EMMC_GPP + 1;
|
||||
usbs.ro = false;
|
||||
usbs.system_maintenance = &manual_system_maintenance;
|
||||
usbs.set_text = &usb_gadget_set_text;
|
||||
}else{
|
||||
error = 0;
|
||||
if(emu_info.enabled == 4 && emu_info.sector){
|
||||
if(!emmc_initialize(false)){
|
||||
error = 3;
|
||||
}
|
||||
storage = &emmc_storage;
|
||||
}else if(emu_info.enabled == 1 && emu_info.sector){
|
||||
if(!sd_initialize(false)){
|
||||
error = 4;
|
||||
}
|
||||
storage = &sd_storage;
|
||||
}else if((emu_info.enabled == 1 || emu_info.enabled == 4) && !emu_info.sector){
|
||||
if(emu_info.enabled == 1){
|
||||
if(!sd_mount()){
|
||||
error = 4;
|
||||
}
|
||||
}else{
|
||||
if(!emmc_mount()){
|
||||
error = 3;
|
||||
}
|
||||
}
|
||||
if(error == 0){
|
||||
file_based = true;
|
||||
if(emu_info.enabled ==1){
|
||||
strcpy(path, "sd:");
|
||||
}else{
|
||||
strcpy(path, "emmc:");
|
||||
}
|
||||
strcat(path, emu_info.path);
|
||||
strcat(path, "/SD/");
|
||||
if(!file_based_storage_init(path)){
|
||||
error = 9;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
error = 10;
|
||||
}
|
||||
}else{
|
||||
error = 7;
|
||||
error = 10;
|
||||
}
|
||||
|
||||
if(error == 0 && emu_info.enabled){
|
||||
error = 6;
|
||||
if(file_based){
|
||||
usbs.offset = 0;
|
||||
}else{
|
||||
usbs.offset = emu_info.sector;
|
||||
}
|
||||
|
||||
if(file_based){
|
||||
error = 9;
|
||||
u32 sz = file_based_storage_get_total_size();
|
||||
if(sz){
|
||||
error = 0;
|
||||
}
|
||||
usbs.sectors = sz;
|
||||
}else{
|
||||
error = 3;
|
||||
mbr_t mbr;
|
||||
if(sdmmc_storage_read(storage, emu_info.sector, 1, &mbr)){
|
||||
error = 0;
|
||||
usbs.sectors = mbr.partitions[0].size_sct + mbr.partitions[0].start_sct;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(emu_info.path){
|
||||
free(emu_info.path);
|
||||
}
|
||||
|
||||
if(error){
|
||||
_create_mbox_ums_error(error);
|
||||
}else{
|
||||
if(file_based){
|
||||
usbs.type = MMC_FILE_BASED;
|
||||
}else{
|
||||
usbs.type = emu_info.enabled == 1 ? MMC_SD : MMC_EMMC;
|
||||
}
|
||||
usbs.partition = EMMC_GPP + 1;
|
||||
usbs.ro = false;
|
||||
usbs.system_maintenance = &manual_system_maintenance;
|
||||
usbs.set_text = &usb_gadget_set_text;
|
||||
_create_mbox_ums(&usbs, NYX_UMS_EMUSD);
|
||||
}
|
||||
|
||||
file_based_storage_end();
|
||||
boot_storage_unmount();
|
||||
|
||||
return LV_RES_OK;
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#include "sfd.h"
|
||||
#include <storage/emmc.h>
|
||||
#include <storage/sdmmc.h>
|
||||
#include <storage/file_based_storage.h>
|
||||
#include <libs/fatfs/diskio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static bool file_based;
|
||||
static sdmmc_storage_t *_storage;
|
||||
static u32 _offset;
|
||||
static u32 _size;
|
||||
@@ -14,7 +18,11 @@ static void ensure_partition(){
|
||||
}
|
||||
|
||||
sdmmc_storage_t *sfd_get_storage(){
|
||||
return _storage;
|
||||
if(file_based){
|
||||
return NULL;
|
||||
}else{
|
||||
return _storage;
|
||||
}
|
||||
}
|
||||
|
||||
int sfd_read(u32 sector, u32 count, void *buff){
|
||||
@@ -22,8 +30,13 @@ int sfd_read(u32 sector, u32 count, void *buff){
|
||||
if(sector + count > _size){
|
||||
return 0;
|
||||
}
|
||||
ensure_partition();
|
||||
res = sdmmc_storage_read(_storage, sector + _offset, count, buff);
|
||||
|
||||
if(file_based){
|
||||
res = file_based_storage_read(sector, count, buff);
|
||||
}else{
|
||||
ensure_partition();
|
||||
res = sdmmc_storage_read(_storage, sector + _offset, count, buff);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -32,8 +45,14 @@ int sfd_write(u32 sector, u32 count, void *buff){
|
||||
if(sector + count > _size){
|
||||
return 0;
|
||||
}
|
||||
ensure_partition();
|
||||
res = sdmmc_storage_write(_storage, sector + _offset, count, buff);
|
||||
|
||||
if(file_based){
|
||||
res = file_based_storage_write(sector, count, buff);
|
||||
}else{
|
||||
ensure_partition();
|
||||
res = sdmmc_storage_write(_storage, sector + _offset, count, buff);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -45,10 +64,23 @@ bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size){
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sfd_file_based_init(const char *base_path) {
|
||||
file_based = true;
|
||||
if(!file_based_storage_init(base_path)){
|
||||
gfx_printf("file based init fail\n");
|
||||
return 0;
|
||||
}
|
||||
_size = file_based_storage_get_total_size();
|
||||
disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &_size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void sfd_end(){
|
||||
_storage = NULL;
|
||||
_offset = 0;
|
||||
_size = 0;
|
||||
u32 size = 0;
|
||||
file_based = false;
|
||||
disk_set_info(DRIVE_SFD, SET_SECTOR_COUNT, &size);
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
int sfd_read(u32 sector, u32 count, void *buff);
|
||||
int sfd_write(u32 sector, u32 count, void *buff);
|
||||
|
||||
bool sfd_file_based_init(const char *base_path);
|
||||
bool sfd_init(sdmmc_storage_t *storage, u32 offset, u32 size);
|
||||
void sfd_end();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user