Skip to content

Commit

Permalink
Add hekate loader
Browse files Browse the repository at this point in the history
  • Loading branch information
CTCaer committed Jul 4, 2020
1 parent da0cdf1 commit 1ceb380
Show file tree
Hide file tree
Showing 12 changed files with 1,095 additions and 3 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
.vscode
build/*
output/*
loader/payload_00.h
loader/payload_01.h
tools/bin2c/bin2c
tools/lz/lz77
29 changes: 26 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,23 @@ LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defs

MODULEDIRS := $(wildcard modules/*)
NYXDIR := $(wildcard nyx)
LDRDIR := $(wildcard loader)
TOOLSLZ := $(wildcard tools/lz)
TOOLSB2C := $(wildcard tools/bin2c)
TOOLS := $(TOOLSLZ) $(TOOLSB2C)

################################################################################

.PHONY: all clean $(MODULEDIRS) $(NYXDIR)
.PHONY: all clean $(MODULEDIRS) $(NYXDIR) $(LDRDIR) $(TOOLS)

all: $(TARGET).bin
all: $(TARGET).bin $(LDRDIR)
@printf ICTC49 >> $(OUTPUTDIR)/$(TARGET).bin
@echo "--------------------------------------"
@echo -n "Uncompr size: "
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET)_unc.bin))
@echo $(BIN_SIZE)" Bytes"
@echo "Uncompr Max: 140288 Bytes + 3 KiB BSS"
@if [ ${BIN_SIZE} -gt 140288 ]; then echo "\e[1;33mUncompr size exceeds limit!\e[0m"; fi
@echo -n "Payload size: "
$(eval BIN_SIZE = $(shell wc -c < $(OUTPUTDIR)/$(TARGET).bin))
@echo $(BIN_SIZE)" Bytes"
Expand All @@ -104,7 +113,21 @@ $(MODULEDIRS):
$(NYXDIR):
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)

$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR)
$(LDRDIR): $(TARGET).bin
@$(TOOLSLZ)/lz77 $(OUTPUTDIR)/$(TARGET).bin
mv $(OUTPUTDIR)/$(TARGET).bin $(OUTPUTDIR)/$(TARGET)_unc.bin
@mv $(OUTPUTDIR)/$(TARGET).bin.00.lz payload_00
@mv $(OUTPUTDIR)/$(TARGET).bin.01.lz payload_01
@$(TOOLSB2C)/bin2c payload_00 > $(LDRDIR)/payload_00.h
@$(TOOLSB2C)/bin2c payload_01 > $(LDRDIR)/payload_01.h
@rm payload_00
@rm payload_01
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS) PAYLOAD_NAME=$(TARGET)

$(TOOLS):
@$(MAKE) --no-print-directory -C $@ $(MAKECMDGOALS) -$(MAKEFLAGS)

$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf $(MODULEDIRS) $(NYXDIR) $(TOOLS)
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$@

$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
Expand Down
62 changes: 62 additions & 0 deletions loader/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif

include $(DEVKITARM)/base_rules

################################################################################

LDR_LOAD_ADDR := 0x40007000
IPL_MAGIC := 0x43544349 #"ICTC"
include ../Versions.inc

################################################################################

TARGET := loader
BUILDDIR := ../build
OUTPUTDIR := ../output
BDKDIR := bdk
BDKINC := -I../$(BDKDIR)
VPATH += $(dir $(wildcard ../$(BDKDIR)/*/)) $(dir $(wildcard ../$(BDKDIR)/*/*/))

# Main and graphics.
OBJS = $(addprefix $(BUILDDIR)/$(TARGET)/, \
start.o loader.o lz.o \
)

################################################################################

CUSTOMDEFINES := -DBL_MAGIC=$(IPL_MAGIC)
CUSTOMDEFINES += -DBL_VER_MJ=$(BLVERSION_MAJOR) -DBL_VER_MN=$(BLVERSION_MINOR) -DBL_VER_HF=$(BLVERSION_HOTFX) -DBL_RESERVED=$(BLVERSION_RSVD)

ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
CFLAGS = $(ARCH) -O2 -g -nostdlib -ffunction-sections -fdata-sections -fomit-frame-pointer -std=gnu11 -Wall $(CUSTOMDEFINES)
LDFLAGS = $(ARCH) -nostartfiles -lgcc -Wl,--nmagic,--gc-sections -Xlinker --defsym=LDR_LOAD_ADDR=$(LDR_LOAD_ADDR)

