summaryrefslogtreecommitdiff
path: root/utils/mks5lboot/dualboot
diff options
context:
space:
mode:
Diffstat (limited to 'utils/mks5lboot/dualboot')
-rw-r--r--utils/mks5lboot/dualboot/.gitignore3
-rw-r--r--utils/mks5lboot/dualboot/Makefile97
-rw-r--r--utils/mks5lboot/dualboot/autoconf.h74
-rw-r--r--utils/mks5lboot/dualboot/bin2c.c140
-rw-r--r--utils/mks5lboot/dualboot/dualboot.c287
-rw-r--r--utils/mks5lboot/dualboot/dualboot.lds59
-rw-r--r--utils/mks5lboot/dualboot/init.S43
7 files changed, 703 insertions, 0 deletions
diff --git a/utils/mks5lboot/dualboot/.gitignore b/utils/mks5lboot/dualboot/.gitignore
new file mode 100644
index 0000000000..34c53b3c82
--- /dev/null
+++ b/utils/mks5lboot/dualboot/.gitignore
@@ -0,0 +1,3 @@
1build/
2*.arm-bin
3bin2c
diff --git a/utils/mks5lboot/dualboot/Makefile b/utils/mks5lboot/dualboot/Makefile
new file mode 100644
index 0000000000..51ce816ca0
--- /dev/null
+++ b/utils/mks5lboot/dualboot/Makefile
@@ -0,0 +1,97 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9ifndef V
10SILENT = @
11endif
12
13CC = gcc
14LD = ld
15OC = objcopy
16CROSS ?= arm-elf-eabi-
17
18ROOTDIR = ../../..
19FIRMDIR = $(ROOTDIR)/firmware
20FWARM = $(FIRMDIR)/target/arm
21FW8702 = $(FWARM)/s5l8702
22BUILDDIR = build/
23LINKFILE = dualboot.lds
24
25# Edit the following variables when adding a new target.
26# mks5lboot.c also needs to be edited to refer to these
27# To add a new target x you need to:
28# 1) add x to the list in TARGETS
29# 2) create a variable named OPT_x of the form:
30# OPT_x=target specific defines
31TARGETS = ipod6g
32OPT_ipod6g = -DIPOD_6G -DMEMORYSIZE=64
33
34LOADERS = install uninstall
35OPT_install =
36OPT_uninstall = -DDUALBOOT_UNINSTALL
37
38# target/loader specific options
39$(foreach l, $(LOADERS),$(foreach t, $(TARGETS),\
40 $(eval OPT_$(l)_$(t) = $(OPT_$(l)) $(OPT_$(t)))))
41
42DEFINES = -DBOOTLOADER
43
44SOURCES = init.S dualboot.c
45SOURCES += $(ROOTDIR)/lib/arm_support/support-arm.S
46SOURCES += $(wildcard $(FIRMDIR)/asm/mem*.c $(FIRMDIR)/libc/mem*.c)
47SOURCES += $(addprefix $(FWARM)/, mmu-arm.S)
48SOURCES += $(addprefix $(FW8702)/, clocking-s5l8702.c spi-s5l8702.c nor-s5l8702.c crypto-s5l8702.c)
49# target/loader specific sources
50SRCTARGET = piezo-.c
51$(foreach l, $(LOADERS), $(foreach t, $(TARGETS),\
52 $(eval SRC_$(l)_$(t) = $(addprefix $(FW8702)/$(t)/, $(subst -.,-$(subst ipod,,$(t)).,$(SRCTARGET))))))
53
54INCLUDES += -I. -I.. -I$(FIRMDIR) -I$(FWARM) -I$(FW8702)
55INCLUDES += $(addprefix -I$(FIRMDIR)/, export include libc/include kernel/include)
56# target/loader specific includes
57$(foreach l,$(LOADERS),$(foreach t,$(TARGETS),$(eval INC_$(l)_$(t) = -I$(FW8702)/$(t))))
58
59CFLAGS = $(INCLUDES) -mcpu=arm926ej-s -std=gnu99 -nostdlib -ffreestanding -Os -W -Wall\
60 -Wundef -Wstrict-prototypes -ffunction-sections -fdata-sections -Wl,--gc-sections $(DEFINES)
61
62# Build filenames prefix
63PFX = dualboot_
64
65BOOTBINS = $(foreach l, $(LOADERS),$(foreach t, $(TARGETS),$(PFX)$(l)_$(t).arm-bin))
66
67OUTPUTDUALBOOT = ../dualboot.h ../dualboot.c
68OUTPUTDEBUG = $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.arm-elf) $(BOOTBINS:%.arm-bin=$(BUILDDIR)%.lds)
69
70
71all: $(BUILDDIR) $(OUTPUTDUALBOOT)
72
73$(BUILDDIR)$(PFX)%.lds: $(LINKFILE)
74 @echo Creating $@
75 $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -E -x c - < $< | sed '/#/d' > $@
76
77$(BUILDDIR)$(PFX)%.arm-elf: $(BUILDDIR)$(PFX)%.lds $(SOURCES)
78 @echo CC -T $(notdir $^ $(SRC_$*))
79 $(SILENT)$(CROSS)$(CC) $(INC_$*) $(CFLAGS) $(OPT_$*) -o $@ -T$^ $(SRC_$*)
80
81$(PFX)%.arm-bin: $(BUILDDIR)$(PFX)%.arm-elf
82 @echo OC $<
83 $(SILENT)$(CROSS)$(OC) -O binary $< $@
84
85bin2c: bin2c.c
86 $(CC) -o $@ $<
87
88$(OUTPUTDUALBOOT): bin2c $(BOOTBINS)
89 ./bin2c ../dualboot $(BOOTBINS)
90
91$(BUILDDIR):
92 mkdir -p $@
93
94clean:
95 rm -rf bin2c $(BOOTBINS) $(BUILDDIR)
96
97.PRECIOUS: $(OUTPUTDEBUG)
diff --git a/utils/mks5lboot/dualboot/autoconf.h b/utils/mks5lboot/dualboot/autoconf.h
new file mode 100644
index 0000000000..cd5b3f9aeb
--- /dev/null
+++ b/utils/mks5lboot/dualboot/autoconf.h
@@ -0,0 +1,74 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2012 by Andrew Ryabinin
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __BUILD_AUTOCONF_H
22#define __BUILD_AUTOCONF_H
23
24/* lower case names match the what's exported in the Makefile
25 * upper case name looks nicer in the code */
26
27#define arch_none 0
28#define ARCH_NONE 0
29
30#define arch_sh 1
31#define ARCH_SH 1
32
33#define arch_m68k 2
34#define ARCH_M68K 2
35
36#define arch_arm 3
37#define ARCH_ARM 3
38
39#define arch_mips 4
40#define ARCH_MIPS 4
41
42#define arch_x86 5
43#define ARCH_X86 5
44
45#define arch_amd64 6
46#define ARCH_AMD64 6
47
48/* Define target machine architecture */
49#define ARCH arch_arm
50/* Optionally define architecture version */
51#define ARCH_VERSION 5
52
53/* Define endianess for the target or simulator platform */
54#define ROCKBOX_LITTLE_ENDIAN 1
55
56/* Define this if you build rockbox to support the logf logging and display */
57#undef ROCKBOX_HAS_LOGF
58
59/* Define this if you want logf to output to the serial port */
60#undef LOGF_SERIAL
61
62/* Define this to record a chart with timings for the stages of boot */
63#undef DO_BOOTCHART
64
65/* the threading backend we use */
66#define ASSEMBLER_THREADS
67
68/* root of Rockbox */
69#define ROCKBOX_DIR "/.rockbox"
70#define ROCKBOX_SHARE_PATH ""
71#define ROCKBOX_BINARY_PATH ""
72#define ROCKBOX_LIBRARY_PATH ""
73
74#endif /* __BUILD_AUTOCONF_H */
diff --git a/utils/mks5lboot/dualboot/bin2c.c b/utils/mks5lboot/dualboot/bin2c.c
new file mode 100644
index 0000000000..4d74a19696
--- /dev/null
+++ b/utils/mks5lboot/dualboot/bin2c.c
@@ -0,0 +1,140 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2007 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include <stdio.h>
23#include <string.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <unistd.h>
27#include <fcntl.h>
28#include <stdlib.h>
29#include <libgen.h>
30
31#ifndef O_BINARY
32#define O_BINARY 0
33#endif
34
35static off_t filesize(int fd)
36{
37 struct stat buf;
38
39 fstat(fd,&buf);
40 return buf.st_size;
41}
42
43static void write_cfile(const unsigned char* buf, off_t len, FILE* fp, const char *name)
44{
45 int i;
46
47 fprintf(fp,"unsigned char %s[%ld] = {",name,len);
48
49 for (i=0;i<len;i++) {
50 if ((i % 16) == 0) {
51 fprintf(fp,"\n ");
52 }
53 if (i == (len-1)) {
54 fprintf(fp,"0x%02x",buf[i]);
55 } else if ((i % 16) == 15) {
56 fprintf(fp,"0x%02x,",buf[i]);
57 } else {
58 fprintf(fp,"0x%02x, ",buf[i]);
59 }
60 }
61 fprintf(fp,"\n};\n");
62}
63
64int main (int argc, char* argv[])
65{
66 char* cname;
67 int i;
68 FILE *cfile, *hfile;
69 char cfilename[256], hfilename[256];
70
71 if (argc < 3) {
72 fprintf(stderr,"Usage: bin2c cname file1 [file2 [file3 ...]]\n");
73 return 1;
74 }
75
76 cname=argv[1];
77
78 snprintf(cfilename,256,"%s.c",cname);
79 cfile = fopen(cfilename,"w+");
80 if (cfile == NULL) {
81 fprintf(stderr,"Couldn't open %s\n",cfilename);
82 return 2;
83 }
84
85 snprintf(hfilename,256,"%s.h",cname);
86 hfile = fopen(hfilename,"w+");
87 if (hfile == NULL) {
88 fprintf(stderr,"Couldn't open %s\n",hfilename);
89 fclose(cfile);
90 return 3;
91 }
92
93 fprintf(cfile,"/* Generated by bin2c */\n\n");
94 fprintf(cfile,"#include \"%s\"\n\n", basename(hfilename));
95 fprintf(hfile,"/* Generated by bin2c */\n\n");
96
97 for(i=0; i < argc - 2; i++) {
98 unsigned char* buf;
99 off_t len;
100 off_t orig_len;
101 char *ext;
102 char *array = argv[2+i];
103
104 int fd = open(array,O_RDONLY|O_BINARY);
105 if (fd < 0) {
106 fprintf(stderr,"Can not open %s\n",argv[2+i]);
107 fclose(cfile);
108 fclose(hfile);
109 return 4;
110 }
111
112 orig_len = filesize(fd);
113 /* pad to 32bit */
114 len = (orig_len + 3) & ~3;
115
116 buf = malloc(len);
117 if (read(fd,buf,orig_len) < orig_len) {
118 fprintf(stderr,"Short read, aborting\n");
119 return 5;
120 }
121
122 /* pad to 32bit with zeros */
123 if (len > orig_len)
124 memset(buf+orig_len, 0, len-orig_len);
125
126 /* remove file extension */
127 ext = strchr (array, '.');
128 if (ext != NULL)
129 *ext = '\0';
130 write_cfile (buf, len, cfile, array);
131 fprintf(hfile,"extern unsigned char %s[%ld];\n",array,len);
132
133 close(fd);
134 }
135
136 fclose(cfile);
137 fclose(hfile);
138
139 return 0;
140}
diff --git a/utils/mks5lboot/dualboot/dualboot.c b/utils/mks5lboot/dualboot/dualboot.c
new file mode 100644
index 0000000000..b8167ec124
--- /dev/null
+++ b/utils/mks5lboot/dualboot/dualboot.c
@@ -0,0 +1,287 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2015 by Cástor Muñoz
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdint.h>
22#include <string.h>
23
24#include "config.h"
25#include "system.h"
26#include "button.h"
27
28#include "s5l8702.h"
29#include "clocking-s5l8702.h"
30#include "spi-s5l8702.h"
31#include "nor-target.h"
32#include "piezo.h"
33
34/* How it works:
35 *
36 * - dualboot-installer: installs or updates a RB bootloader, the bootloader
37 * to install/update is already included into dualboot-installer.dfu file,
38 * once it is executed by the iPod device:
39 *
40 * 1) locates an original NORBOOT (ONB): first it looks at offset=32KB, if
41 * a NORBOOT is found but it is not an ONB then it is supposed it is a
42 * RB bootloader (that should be updated), then the ONB is loaded from
43 * offset=32KB+old_BLSIZE).
44 * 2) write ONB at 32KB+new_BLSIZE, if it fails then:
45 * 2a) try to restore ONB to its 'pristine' place (offset=32KB), if it
46 * also fails then the NOR got corrupted (ONB probably destroyed)
47 * and iTunes should be used to restore the iPod.
48 * 3) write new (included) RB bootloader at offset=32KB, it it fails then
49 * goto 2a)
50 *
51 * - dualboot-uninstaller: uninstall RB bootloader from NOR, leaving it at
52 * it's previous (pristine) state.
53 *
54 * See bootloader/ipod6g.c for notes on how the RB bootloader works.
55 *
56 *
57 * Pristine NOR Rockboxed NOR
58 * 1MB ______________
59 * | |
60 * | flsh DIR |
61 * 1MB-0x200 |______________|
62 * | |
63 * | File 1 |
64 * |..............|
65 * | |
66 * . .
67 * . .
68 * . .
69 * | |
70 * |..............|
71 * | | . .
72 * | File N | . .
73 * |______________| |______________|
74 * | | | |
75 * | | | |
76 * | | | Unused |
77 * | | | |
78 * | Unused | 160KB+BLSZ |______________|
79 * | | | |
80 * | | | Original |
81 * | | | NOR boot |
82 * 160KB |______________| | (decrypted) |
83 * | | | |
84 * | | 32KB+BLSZ |______________|
85 * | Original | | |
86 * | NOR boot | | Decrypted |
87 * | (encrypted) | | Rockbox |
88 * | | | Bootloader |
89 * 32KB |______________| 32KB |______________|
90 * | | | |
91 * | | . .
92 * | | . .
93 * |______________|
94 * | |
95 * | SysCfg |
96 * 0 |______________|
97 *
98 */
99
100#define OF_LOADADDR IRAM1_ORIG
101
102/* tone sequences: period (uS), duration (ms), silence (ms) */
103static uint16_t alive[] = { 500,100,0, 0 };
104static uint16_t happy[] = { 1000,100,0, 500,150,0, 0 };
105static uint16_t fatal[] = { 3000,500,500, 3000,500,500, 3000,500,0, 0 };
106#define sad2 (&fatal[3])
107#define sad (&fatal[6])
108
109/* iPod Classic: decrypted hashes for known OFs */
110static unsigned char of_sha[][SIGN_SZ] = {
111 "\x66\x66\x76\xDC\x1D\x32\xB2\x46\xA6\xC9\x7D\x5A\x61\xD3\x49\x4C", /* v1.1.2 */
112 "\x1E\xF0\xD9\xDE\xC2\x7E\xEC\x02\x7C\x15\x76\xBB\x5C\x4F\x2D\x95", /* v2.0.1 */
113 "\x06\x85\xDF\x28\xE4\xD7\xF4\x82\xC0\x73\xB0\x53\x26\xFC\xB0\xFE", /* v2.0.4 */
114 "\x60\x80\x7D\x33\xA8\xDE\xF8\x49\xBB\xBE\x01\x45\xFF\x62\x40\x19" /* v2.0.5 */
115};
116#define N_OF (int)(sizeof(of_sha)/SIGN_SZ)
117
118/* we can assume that unknown FW is a RB bootloader */
119#define FW_RB N_OF
120
121static int identify_fw(struct Im3Info *hinfo)
122{
123 unsigned char hash[SIGN_SZ];
124 int of;
125
126 /* decrypt hash to identify OF */
127 memcpy(hash, hinfo->u.enc12.data_sign, SIGN_SZ);
128 hwkeyaes(HWKEYAES_DECRYPT, HWKEYAES_UKEY, hash, SIGN_SZ);
129
130 for (of = 0; of < N_OF; of++)
131 if (memcmp(hash, of_sha[of], SIGN_SZ) == 0)
132 break;
133
134 return of;
135}
136
137#ifdef DUALBOOT_UNINSTALL
138/* Uninstall RB bootloader */
139void main(void)
140{
141 struct Im3Info *hinfo;
142 void *fw_addr;
143 uint16_t *status;
144 unsigned bl_nor_sz;
145
146 usec_timer_init();
147 piezo_seq(alive);
148 spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
149
150 hinfo = (struct Im3Info*)OF_LOADADDR;
151 fw_addr = (void*)hinfo + IM3HDR_SZ;
152
153 if (im3_read(NORBOOT_OFF, hinfo, NULL) != 0) {
154 status = sad;
155 goto bye; /* no FW found */
156 }
157
158 if (identify_fw(hinfo) != FW_RB) {
159 status = happy;
160 goto bye; /* RB bootloader not installed, nothing to do */
161 }
162
163 /* if found FW is a RB bootloader, OF should start just behind it */
164 bl_nor_sz = im3_nor_sz(hinfo);
165 if ((im3_read(NORBOOT_OFF + bl_nor_sz, hinfo, fw_addr) != 0)
166 || (identify_fw(hinfo) == FW_RB)) {
167 status = sad;
168 goto bye; /* OF not found */
169 }
170
171 /* decrypted OF correctly loaded, encrypt it before restoration */
172 im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
173
174 /* restore OF to it's original place */
175 if (!im3_write(NORBOOT_OFF, hinfo)) {
176 status = fatal;
177 goto bye; /* corrupted NOR, use iTunes to restore */
178 }
179
180 /* erase freed NOR blocks */
181 bootflash_init(SPI_PORT);
182 bootflash_erase_blocks(SPI_PORT,
183 (NORBOOT_OFF + im3_nor_sz(hinfo)) >> 12, bl_nor_sz >> 12);
184 bootflash_close(SPI_PORT);
185
186 status = happy;
187
188bye:
189 /* minimum time between the initial and the final beeps */
190 while (USEC_TIMER < 2000000);
191 piezo_seq(status);
192 WDTCON = 0x100000; /* WDT reset */
193 while (1);
194}
195
196#else
197/* Install RB bootloader */
198struct Im3Info bl_hinfo __attribute__((section(".im3info.data"))) =
199{
200 .ident = IM3_IDENT,
201 .version = IM3_VERSION,
202 .enc_type = 2,
203};
204
205static uint32_t get_uint32le(unsigned char *p)
206{
207 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
208}
209
210void main(void)
211{
212 uint16_t *status = happy;
213 int single_boot;
214 struct Im3Info *hinfo;
215 void *fw_addr;
216 unsigned bl_nor_sz;
217
218 usec_timer_init();
219 piezo_seq(alive);
220 spi_clkdiv(SPI_PORT, 4); /* SPI clock = 27/5 MHz. */
221
222 /* check for single boot installation, is is configured when
223 mks5lboot.exe builds the .dfu image */
224 single_boot = bl_hinfo.info_sign[0];
225
226 /* sign RB bootloader (data and header), but don't encrypt it,
227 use current decrypted image for faster load */
228 im3_sign(HWKEYAES_UKEY, (void*)&bl_hinfo + IM3HDR_SZ,
229 get_uint32le(bl_hinfo.data_sz), bl_hinfo.u.enc12.data_sign);
230 im3_sign(HWKEYAES_UKEY, &bl_hinfo, IM3INFOSIGN_SZ, bl_hinfo.info_sign);
231
232 if (single_boot) {
233 if (!im3_write(NORBOOT_OFF, &bl_hinfo))
234 status = sad;
235 goto bye;
236 }
237
238 hinfo = (struct Im3Info*)OF_LOADADDR;
239 fw_addr = (void*)hinfo + IM3HDR_SZ;
240
241 if (im3_read(NORBOOT_OFF, hinfo, fw_addr) != 0) {
242 status = sad;
243 goto bye; /* no FW found */
244 }
245
246 if (identify_fw(hinfo) == FW_RB) {
247 /* FW found, but not OF, assume it is a RB bootloader,
248 already decrypted OF should be located just behind */
249 int nor_offset = NORBOOT_OFF + im3_nor_sz(hinfo);
250 if ((im3_read(nor_offset, hinfo, fw_addr) != 0)
251 || (identify_fw(hinfo) == FW_RB)) {
252 status = sad;
253 goto bye; /* OF not found, use iTunes to restore */
254 }
255 }
256
257 bl_nor_sz = im3_nor_sz(&bl_hinfo);
258 /* safety check - verify we are not going to overwrite useful data */
259 if (flsh_get_unused() < bl_nor_sz) {
260 status = sad2;
261 goto bye; /* no space if flash, use iTunes to restore */
262 }
263
264 /* write decrypted OF and RB bootloader, if any of these fails we
265 will try to retore OF to its original place */
266 if (!im3_write(NORBOOT_OFF + bl_nor_sz, hinfo)
267 || !im3_write(NORBOOT_OFF, &bl_hinfo)) {
268 im3_crypt(HWKEYAES_ENCRYPT, hinfo, fw_addr);
269 if (!im3_write(NORBOOT_OFF, hinfo)) {
270 /* corrupted NOR, use iTunes to restore */
271 status = fatal;
272 }
273 else {
274 /* RB bootloader not succesfully intalled, but device
275 was restored and should be working as before */
276 status = sad;
277 }
278 }
279
280bye:
281 /* minimum time between the initial and the final beeps */
282 while (USEC_TIMER < 2000000);
283 piezo_seq(status);
284 WDTCON = 0x100000; /* WDT reset */
285 while (1);
286}
287#endif /* DUALBOOT_UNINSTALL */
diff --git a/utils/mks5lboot/dualboot/dualboot.lds b/utils/mks5lboot/dualboot/dualboot.lds
new file mode 100644
index 0000000000..cb92e2a286
--- /dev/null
+++ b/utils/mks5lboot/dualboot/dualboot.lds
@@ -0,0 +1,59 @@
1#define ASM
2#include "config.h"
3#include "cpu.h"
4#include "mks5lboot.h"
5
6ENTRY(_start)
7OUTPUT_FORMAT(elf32-littlearm)
8OUTPUT_ARCH(arm)
9
10#define BIN_ORIG DFU_LOADADDR + BIN_OFFSET
11#define BIN_SIZE MAX_PAYLOAD
12
13MEMORY
14{
15 IRAM : ORIGIN = BIN_ORIG, LENGTH = BIN_SIZE
16}
17
18SECTIONS
19{
20 .text : {
21 *(.init.text*)
22 *(.text*)
23 *(.icode*)
24 . = ALIGN(4);
25 } > IRAM
26
27 /* include initialized BSS (if any) into DFU image */
28 .bss : {
29 *(.bss*)
30 *(.ibss*)
31 *(COMMON)
32 . = ALIGN(4);
33 } > IRAM
34
35#if 1
36 /* reuse pwnage as stack, 0x30c bytes available */
37 _exception_stack = BIN_ORIG;
38 _supervisor_stack = _exception_stack;
39#else
40 /* include stack into DFU image */
41 .stack : {
42 . += 0x400;
43 _supervisor_stack = .;
44 . += 0x200;
45 _exception_stack = .;
46 } > IRAM
47#endif
48
49 .data : {
50 *(.data*)
51 *(.rodata*)
52 *(.idata*)
53 *(.irodata*)
54 /* place bootloader IM3 header at the end, mkdfu
55 will concatenate the bootloader binary here */
56 . = ALIGN(16);
57 *(.im3info.data*)
58 } > IRAM
59}
diff --git a/utils/mks5lboot/dualboot/init.S b/utils/mks5lboot/dualboot/init.S
new file mode 100644
index 0000000000..bd049515f4
--- /dev/null
+++ b/utils/mks5lboot/dualboot/init.S
@@ -0,0 +1,43 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:
9 *
10 * Copyright © 2009 Michael Sparmann
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22 .section .init.text, "ax", %progbits
23 .global _start
24
25_start:
26 mov r0, #0xD7
27 msr CPSR_c, r0 @ Abort mode, IRQs/FIQs disabled
28 ldr sp, =_exception_stack
29
30 mov r0, #0xDB
31 msr CPSR_c, r0 @ Undefined Instruction mode, IRQs/FIQs disabled
32 ldr sp, =_exception_stack
33
34 mov r0, #0xD3
35 msr CPSR_c, r0 @ Supervisor mode, IRQs/FIQs disabled
36 ldr sp, =_supervisor_stack
37
38 MOV R0, #0x00050000
39 ORR R0, #0x00000078
40 MCR p15, 0, R0, c1, c0, 0 @ Get rid of some CPU "features" likely to cause trouble
41
42 bl main
43 .ltorg