From 346423c040fe4ac31dae7c1afcb1d853cc80635c Mon Sep 17 00:00:00 2001 From: Cástor Muñoz Date: Thu, 4 Feb 2016 23:05:17 +0100 Subject: 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 --- rbutil/mks5lboot/dualboot/.gitignore | 3 + rbutil/mks5lboot/dualboot/Makefile | 97 +++++++++++ rbutil/mks5lboot/dualboot/autoconf.h | 74 +++++++++ rbutil/mks5lboot/dualboot/bin2c.c | 140 ++++++++++++++++ rbutil/mks5lboot/dualboot/dualboot.c | 287 +++++++++++++++++++++++++++++++++ rbutil/mks5lboot/dualboot/dualboot.lds | 59 +++++++ rbutil/mks5lboot/dualboot/init.S | 43 +++++ 7 files changed, 703 insertions(+) create mode 100644 rbutil/mks5lboot/dualboot/.gitignore create mode 100644 rbutil/mks5lboot/dualboot/Makefile create mode 100644 rbutil/mks5lboot/dualboot/autoconf.h create mode 100644 rbutil/mks5lboot/dualboot/bin2c.c create mode 100644 rbutil/mks5lboot/dualboot/dualboot.c create mode 100644 rbutil/mks5lboot/dualboot/dualboot.lds create mode 100644 rbutil/mks5lboot/dualboot/init.S (limited to 'rbutil/mks5lboot/dualboot') diff --git a/rbutil/mks5lboot/dualboot/.gitignore b/rbutil/mks5lboot/dualboot/.gitignore new file mode 100644 index 0000000000..34c53b3c82 --- /dev/null +++ b/rbutil/mks5lboot/dualboot/.gitignore @@ -0,0 +1,3 @@ +build/ +*.arm-bin +bin2c diff --git a/rbutil/mks5lboot/dualboot/Makefile b/rbutil/mks5lboot/dualboot/Makefile new file mode 100644 index 0000000000..51ce816ca0 --- /dev/null +++ b/rbutil/mks5lboot/dualboot/Makefile @@ -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) diff --git a/rbutil/mks5lboot/dualboot/autoconf.h b/rbutil/mks5lboot/dualboot/autoconf.h new file mode 100644 index 0000000000..cd5b3f9aeb --- /dev/null +++ b/rbutil/mks5lboot/dualboot/autoconf.h @@ -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 */ diff --git a/rbutil/mks5lboot/dualboot/bin2c.c b/rbutil/mks5lboot/dualboot/bin2c.c new file mode 100644 index 0000000000..4d74a19696 --- /dev/null +++ b/rbutil/mks5lboot/dualboot/bin2c.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#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 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; +} diff --git a/rbutil/mks5lboot/dualboot/dualboot.c b/rbutil/mks5lboot/dualboot/dualboot.c new file mode 100644 index 0000000000..b8167ec124 --- /dev/null +++ b/rbutil/mks5lboot/dualboot/dualboot.c @@ -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 +#include + +#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 */ diff --git a/rbutil/mks5lboot/dualboot/dualboot.lds b/rbutil/mks5lboot/dualboot/dualboot.lds new file mode 100644 index 0000000000..cb92e2a286 --- /dev/null +++ b/rbutil/mks5lboot/dualboot/dualboot.lds @@ -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 +} diff --git a/rbutil/mks5lboot/dualboot/init.S b/rbutil/mks5lboot/dualboot/init.S new file mode 100644 index 0000000000..bd049515f4 --- /dev/null +++ b/rbutil/mks5lboot/dualboot/init.S @@ -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 -- cgit v1.2.3