Skip to content

Commit

Permalink
- Add Wii Swiss Booter.
Browse files Browse the repository at this point in the history
  • Loading branch information
Extrems committed Nov 28, 2024
1 parent 2e478d4 commit 3c18906
Show file tree
Hide file tree
Showing 5 changed files with 361 additions and 3 deletions.
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ else
PACMAN = pacman
endif

BUILT_PATCHES = patches
GECKOSERVER = pc/usbgecko
WIIBOOTER = wii/booter

#------------------------------------------------------------------
.NOTPARALLEL:

# Ready to go .7z file with every type of DOL we can think of
all: clean compile-patches compile compile-packer build recovery-iso build-AR build-gci build-ipl build-geckoserver package
all: clean compile-patches compile compile-packer build recovery-iso build-AR build-gci build-ipl build-wii build-geckoserver package

# For dev use only, avoid the unnecessary fluff
dev: clean compile-patches compile
Expand Down Expand Up @@ -123,6 +123,7 @@ package: # create distribution package
@mv $(DIST)/MemoryCard $(SVN_REVISION)
@mv $(DIST)/PicoBoot $(SVN_REVISION)
@mv $(DIST)/USBGeckoRemoteServer $(SVN_REVISION)
@mv $(DIST)/Wii $(SVN_REVISION)
@mv $(DIST)/WiikeyFusion $(SVN_REVISION)
@mv $(DIST)/WODE $(SVN_REVISION)
@find ./$(SVN_REVISION) -type f -print0 | xargs -0 sha256sum > $(SVN_REVISION).sha256
Expand Down Expand Up @@ -166,3 +167,13 @@ build-ipl:
@mkdir $(DIST)/PicoBoot
@$(DOL2IPL) $(DIST)/Apploader/swiss/patches/apploader.img $(PACKER)/reboot.dol *$(SVN_REVISION).dol
@$(DOL2IPL) $(DIST)/PicoBoot/$(SVN_REVISION).uf2 $(PACKER)/reboot.dol

#------------------------------------------------------------------

build-wii:
@cd $(WIIBOOTER) && $(MAKE)
@$(DOL2IPL) $(WIIBOOTER)/boot.dol $(PACKER)/reboot.dol
@mkdir $(DIST)/Wii
@mkdir $(DIST)/Wii/apps
@mkdir $(DIST)/Wii/apps/swiss-gc
@cp $(WIIBOOTER)/boot.dol $(DIST)/Wii/apps/swiss-gc/
49 changes: 48 additions & 1 deletion buildtools/dol2ipl.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,40 @@ def flatten_dol(data):
# Entry point, load address, memory image
return entry, dol_min, img

def append_dol(data, trailer, base_address):
header = struct.unpack(">64I", data[:256])
offsets = header[:18]
addresses = header[18:36]
sizes = header[36:54]

for section, (offset, address, size) in enumerate(zip(offsets[7:], addresses[7:], sizes[7:]), 7):
if address == base_address and offset + size == len(data):
data = data[:offset]
offset = 0
address = 0
size = 0

if offset == 0:
offset = len(data)
address = base_address
size = len(trailer)
data = data + trailer
break

offsets = offsets[:section] + (offset,) + offsets[section + 1:]
addresses = addresses[:section] + (address,) + addresses[section + 1:]
sizes = sizes[:section] + (size,) + sizes[section + 1:]

header = struct.pack(
"> 64I",
*offsets,
*addresses,
*sizes,
*header[54:64]
)

return header + data[256:]

def pack_uf2(data, base_address):
ret = bytearray()

Expand Down Expand Up @@ -140,7 +174,20 @@ def main():
print("Unknown input format")
return -1

if output.endswith(".img"):
if output.endswith(".dol"):
with open(output, "rb") as f:
img = bytearray(f.read())

header_size = 32
header = struct.pack(
"> 32s",
b"gchomebrew dol"
)
assert len(header) == header_size

out = append_dol(img, header + exe, 0x80800000 - header_size)

elif output.endswith(".img"):
if entry != 0x81300000 or load != 0x01300000:
print("Invalid entry point and base address (must be 0x81300000)")
return -1
Expand Down
5 changes: 5 additions & 0 deletions cube/packer/source/crt0.S
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ startup:
ori r0, r0, 0x000C
mtear r0

li r3, 0x30F8
lis r0, 0xdead
ori r0, r0, 0xbeef
ecowx r0, 0, r3

lis r3, 0x0C00
li r4, 0x3000
li r0, 1
Expand Down
138 changes: 138 additions & 0 deletions wii/booter/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif

include $(DEVKITPRO)/libogc2/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)/*.*)))

#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
export LD := $(CC)
else
export LD := $(CXX)
endif

export OFILES_BIN := $(addsuffix .o,$(BINFILES))
export OFILES_SOURCES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(sFILES:.s=.o) $(SFILES:.S=.o)
export OFILES := $(OFILES_BIN) $(OFILES_SOURCES)

export HFILES := $(addsuffix .h,$(subst .,_,$(BINFILES)))

#---------------------------------------------------------------------------------
# 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 := -L$(LIBOGC_LIB) $(foreach dir,$(LIBDIRS),-L$(dir)/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)

$(OFILES_SOURCES) : $(HFILES)

#---------------------------------------------------------------------------------
# This rule links in binary data with the .jpg extension
#---------------------------------------------------------------------------------
%.jpg.o %_jpg.h : %.jpg
#---------------------------------------------------------------------------------
@echo $(notdir $<)
$(bin2o)

-include $(DEPENDS)

#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
Loading

1 comment on commit 3c18906

@pyorot
Copy link

@pyorot pyorot commented on 3c18906 Nov 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

about wii/booter/source/main.c firstly:

  1. i marked a typo above in line 58
  2. is this settings init needed because the wii settings can’t be accessed later in gamecube mode (during swiss init)? swiss seemed to me to boot fine before without enforcing system settings like this so i wonder why you do it
  3. do wii settings get reduced to gamecube ones? e.g. surround -> stereo, japanese-> english
  4. what’s the difference between configuring video with initVideo (VIDEO_*) vs initSram (SYS_*)? is the latter only needed for gamecube mode?
  5. is 2 Vsyncs the cleanest sync strategy? i’ve seen many variations of that code in different projects
  6. should some or all of this just be added to libogc as initPreferredSettings or such? (idk if libogc2 is required for this tho i notice one of the externs is only in that one)

Please sign in to comment.