mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
mks5lboot v1.0 - dualboot installer for s5l8702 targets
A tool to install/uninstall a bootloader into a s5l8702 based device: - iPod Classic 6G - iPod Nano 3G (TODO) See mks5lboot/README for detailed info. Change-Id: I451d2aaff34509ebd356e4660647e5222c5d3409
This commit is contained in:
parent
eefc7c73e2
commit
346423c040
16 changed files with 3226 additions and 0 deletions
3
rbutil/mks5lboot/dualboot/.gitignore
vendored
Normal file
3
rbutil/mks5lboot/dualboot/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
build/
|
||||
*.arm-bin
|
||||
bin2c
|
||||
97
rbutil/mks5lboot/dualboot/Makefile
Normal file
97
rbutil/mks5lboot/dualboot/Makefile
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
# __________ __ ___.
|
||||
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
# \/ \/ \/ \/ \/
|
||||
# $Id$
|
||||
#
|
||||
ifndef V
|
||||
SILENT = @
|
||||
endif
|
||||
|
||||
CC = gcc
|
||||
LD = ld
|
||||
OC = objcopy
|
||||
CROSS ?= arm-elf-eabi-
|
||||
|
||||
ROOTDIR = ../../..
|
||||
FIRMDIR = $(ROOTDIR)/firmware
|
||||
FWARM = $(FIRMDIR)/target/arm
|
||||
FW8702 = $(FWARM)/s5l8702
|
||||
BUILDDIR = build/
|
||||
LINKFILE = dualboot.lds
|
||||
|
||||
# Edit the following variables when adding a new target.
|
||||
# mks5lboot.c also needs to be edited to refer to these
|
||||
# To add a new target x you need to:
|
||||
# 1) add x to the list in TARGETS
|
||||
# 2) create a variable named OPT_x of the form:
|
||||
# OPT_x=target specific defines
|
||||
TARGETS = ipod6g
|
||||
OPT_ipod6g = -DIPOD_6G -DMEMORYSIZE=64
|
||||
|
||||
LOADERS = install uninstall
|
||||
OPT_install =
|
||||
OPT_uninstall = -DDUALBOOT_UNINSTALL
|
||||
|
||||
# target/loader specific options
|
||||
$(foreach l, $(LOADERS),$(foreach t, $(TARGETS),\
|
||||
$(eval OPT_$(l)_$(t) = $(OPT_$(l)) $(OPT_$(t)))))
|
||||
|
||||
DEFINES = -DBOOTLOADER
|
||||
|
||||
SOURCES = init.S dualboot.c
|
||||
SOURCES += $(ROOTDIR)/lib/arm_support/support-arm.S
|
||||
SOURCES += $(wildcard $(FIRMDIR)/asm/mem*.c $(FIRMDIR)/libc/mem*.c)
|
||||
SOURCES += $(addprefix $(FWARM)/, mmu-arm.S)
|
||||
SOURCES += $(addprefix $(FW8702)/, clocking-s5l8702.c spi-s5l8702.c nor-s5l8702.c crypto-s5l8702.c)
|
||||
# target/loader specific sources
|
||||
SRCTARGET = piezo-.c
|
||||
$(foreach l, $(LOADERS), $(foreach t, $(TARGETS),\
|
||||
$(eval SRC_$(l)_$(t) = $(addprefix $(FW8702)/$(t)/, $(subst -.,-$(subst ipod,,$(t)).,$(SRCTARGET))))))
|
||||
|
||||
INCLUDES += -I. -I.. -I$(FIRMDIR) -I$(FWARM) -I$(FW8702)
|
||||
INCLUDES += $(addprefix -I$(FIRMDIR)/, export include libc/include kernel/include)
|
||||
# target/loader specific includes
|
||||
$(foreach l,$(LOADERS),$(foreach t,$(TARGETS),$(eval INC_$(l)_$(t) = -I$(FW8702)/$(t))))
|
||||
|
||||
CFLAGS = $(INCLUDES) -mcpu=arm926ej-s -std=gnu99 -nostdlib -ffreestanding -Os -W -Wall\
|
||||
-Wundef -Wstrict-prototypes -ffunction-sections -fdata-sections -Wl,--gc-sections $(DEFINES)
|
||||
|
||||
# Build filenames prefix
|
||||
PFX = dualboot_
|
||||
|
||||
BOOTBINS = $(foreach l, $(LOADERS),$(foreach t, $(TARGETS),$(PFX)$(l)_$(t).arm-bin))
|
||||
|
||||
OUTPUTDUALBOOT = ../dualboot.h ../dualboot.c
|
||||
OUTPUTDEBUG = $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.arm-elf) $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.lds)
|
||||
|
||||
|
||||
all: $(BUILDDIR) $(OUTPUTDUALBOOT)
|
||||
|
||||
$(BUILDDIR)$(PFX)%.lds: $(LINKFILE)
|
||||
@echo Creating $@
|
||||
$(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -E -x c - < $< | sed '/#/d' > $@
|
||||
|
||||
$(BUILDDIR)$(PFX)%.arm-elf: $(BUILDDIR)$(PFX)%.lds $(SOURCES)
|
||||
@echo CC -T $(notdir $^ $(SRC_$*))
|
||||
$(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -o $@ -T$^ $(SRC_$*)
|
||||
|
||||
$(PFX)%.arm-bin: $(BUILDDIR)$(PFX)%.arm-elf
|
||||
@echo OC $<
|
||||
$(SILENT)$(CROSS)$(OC) -O binary $< $@
|
||||
|
||||
bin2c: bin2c.c
|
||||
$(CC) -o $@ $<
|
||||
|
||||
$(OUTPUTDUALBOOT): bin2c $(BOOTBINS)
|
||||
./bin2c ../dualboot $(BOOTBINS)
|
||||
|
||||
$(BUILDDIR):
|
||||
mkdir -p $@
|
||||
|
||||
clean:
|
||||
rm -rf bin2c $(BOOTBINS) $(BUILDDIR)
|
||||
|
||||
.PRECIOUS: $(OUTPUTDEBUG)
|
||||
74
rbutil/mks5lboot/dualboot/autoconf.h
Normal file
74
rbutil/mks5lboot/dualboot/autoconf.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id:$
|
||||
*
|
||||
* Copyright (C) 2012 by Andrew Ryabinin
|
||||
*
|
||||
* 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef __BUILD_AUTOCONF_H
|
||||
#define __BUILD_AUTOCONF_H
|
||||
|
||||
/* lower case names match the what's exported in the Makefile
|
||||
* upper case name looks nicer in the code */
|
||||
|
||||
#define arch_none 0
|
||||
#define ARCH_NONE 0
|
||||
|
||||
#define arch_sh 1
|
||||
#define ARCH_SH 1
|
||||
|
||||
#define arch_m68k 2
|
||||
#define ARCH_M68K 2
|
||||
|
||||
#define arch_arm 3
|
||||
#define ARCH_ARM 3
|
||||
|
||||
#define arch_mips 4
|
||||
#define ARCH_MIPS 4
|
||||
|
||||
#define arch_x86 5
|
||||
#define ARCH_X86 5
|
||||
|
||||
#define arch_amd64 6
|
||||
#define ARCH_AMD64 6
|
||||
|
||||
/* Define target machine architecture */
|
||||
#define ARCH arch_arm
|
||||
/* Optionally define architecture version */
|
||||
#define ARCH_VERSION 5
|
||||
|
||||
/* Define endianess for the target or simulator platform */
|
||||
#define ROCKBOX_LITTLE_ENDIAN 1
|
||||
|
||||
/* Define this if you build rockbox to support the logf logging and display */
|
||||
#undef ROCKBOX_HAS_LOGF
|
||||
|
||||
/* Define this if you want logf to output to the serial port */
|
||||
#undef LOGF_SERIAL
|
||||
|
||||
/* Define this to record a chart with timings for the stages of boot */
|
||||
#undef DO_BOOTCHART
|
||||
|
||||
/* the threading backend we use */
|
||||
#define ASSEMBLER_THREADS
|
||||
|
||||
/* root of Rockbox */
|
||||
#define ROCKBOX_DIR "/.rockbox"
|
||||
#define ROCKBOX_SHARE_PATH ""
|
||||
#define ROCKBOX_BINARY_PATH ""
|
||||
#define ROCKBOX_LIBRARY_PATH ""
|
||||
|
||||
#endif /* __BUILD_AUTOCONF_H */
|
||||
140
rbutil/mks5lboot/dualboot/bin2c.c
Normal file
140
rbutil/mks5lboot/dualboot/bin2c.c
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2007 Dave Chapman
|
||||
*
|
||||
* 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <libgen.h>
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
static off_t filesize(int fd)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
fstat(fd,&buf);
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(fp,"unsigned char %s[%ld] = {",name,len);
|
||||
|
||||
for (i=0;i<len;i++) {
|
||||
if ((i % 16) == 0) {
|
||||
fprintf(fp,"\n ");
|
||||
}
|
||||
if (i == (len-1)) {
|
||||
fprintf(fp,"0x%02x",buf[i]);
|
||||
} else if ((i % 16) == 15) {
|
||||
fprintf(fp,"0x%02x,",buf[i]);
|
||||
} else {
|
||||
fprintf(fp,"0x%02x, ",buf[i]);
|
||||
}
|
||||
}
|
||||
fprintf(fp,"\n};\n");
|
||||
}
|
||||
|
||||
int main (int argc, char* argv[])
|
||||
{
|
||||
char* cname;
|
||||
int i;
|
||||
FILE *cfile, *hfile;
|
||||
char cfilename[256], hfilename[256];
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
cname=argv[1];
|
||||
|
||||
snprintf(cfilename,256,"%s.c",cname);
|
||||
cfile = fopen(cfilename,"w+");
|
||||
if (cfile == NULL) {
|
||||
fprintf(stderr,"Couldn't open %s\n",cfilename);
|
||||
return 2;
|
||||
}
|
||||
|
||||
snprintf(hfilename,256,"%s.h",cname);
|
||||
hfile = fopen(hfilename,"w+");
|
||||
if (hfile == NULL) {
|
||||
fprintf(stderr,"Couldn't open %s\n",hfilename);
|
||||
fclose(cfile);
|
||||
return 3;
|
||||
}
|
||||
|
||||
fprintf(cfile,"/* Generated by bin2c */\n\n");
|
||||
fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
|
||||
fprintf(hfile,"/* Generated by bin2c */\n\n");
|
||||
|
||||
for(i=0; i < argc - 2; i++) {
|
||||
unsigned char* buf;
|
||||
off_t len;
|
||||
off_t orig_len;
|
||||
char *ext;
|
||||
char *array = argv[2+i];
|
||||
|
||||
int fd = open(array,O_RDONLY|O_BINARY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr,"Can not open %s\n",argv[2+i]);
|
||||
fclose(cfile);
|
||||
fclose(hfile);
|
||||
return 4;
|
||||
}
|
||||
|
||||
orig_len = filesize(fd);
|
||||
/* pad to 32bit */
|
||||
len = (orig_len + 3) & ~3;
|
||||
|
||||
buf = malloc(len);
|
||||
if (read(fd,buf,orig_len) < orig_len) {
|
||||
fprintf(stderr,"Short read, aborting\n");
|
||||
return 5;
|
||||
}
|
||||
|
||||
/* pad to 32bit with zeros */
|
||||
if (len > orig_len)
|
||||
memset(buf+orig_len, 0, len-orig_len);
|
||||
|
||||
/* remove file extension */
|
||||
ext = strchr (array, '.');
|
||||
if (ext != NULL)
|
||||
*ext = '\0';
|
||||
write_cfile (buf, len, cfile, array);
|
||||
fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
fclose(cfile);
|
||||
fclose(hfile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
287
rbutil/mks5lboot/dualboot/dualboot.c
Normal file
287
rbutil/mks5lboot/dualboot/dualboot.c
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2015 by Cástor Muñoz
|
||||
*
|
||||
* 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "button.h"
|
||||
|
||||
#include "s5l8702.h"
|
||||
#include "clocking-s5l8702.h"
|
||||
#include "spi-s5l8702.h"
|
||||
#include "nor-target.h"
|
||||
#include "piezo.h"
|
||||
|
||||
/* How it works:
|
||||
*
|
||||
* - dualboot-installer: installs or updates a RB bootloader, the bootloader
|
||||
* to install/update is already included into dualboot-installer.dfu file,
|
||||
* once it is executed by the iPod device:
|
||||
*
|
||||
* 1) locates an original NORBOOT (ONB): first it looks at offset=32KB, if
|
||||
* a NORBOOT is found but it is not an ONB then it is supposed it is a
|
||||
* RB bootloader (that should be updated), then the ONB is loaded from
|
||||
* offset=32KB+old_BLSIZE).
|
||||
* 2) write ONB at 32KB+new_BLSIZE, if it fails then:
|
||||
* 2a) try to restore ONB to its 'pristine' place (offset=32KB), if it
|
||||
* also fails then the NOR got corrupted (ONB probably destroyed)
|
||||
* and iTunes should be used to restore the iPod.
|
||||
* 3) write new (included) RB bootloader at offset=32KB, it it fails then
|
||||
* goto 2a)
|
||||
*
|
||||
* - dualboot-uninstaller: uninstall RB bootloader from NOR, leaving it at
|
||||
* it's previous (pristine) state.
|
||||
*
|
||||
* See bootloader/ipod6g.c for notes on how the RB bootloader works.
|
||||
*
|
||||
*
|
||||
* Pristine NOR Rockboxed NOR
|
||||
* 1MB ______________
|
||||
* | |
|
||||
* | flsh DIR |
|
||||
* 1MB-0x200 |______________|
|
||||
* | |
|
||||
* | File 1 |
|
||||
* |..............|
|
||||
* | |
|
||||
* . .
|
||||
* . .
|
||||
* . .
|
||||
* | |
|
||||
* |..............|
|
||||
* | | . .
|
||||
* | File N | . .
|
||||
* |______________| |______________|
|
||||
* | | | |
|
||||
* | | | |
|
||||
* | | | Unused |
|
||||
* | | | |
|
||||
* | Unused | 160KB+BLSZ |______________|
|
||||
* | | | |
|
||||
* | | | Original |
|
||||
* | | | NOR boot |
|
||||
* 160KB |______________| | (decrypted) |
|
||||
* | | | |
|
||||
* | | 32KB+BLSZ |______________|
|
||||
* | Original | | |
|
||||
* | NOR boot | | Decrypted |
|
||||
* | (encrypted) | | Rockbox |
|
||||
* | | | Bootloader |
|
||||
* 32KB |______________| 32KB |______________|
|
||||
* | | | |
|
||||
* | | . .
|
||||
* | | . .
|
||||
* |______________|
|
||||
* | |
|
||||
* | SysCfg |
|
||||
* 0 |______________|
|
||||
*
|
||||
*/
|
||||
|
||||
#define OF_LOADADDR IRAM1_ORIG
|
||||
|
||||
/* tone sequences: period (uS), duration (ms), silence (ms) */
|
||||
static uint16_t alive[] = { 500,100,0, 0 };
|
||||
static uint16_t happy[] = { 1000,100,0, 500,150,0, 0 };
|
||||
static uint16_t fatal[] = { 3000,500,500, 3000,500,500, 3000,500,0, 0 };
|
||||
#define sad2 (&fatal[3])
|
||||
#define sad (&fatal[6])
|
||||
|
||||
/* iPod Classic: decrypted hashes for known OFs */
|
||||
static unsigned char of_sha[][SIGN_SZ] = {
|
||||
"\x66\x66\x76\xDC\x1D\x32\xB2\x46\xA6\xC9\x7D\x5A\x61\xD3\x49\x4C", /* v1.1.2 */
|
||||
"\x1E\xF0\xD9\xDE\xC2\x7E\xEC\x02\x7C\x15\x76\xBB\x5C\x4F\x2D\x95", /* v2.0.1 */
|
||||
"\x06\x85\xDF\x28\xE4\xD7\xF4\x82\xC0\x73\xB0\x53\x26\xFC\xB0\xFE", /* v2.0.4 */
|
||||
"\x60\x80\x7D\x33\xA8\xDE\xF8\x49\xBB\xBE\x01\x45\xFF\x62\x40\x19" /* v2.0.5 */
|
||||
};
|
||||
#define N_OF (int)(sizeof(of_sha)/SIGN_SZ)
|
||||
|
||||
/* we can assume that unknown FW is a RB bootloader */
|
||||
#define FW_RB N_OF
|
||||
|
||||
static int identify_fw(struct Im3Info *hinfo)
|
||||
{
|
||||
unsigned char hash[SIGN_SZ];
|
||||
int of;
|
||||
|
||||
/* decrypt hash to identify OF */
|
||||
memcpy(hash, hinfo->u.enc12.data_sign, SIGN_SZ);
|
||||
hwkeyaes(HWKEYAES_DECRYPT, HWKEYAES_UKEY, hash, SIGN_SZ);
|
||||
|
||||
for (of = 0; of < N_OF; of++)
|
||||
if (memcmp(hash, of_sha[of], SIGN_SZ) == 0)
|
||||
break;
|
||||
|
||||
return of;
|
||||
}
|
||||
|
||||
#ifdef DUALBOOT_UNINSTALL
|
||||
/* Uninstall RB bootloader */
|
||||
void main(void)
|
||||
{
|
||||
struct Im3Info *hinfo;
|
||||
void *fw_addr;
|
||||
uint16_t *status;
|
||||
unsigned bl_nor_sz;
|
||||
|
||||
usec_timer_init();
|
||||
piezo_seq(alive);
|
||||
spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
|
||||
|
||||
hinfo = (struct Im3Info*)OF_LOADADDR;
|
||||
fw_addr = (void*)hinfo + IM3HDR_SZ;
|
||||
|
||||
if (im3_read(NORBOOT_OFF, hinfo, NULL) != 0) {
|
||||
status = sad;
|
||||
goto bye; /* no FW found */
|
||||
}
|
||||
|
||||
if (identify_fw(hinfo) != FW_RB) {
|
||||
status = happy;
|
||||
goto bye; /* RB bootloader not installed, nothing to do */
|
||||
}
|
||||
|
||||
/* if found FW is a RB bootloader, OF should start just behind it */
|
||||
bl_nor_sz = im3_nor_sz(hinfo);
|
||||
if ((im3_read(NORBOOT_OFF + bl_nor_sz, hinfo, fw_addr) != 0)
|
||||
|| (identify_fw(hinfo) == FW_RB)) {
|
||||
status = sad;
|
||||
goto bye; /* OF not found */
|
||||
}
|
||||
|
||||
/* decrypted OF correctly loaded, encrypt it before restoration */
|
||||
im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
|
||||
|
||||
/* restore OF to it's original place */
|
||||
if (!im3_write(NORBOOT_OFF, hinfo)) {
|
||||
status = fatal;
|
||||
goto bye; /* corrupted NOR, use iTunes to restore */
|
||||
}
|
||||
|
||||
/* erase freed NOR blocks */
|
||||
bootflash_init(SPI_PORT);
|
||||
bootflash_erase_blocks(SPI_PORT,
|
||||
(NORBOOT_OFF + im3_nor_sz(hinfo)) >> 12, bl_nor_sz >> 12);
|
||||
bootflash_close(SPI_PORT);
|
||||
|
||||
status = happy;
|
||||
|
||||
bye:
|
||||
/* minimum time between the initial and the final beeps */
|
||||
while (USEC_TIMER < 2000000);
|
||||
piezo_seq(status);
|
||||
WDTCON = 0x100000; /* WDT reset */
|
||||
while (1);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Install RB bootloader */
|
||||
struct Im3Info bl_hinfo __attribute__((section(".im3info.data"))) =
|
||||
{
|
||||
.ident = IM3_IDENT,
|
||||
.version = IM3_VERSION,
|
||||
.enc_type = 2,
|
||||
};
|
||||
|
||||
static uint32_t get_uint32le(unsigned char *p)
|
||||
{
|
||||
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
uint16_t *status = happy;
|
||||
int single_boot;
|
||||
struct Im3Info *hinfo;
|
||||
void *fw_addr;
|
||||
unsigned bl_nor_sz;
|
||||
|
||||
usec_timer_init();
|
||||
piezo_seq(alive);
|
||||
spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
|
||||
|
||||
/* check for single boot installation, is is configured when
|
||||
mks5lboot.exe builds the .dfu image */
|
||||
single_boot = bl_hinfo.info_sign[0];
|
||||
|
||||
/* sign RB bootloader (data and header), but don't encrypt it,
|
||||
use current decrypted image for faster load */
|
||||
im3_sign(HWKEYAES_UKEY, (void*)&bl_hinfo + IM3HDR_SZ,
|
||||
get_uint32le(bl_hinfo.data_sz), bl_hinfo.u.enc12.data_sign);
|
||||
im3_sign(HWKEYAES_UKEY, &bl_hinfo, IM3INFOSIGN_SZ, bl_hinfo.info_sign);
|
||||
|
||||
if (single_boot) {
|
||||
if (!im3_write(NORBOOT_OFF, &bl_hinfo))
|
||||
status = sad;
|
||||
goto bye;
|
||||
}
|
||||
|
||||
hinfo = (struct Im3Info*)OF_LOADADDR;
|
||||
fw_addr = (void*)hinfo + IM3HDR_SZ;
|
||||
|
||||
if (im3_read(NORBOOT_OFF, hinfo, fw_addr) != 0) {
|
||||
status = sad;
|
||||
goto bye; /* no FW found */
|
||||
}
|
||||
|
||||
if (identify_fw(hinfo) == FW_RB) {
|
||||
/* FW found, but not OF, assume it is a RB bootloader,
|
||||
already decrypted OF should be located just behind */
|
||||
int nor_offset = NORBOOT_OFF + im3_nor_sz(hinfo);
|
||||
if ((im3_read(nor_offset, hinfo, fw_addr) != 0)
|
||||
|| (identify_fw(hinfo) == FW_RB)) {
|
||||
status = sad;
|
||||
goto bye; /* OF not found, use iTunes to restore */
|
||||
}
|
||||
}
|
||||
|
||||
bl_nor_sz = im3_nor_sz(&bl_hinfo);
|
||||
/* safety check - verify we are not going to overwrite useful data */
|
||||
if (flsh_get_unused() < bl_nor_sz) {
|
||||
status = sad2;
|
||||
goto bye; /* no space if flash, use iTunes to restore */
|
||||
}
|
||||
|
||||
/* write decrypted OF and RB bootloader, if any of these fails we
|
||||
will try to retore OF to its original place */
|
||||
if (!im3_write(NORBOOT_OFF + bl_nor_sz, hinfo)
|
||||
|| !im3_write(NORBOOT_OFF, &bl_hinfo)) {
|
||||
im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
|
||||
if (!im3_write(NORBOOT_OFF, hinfo)) {
|
||||
/* corrupted NOR, use iTunes to restore */
|
||||
status = fatal;
|
||||
}
|
||||
else {
|
||||
/* RB bootloader not succesfully intalled, but device
|
||||
was restored and should be working as before */
|
||||
status = sad;
|
||||
}
|
||||
}
|
||||
|
||||
bye:
|
||||
/* minimum time between the initial and the final beeps */
|
||||
while (USEC_TIMER < 2000000);
|
||||
piezo_seq(status);
|
||||
WDTCON = 0x100000; /* WDT reset */
|
||||
while (1);
|
||||
}
|
||||
#endif /* DUALBOOT_UNINSTALL */
|
||||
59
rbutil/mks5lboot/dualboot/dualboot.lds
Normal file
59
rbutil/mks5lboot/dualboot/dualboot.lds
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#define ASM
|
||||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
#include "mks5lboot.h"
|
||||
|
||||
ENTRY(_start)
|
||||
OUTPUT_FORMAT(elf32-littlearm)
|
||||
OUTPUT_ARCH(arm)
|
||||
|
||||
#define BIN_ORIG DFU_LOADADDR + BIN_OFFSET
|
||||
#define BIN_SIZE MAX_PAYLOAD
|
||||
|
||||
MEMORY
|
||||
{
|
||||
IRAM : ORIGIN = BIN_ORIG, LENGTH = BIN_SIZE
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
*(.init.text*)
|
||||
*(.text*)
|
||||
*(.icode*)
|
||||
. = ALIGN(4);
|
||||
} > IRAM
|
||||
|
||||
/* include initialized BSS (if any) into DFU image */
|
||||
.bss : {
|
||||
*(.bss*)
|
||||
*(.ibss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
} > IRAM
|
||||
|
||||
#if 1
|
||||
/* reuse pwnage as stack, 0x30c bytes available */
|
||||
_exception_stack = BIN_ORIG;
|
||||
_supervisor_stack = _exception_stack;
|
||||
#else
|
||||
/* include stack into DFU image */
|
||||
.stack : {
|
||||
. += 0x400;
|
||||
_supervisor_stack = .;
|
||||
. += 0x200;
|
||||
_exception_stack = .;
|
||||
} > IRAM
|
||||
#endif
|
||||
|
||||
.data : {
|
||||
*(.data*)
|
||||
*(.rodata*)
|
||||
*(.idata*)
|
||||
*(.irodata*)
|
||||
/* place bootloader IM3 header at the end, mkdfu
|
||||
will concatenate the bootloader binary here */
|
||||
. = ALIGN(16);
|
||||
*(.im3info.data*)
|
||||
} > IRAM
|
||||
}
|
||||
43
rbutil/mks5lboot/dualboot/init.S
Normal file
43
rbutil/mks5lboot/dualboot/init.S
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id:
|
||||
*
|
||||
* Copyright © 2009 Michael Sparmann
|
||||
*
|
||||
* 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
.section .init.text, "ax", %progbits
|
||||
.global _start
|
||||
|
||||
_start:
|
||||
mov r0, #0xD7
|
||||
msr CPSR_c, r0 @ Abort mode, IRQs/FIQs disabled
|
||||
ldr sp, =_exception_stack
|
||||
|
||||
mov r0, #0xDB
|
||||
msr CPSR_c, r0 @ Undefined Instruction mode, IRQs/FIQs disabled
|
||||
ldr sp, =_exception_stack
|
||||
|
||||
mov r0, #0xD3
|
||||
msr CPSR_c, r0 @ Supervisor mode, IRQs/FIQs disabled
|
||||
ldr sp, =_supervisor_stack
|
||||
|
||||
MOV R0, #0x00050000
|
||||
ORR R0, #0x00000078
|
||||
MCR p15, 0, R0, c1, c0, 0 @ Get rid of some CPU "features" likely to cause trouble
|
||||
|
||||
bl main
|
||||
.ltorg
|
||||
Loading…
Add table
Add a link
Reference in a new issue