diff --git a/boot/Makefile b/boot/Makefile new file mode 100644 index 0000000..885cfa3 --- /dev/null +++ b/boot/Makefile @@ -0,0 +1,140 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") +endif + +include $(DEVKITPPC)/wii_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := boot +BUILD := build +SOURCES := source +DATA := data +INCLUDES := + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -logc + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +DOLFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.dol))) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) \ + $(addsuffix .o,$(DOLFILES)) \ + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +run: + wiiload $(TARGET).dol + + +#--------------------------------------------------------------------------------- +else + +DEPENDS := $(OFILES:.o=.d) + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .jpg extension +#--------------------------------------------------------------------------------- +%.dol.o : %.dol + @echo $(notdir $<) + @bin2s -a 32 $< | $(AS) -o $(@) + +%.jpg.o : %.jpg + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- diff --git a/boot/source/main.c b/boot/source/main.c new file mode 100644 index 0000000..c29175f --- /dev/null +++ b/boot/source/main.c @@ -0,0 +1,77 @@ + +#include +#include +#include +#include + +extern void __exception_closeall(); +typedef void (*entrypoint) (void); + +static u8 *buffer = (u8 *) 0x92000000; + +extern u8 hbf_dol[]; +extern u32 hbf_dol_size; + +typedef struct _dolheader { + u32 text_pos[7]; + u32 data_pos[11]; + u32 text_start[7]; + u32 data_start[11]; + u32 text_size[7]; + u32 data_size[11]; + u32 bss_start; + u32 bss_size; + u32 entry_point; +} dolheader; + +u32 load_dol_image(void *dolstart) +{ + u32 i; + dolheader *dolfile; + + if (dolstart) + { + dolfile = (dolheader *) dolstart; + for (i = 0; i < 7; i++) + { + if ((!dolfile->text_size[i]) || (dolfile->text_start[i] < 0x100)) + continue; + + memmove((void *) dolfile->text_start[i], dolstart + + dolfile->text_pos[i], dolfile->text_size[i]); + + DCFlushRange ((void *) dolfile->text_start[i], dolfile->text_size[i]); + ICInvalidateRange((void *) dolfile->text_start[i], dolfile->text_size[i]); + } + + for (i = 0; i < 11; i++) + { + if ((!dolfile->data_size[i]) || (dolfile->data_start[i] < 0x100)) + continue; + + memmove((void *) dolfile->data_start[i], dolstart + + dolfile->data_pos[i], dolfile->data_size[i]); + + DCFlushRange((void *) dolfile->data_start[i], + dolfile->data_size[i]); + } + return dolfile->entry_point; + } + return 0; +} + +int main(int argc, char **argv) { + memcpy(buffer, (void *) hbf_dol, hbf_dol_size); + + u32 exeEntryPointAddress = load_dol_image(buffer); + entrypoint exeEntryPoint = (entrypoint) exeEntryPointAddress; + u32 level; + SYS_ResetSystem(SYS_SHUTDOWN, 0, 0); + _CPU_ISR_Disable(level); + __exception_closeall(); + exeEntryPoint(); + _CPU_ISR_Restore(level); + + exit(0); +} +