Dump OTP and SEEPROM

This commit is contained in:
koolkdev 2017-03-27 22:59:03 +03:00
parent dad9a3fbbd
commit 1d7fb42aa3
10 changed files with 185 additions and 17 deletions

View File

@ -59,6 +59,7 @@ $(PROJECTNAME)_syms.h:
@echo "#define $(PROJECTNAME)_SYMS_H" >> $@
@$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep 'g F .text' | grep -v '.hidden' | awk '{print "#define " $$6 " 0x" $$1}' >> $@
@$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep -e 'g .text' -e '_bss_' | awk '{print "#define " $$5 " 0x" $$1}' >> $@
@$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep -e 'g O .dumper_config' | awk '{print "#define " $$6 " 0x" $$1}' >> $@
@echo "#endif" >> $@
clean:

View File

@ -8,6 +8,9 @@ SECTIONS
*(.rodata*);
}
_text_end = .;
.dumper_config : {
*(.dumper_config*);
}
.bss (0x10835000 + 0x1406554) : {
_bss_start = .;

View File

@ -8,6 +8,9 @@
#include "text.h"
#include "hardware_registers.h"
#include "svc.h"
#include "fs_config.h"
fs_config dumper_config __attribute__((section(".dumper_config")));
#define IO_BUFFER_SIZE 0x40000
#define IO_BUFFER_SPARE_SIZE (IO_BUFFER_SIZE+0x2000)
@ -233,15 +236,10 @@ void dump_nand_complete()
_printf(20, offset_y, "Init SD card.... Success!");
offset_y += 10;
int * dumpSlc = (int *)(0x107f8200 - 4);
int * dumpSlccmpt = (int *)(0x107f8200 - 8);
int * dumpMlc = (int *)(0x107f8200 - 12);
//wait_format_confirmation();
u32 mlc_sector_count = 0;
if (*dumpMlc) {
if (dumper_config.dump_mlc) {
mlc_init();
FS_SLEEP(1000);
@ -268,17 +266,53 @@ void dump_nand_complete()
svcShutdown(SHUTDOWN_TYPE_REBOOT);
}*/
if (*dumpSlc) {
if (dumper_config.dump_otp) {
_printf(20, offset_y, "Writing otp...");
FL_FILE *file = fl_fopen("/otp.bin", "w");
if (!file) {
_printf(20, offset_y+10, "Failed to open /otp.bin for writing!");
goto error;
}
// It doesn't work if we try write directly this buffer, does it try to access too much?
memcpy(io_buffer, dumper_config.otp_buffer, sizeof(dumper_config.otp_buffer));
if (fl_fwrite(io_buffer, 1, sizeof(dumper_config.otp_buffer), file) != sizeof(dumper_config.otp_buffer)) {
fl_fclose(file);
_printf(20, offset_y+10, "Failed to write otp to file!");
goto error;
}
fl_fclose(file);
_printf(20, offset_y, "Writing otp... Success!");
offset_y += 10;
}
if (dumper_config.dump_seeprom) {
_printf(20, offset_y, "Writing seeprom...");
FL_FILE *file = fl_fopen("/seeprom.bin", "w");
if (!file) {
_printf(20, offset_y+10, "Failed to open /seeprom.bin for writing!");
goto error;
}
// It doesn't work if we try write directly this buffer, does it try to access too much?
memcpy(io_buffer, dumper_config.seeprom_buffer, sizeof(dumper_config.seeprom_buffer));
if (fl_fwrite(io_buffer, 1, sizeof(dumper_config.seeprom_buffer), file) != sizeof(dumper_config.seeprom_buffer)) {
fl_fclose(file);
_printf(20, offset_y+10, "Failed to write seeprom to file!");
goto error;
}
fl_fclose(file);
_printf(20, offset_y, "Writing seeprom... Success!");
offset_y += 10;
}
if (dumper_config.dump_slc) {
if (slc_dump(FS_SLC_PHYS_DEV_STRUCT, "slc ", "/slc.bin", offset_y))
goto error;
offset_y += 10;
}
if (*dumpSlccmpt) {
if (dumper_config.dump_slccmpt) {
if (slc_dump(FS_SLCCMPT_PHYS_DEV_STRUCT, "slccmpt", "/slccmpt.bin", offset_y))
goto error;
offset_y += 10;
}
if (*dumpMlc) {
if (dumper_config.dump_mlc) {
if (mlc_dump(mlc_sector_count, offset_y))
goto error;
offset_y += 10;

14
ios_fs/source/fs_config.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef _FS_CONFIG_H
#define _FS_CONFIG_H
typedef struct {
int dump_slc;
int dump_slccmpt;
int dump_mlc;
int dump_otp;
int dump_seeprom;
char otp_buffer[0x400];
char seeprom_buffer[0x200];
} fs_config;
#endif

View File

@ -25,7 +25,9 @@
#include "elf_patcher.h"
#include "ios_fs_patches.h"
#include "config.h"
#include "utils.h"
#include "../../ios_fs/ios_fs_syms.h"
#include "../../ios_fs/source/fs_config.h"
#define FS_PHYS_DIFF 0
@ -51,6 +53,9 @@
extern const patch_table_t fs_patches_table[];
extern const patch_table_t fs_patches_table_end[];
extern unsigned char otp_buffer[0x400];
extern unsigned char seeprom_buffer[0x400];
u32 fs_get_phys_code_base(void)
{
return _text_start + FS_PHYS_DIFF;
@ -58,6 +63,8 @@ u32 fs_get_phys_code_base(void)
void fs_run_patches(u32 ios_elf_start)
{
fs_config config;
// write wupserver code and bss
section_write(ios_elf_start, _text_start, (void*)fs_get_phys_code_base(), _text_end - _text_start);
section_write_bss(ios_elf_start, _bss_start, _bss_end - _bss_start);
@ -78,9 +85,16 @@ void fs_run_patches(u32 ios_elf_start)
section_write_word(ios_elf_start, FS_SLC_ECC_CHECK, ARM_B(FS_SLC_ECC_CHECK, eccCheck_patch));
section_write_word(ios_elf_start, (_text_start - 4), cfw_config.dumpSlc);
section_write_word(ios_elf_start, (_text_start - 8), cfw_config.dumpSlccmpt);
section_write_word(ios_elf_start, (_text_start - 12), cfw_config.dumpMlc);
config.dump_slc = cfw_config.dumpSlc;
config.dump_slccmpt = cfw_config.dumpSlccmpt;
config.dump_mlc = cfw_config.dumpMlc;
config.dump_otp = cfw_config.dumpOtp;
config.dump_seeprom = cfw_config.dumpSeeprom;
if (cfw_config.dumpOtp)
kernel_memcpy(config.otp_buffer, otp_buffer, sizeof(config.otp_buffer));
if (cfw_config.dumpSeeprom)
kernel_memcpy(config.seeprom_buffer, seeprom_buffer, sizeof(config.seeprom_buffer));
section_write(ios_elf_start, dumper_config, &config, sizeof(config));
//section_write_word(ios_elf_start, FS_USB_READ, ARM_B(FS_USB_READ, usbRead_patch));
//section_write_word(ios_elf_start, FS_USB_WRITE, ARM_B(FS_USB_WRITE, usbWrite_patch));

View File

@ -38,7 +38,7 @@ extern void __KERNEL_CODE_END(void);
extern const patch_table_t kernel_patches_table[];
extern const patch_table_t kernel_patches_table_end[];
static u8 otp_buffer[0x400];
//static u8 otp_buffer[0x400];
static const u32 mcpIoMappings_patch[] =
{
@ -60,7 +60,7 @@ static u32 kernel_syscall_0x81(u32 address)
return *(volatile u32*)address;
}
static int kernel_read_otp_internal(int index, void* out_buf, u32 size)
/*static int kernel_read_otp_internal(int index, void* out_buf, u32 size)
{
kernel_memcpy(out_buf, otp_buffer + (index << 2), size);
return 0;
@ -85,7 +85,7 @@ int kernel_init_otp_buffer(u32 sd_sector, int dumpFound)
FSA_SDWriteRawSectors(otp_buffer, sd_sector, 2);
}
return res;
}
}*/
void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
{

View File

@ -34,6 +34,9 @@
cfw_config_t cfw_config;
unsigned char otp_buffer[0x400];
unsigned char seeprom_buffer[0x400];
typedef struct
{
u32 size;
@ -64,16 +67,105 @@ static const char repairData_usb_root_thread[] = {
0xE5,0x9F,0x0E,0x68,0xEB,0x00,0xB3,0x20,
};
// based on mini implementation by sven peter
#define LT_TIMER 0x0d800010
#define LT_GPIO_OUT 0x0d8000e0
#define LT_GPIO_IN 0x0d8000e8
#define EEPROM_SPI_CS 0x400
#define EEPROM_SPI_SCK 0x800
#define EEPROM_SPI_MOSI 0x1000
#define EEPROM_SPI_MISO 0x2000
#define HW_REG(reg) (*(volatile unsigned int*)(reg))
static inline void _delay(u32 ticks)
{
u32 now = HW_REG(LT_TIMER);
while((HW_REG(LT_TIMER) - now) < ticks);
}
static u32 spi_read(int bit_count)
{
u32 word = 0;
while(bit_count--)
{
word <<= 1;
HW_REG(LT_GPIO_OUT) |= EEPROM_SPI_SCK;
_delay(9);
HW_REG(LT_GPIO_OUT) &= ~EEPROM_SPI_SCK;
_delay(9);
word |= ((HW_REG(LT_GPIO_IN) & EEPROM_SPI_MISO) != 0);
}
return word;
}
static void spi_write(u32 word, int bit_count)
{
while(bit_count--)
{
if(word & (1 << bit_count))
{
HW_REG(LT_GPIO_OUT) |= EEPROM_SPI_MOSI;
}
else
{
HW_REG(LT_GPIO_OUT) &= ~EEPROM_SPI_MOSI;
}
_delay(9);
HW_REG(LT_GPIO_OUT) |= EEPROM_SPI_SCK;
_delay(9);
HW_REG(LT_GPIO_OUT) &= ~EEPROM_SPI_SCK;
_delay(9);
}
}
static int seeprom_read(u16 *dst, int offset, int size)
{
int i;
offset >>= 1;
size >>= 1;
HW_REG(LT_GPIO_OUT) &= ~EEPROM_SPI_SCK;
HW_REG(LT_GPIO_OUT) &= ~EEPROM_SPI_CS;
_delay(9);
for(i = 0; i < size; ++i, ++offset)
{
HW_REG(LT_GPIO_OUT) |= EEPROM_SPI_CS;
spi_write((0x600 | offset), 11);
dst[i] = spi_read(16);
HW_REG(LT_GPIO_OUT) &= ~EEPROM_SPI_CS;
_delay(9);
}
return size;
}
int _main()
{
void(*invalidate_icache)() = (void(*)())0x0812DCF0;
void(*invalidate_dcache)(unsigned int, unsigned int) = (void(*)())0x08120164;
void(*flush_dcache)(unsigned int, unsigned int) = (void(*)())0x08120160;
int (*orig_kernel_read_otp_internal)(int index, void* out_buf, u32 size) = (void*)0x08120248;
flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache
// We don't have the config yet, so read it anyway
orig_kernel_read_otp_internal(0, otp_buffer, 0x400);
flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache
int level = disable_interrupts();
// We don't have the config yet, so read it anyway
seeprom_read(seeprom_buffer, 0, 0x200);
unsigned int control_register = disable_mmu();
/* Save the request handle so we can reply later */

View File

@ -88,6 +88,8 @@ void default_config(cfw_config_t * config)
config->dumpSlc = 1;
config->dumpSlccmpt = 1;
config->dumpMlc = 0;
config->dumpOtp = 1;
config->dumpSeeprom = 1;
}
/*int read_config(cfw_config_t * config)

View File

@ -42,6 +42,8 @@ typedef struct
int dumpSlc;
int dumpSlccmpt;
int dumpMlc;
int dumpOtp;
int dumpSeeprom;
} cfw_config_t;
void default_config(cfw_config_t * config);

View File

@ -36,7 +36,7 @@
#include "dynamic_libs/socket_functions.h"
#include "cfw_config.h"
#define MAX_CONFIG_SETTINGS 3
#define MAX_CONFIG_SETTINGS 5
//#define MAX_CONFIG_SETTINGS_EXPERT 9
//#define MAX_CONFIG_SETTINGS_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3)
@ -163,6 +163,12 @@ int ShowMenu(cfw_config_t * currentConfig)
case 2:
config.dumpMlc = !config.dumpMlc;
break;
case 3:
config.dumpOtp = !config.dumpOtp;
break;
case 4:
config.dumpSeeprom = !config.dumpSeeprom;
break;
/*case 0:
config.viewMode = !config.viewMode;
max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS_EXPERT : MAX_CONFIG_SETTINGS_DEFAULT;