################################################################################

.PHONY: all clean

all: $(TARGET).bin $(TOOLSLZ) $(TOOLSB2C)

clean:
@rm -rf $(OBJS)

$(TARGET).bin: $(BUILDDIR)/$(TARGET)/$(TARGET).elf
$(OBJCOPY) -S -O binary $< $(OUTPUTDIR)/$(PAYLOAD_NAME).bin

$(BUILDDIR)/$(TARGET)/$(TARGET).elf: $(OBJS)
@$(CC) $(LDFLAGS) -T link.ld $^ -o $@

$(BUILDDIR)/$(TARGET)/%.o: %.c
@$(CC) $(CFLAGS) $(BDKINC) -c $< -o $@

$(BUILDDIR)/$(TARGET)/%.o: %.S
@$(CC) $(CFLAGS) -c $< -o $@

$(OBJS): $(BUILDDIR)/$(TARGET)

$(BUILDDIR)/$(TARGET):
@mkdir -p "$(BUILDDIR)"
@mkdir -p "$(BUILDDIR)/$(TARGET)"
@mkdir -p "$(OUTPUTDIR)"
22 changes: 22 additions & 0 deletions loader/link.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ENTRY(_start)

SECTIONS {
PROVIDE(__ipl_start = LDR_LOAD_ADDR);
. = __ipl_start;
.text : {
*(.text._start);
*(._boot_cfg);
*(._ipl_version);
*(._octopus);
*(.text*);
}
.data : {
*(.data*);
*(.rodata*);
*(._payload_00);
*(._payload_01);
}
__ldr_end = .;
. = ALIGN(0x10);
__ipl_end = .;
}
107 changes: 107 additions & 0 deletions loader/loader.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* Copyright (c) 2019 CTCaer
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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 <string.h>
#include <stdlib.h>

#include "payload_00.h"
#include "payload_01.h"

#include <memory_map.h>
#include <libs/compr/lz.h>
#include <soc/clock.h>
#include <soc/t210.h>

// 0x4003D000: Safe for panic preserving, 0x40038000: Safe for debugging needs.
#define IPL_RELOC_TOP 0x40038000
#define IPL_PATCHED_RELOC_SZ 0x94

boot_cfg_t __attribute__((section ("._boot_cfg"))) b_cfg;
const volatile ipl_ver_meta_t __attribute__((section ("._ipl_version"))) ipl_ver = {
.magic = BL_MAGIC,
.version = (BL_VER_MJ + '0') | ((BL_VER_MN + '0') << 8) | ((BL_VER_HF + '0') << 16),
.rsvd0 = 0,
.rsvd1 = 0
};

const volatile char __attribute__((section ("._octopus"))) octopus[] =
"\n"
" ___\n"
" .-' `'.\n"
" / \\\n"
" | ;\n"
" | | ___.--,\n"
" _.._ |0) = (0) | _.---'`__.-( (_.\n"
" __.--'`_.. '.__.\\ '--. \\_.-' ,.--'` `\"\"`\n"
" ( ,.--'` ',__ /./; ;, '.__.'` __\n"
" _`) ) .---.__.' / | |\\ \\__..--\"\" \"\"\"--.,_\n"
" `---' .'.''-._.-'`_./ /\\ '. \\ _.--''````'''--._`-.__.'\n"
" | | .' _.-' | | \\ \\ '. `----`\n"
" \\ \\/ .' \\ \\ '. '-._)\n"
" \\/ / \\ \\ `=.__`'-.\n"
" / /\\ `) ) / / `\"\".`\\\n"
" , _.-'.'\\ \\ / / ( ( / /\n"
" `--'` ) ) .-'.' '.'. | (\n"
" (/` ( (` ) ) '-; [switchbrew]\n";

void loader_main()
{
// Preserve sections.
__asm__ ("" : : "" (b_cfg));
__asm__ ("" : : "" (ipl_ver));
__asm__ ("" : : "" (octopus[0]));

// Preliminary BPMP clocks init.
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 0x10; // Set HCLK div to 2 and PCLK div to 1.
CLOCK(CLK_RST_CONTROLLER_CLK_SOURCE_SYS) = 0; // Set SCLK div to 1.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20004444; // Set clk source to Run and PLLP_OUT2 (204MHz).
CLOCK(CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER) = 0x80000000; // Enable SUPER_SDIV to 1.
CLOCK(CLK_RST_CONTROLLER_CLK_SYSTEM_RATE) = 2; // Set HCLK div to 1 and PCLK div to 3.
CLOCK(CLK_RST_CONTROLLER_SCLK_BURST_POLICY) = 0x20003333; // Set SCLK to PLLP_OUT (408MHz).

// Get Loader and Payload size.
u32 payload_size = sizeof(payload_00) + sizeof(payload_01);
u32 *payload_addr = (u32 *)payload_00;

// Relocate payload to a safer place.
u32 bytes = ALIGN(payload_size, 4) >> 2;
u32 *addr = payload_addr + bytes - 1;
u32 *dst = (u32 *)(IPL_RELOC_TOP - 4);
while (bytes)
{
*dst = *addr;
dst--;
addr--;
bytes--;
}

// Uncompress payload parts.
u8 *src_addr = (void *)(IPL_RELOC_TOP - ALIGN(payload_size, 4));
u32 pos = LZ_Uncompress((const u8 *)src_addr, (u8*)IPL_LOAD_ADDR, sizeof(payload_00));
src_addr += (u32)payload_01 - (u32)payload_00;
LZ_Uncompress((const u8 *)src_addr, (u8*)IPL_LOAD_ADDR + pos, sizeof(payload_01));

// Copy over boot configuration storage in case it was set.
memcpy((u8 *)(IPL_LOAD_ADDR + IPL_PATCHED_RELOC_SZ), &b_cfg, sizeof(boot_cfg_t));

// Chainload.
void (*ipl_ptr)() = (void *)IPL_LOAD_ADDR;
(*ipl_ptr)();

// Halt if we managed to get out of execution.
while (true)
;
}
73 changes: 73 additions & 0 deletions loader/start.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) 2018 naehrwert
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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/>.
*/

.section .text._start
.arm

.extern _reloc_ipl
.type _reloc_ipl, %function

.extern memset
.type memset, %function

.extern loader_main
.type loader_main, %function

.globl _start
.type _start, %function
_start:
ADR R0, _start
LDR R1, =__ipl_start
CMP R0, R1
BEQ _real_start

/* If we are not in the right location already, copy a relocator to upper IRAM. */
ADR R2, _reloc_ipl
LDR R3, =0x4003FF00
MOV R4, #(_real_start - _reloc_ipl)
_copy_loop:
LDMIA R2!, {R5}
STMIA R3!, {R5}
SUBS R4, #4
BNE _copy_loop

/* Use the relocator to copy ourselves into the right place. */
LDR R2, =__ipl_end
SUB R2, R2, R1
LDR R3, =_real_start
LDR R4, =0x4003FF00
BX R4

_reloc_ipl:
LDMIA R0!, {R4-R7}
STMIA R1!, {R4-R7}
SUBS R2, #0x10
BNE _reloc_ipl
/* Jump to the relocated entry. */
BX R3

_real_start:
/* Initially, we place our stack in IRAM but will move it to SDRAM later. */
LDR SP, =0x40007000
LDR R0, =__ldr_end
BL loader_main
B .
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
12 changes: 12 additions & 0 deletions tools/bin2c/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
NATIVE_CC ?= gcc

.PHONY: all clean

all: bin2c
@echo > /dev/null

clean:
rm -f bin2c

bin2c: bin2c.c
@$(NATIVE_CC) -o $@ bin2c.c
Loading

0 comments on commit 1ceb380

Please sign in to comment.