Revision 359b966a5860077c4c5d451f7d23efd2f9c72069 authored by Giovanni Condello on 29 August 2013, 15:13:52 UTC, committed by Giovanni Condello on 29 August 2013, 15:13:52 UTC
1 parent 2a4e3eb
reboot.c
/** \file
* Reboot into the hacked firmware.
*
* This program is very simple: attempt to reboot into the normal
* firmware RAM image after startup.
*/
/*
* Copyright (C) 2009 Trammell Hudson <hudson+ml@osresearch.net>
*
* 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 program is distributed in the hope that 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, write to the
* Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "compiler.h"
#include "consts.h"
#include "fw-signature.h"
#ifdef __ARM__
asm(
".text\n"
".globl _start\n"
"_start:\n"
/* if used in a .fir file, there is a 0x120 byte address offset.
so cut the first 0x120 bytes off autoexec.bin before embedding into .fir
*/
"B skip_fir_header\n"
".incbin \"version.bin\"\n" // this must have exactly 0x11C (284) bytes
"skip_fir_header:\n"
"MRS R0, CPSR\n"
"BIC R0, R0, #0x3F\n" // Clear I,F,T
"ORR R0, R0, #0xD3\n" // Set I,T, M=10011 == supervisor
"MSR CPSR, R0\n"
"B cstart\n"
);
/** Include the relocatable shim code */
extern uint8_t blob_start;
extern uint8_t blob_end;
asm(
".text\n"
".globl blob_start\n"
"blob_start:\n"
".incbin \"magiclantern.bin\"\n"
"blob_end:\n"
".globl blob_end\n"
);
#endif /* __ARM__ */
#if SHOULD_CHECK_SIG
static void busy_wait(int n)
{
int i,j;
static volatile int k = 0;
for (i = 0; i < n; i++)
for (j = 0; j < 100000; j++)
k++;
}
static void blink(int n)
{
while (1)
{
#if defined(CARD_LED_ADDRESS) && defined(LEDON) && defined(LEDOFF)
*(volatile int*) (CARD_LED_ADDRESS) = (LEDON);
busy_wait(n);
*(volatile int*)(CARD_LED_ADDRESS) = (LEDOFF);
busy_wait(n);
#endif
}
}
static void fail()
{
blink(50);
}
#endif
extern int compute_signature(int* start, int num);
void
__attribute__((noreturn))
cstart( void )
{
#if SHOULD_CHECK_SIG
int s = compute_signature((int*)SIG_START, SIG_LEN);
#ifdef CONFIG_5D3
if (s != (int)SIG_5D3_113)
fail();
#endif
#ifdef CONFIG_EOSM
if (s != (int)SIG_EOSM_106)
fail();
#endif
#if defined(CONFIG_7D)
if (s != (int)SIG_7D_203)
fail();
#endif
#if defined(CONFIG_7D_MASTER)
if (s != (int)SIG_7D_MASTER_203)
fail();
#endif
#ifdef CONFIG_6D
if (s != (int)SIG_6D_113)
fail();
#endif
#ifdef CONFIG_650D
if (s != (int)SIG_650D_104)
fail();
#endif
#ifdef CONFIG_700D
if (s != (int)SIG_700D_111)
fail();
#endif
//TODO: Add CONFIG_100D signature check
#endif
#ifdef __ARM__
/* turn on the LED as soon as autoexec.bin is loaded (may happen without powering on) */
#if defined(CONFIG_40D) || defined(CONFIG_5DC)
*(volatile int*) (LEDBLUE) = (LEDON);
*(volatile int*) (LEDRED) = (LEDON); // do we need the red too ?
#elif defined(CARD_LED_ADDRESS) && defined(LEDON) // A more portable way, hopefully
*(volatile int*) (CARD_LED_ADDRESS) = (LEDON);
#endif
#if defined(CONFIG_7D)
*(volatile int*)0xC0A00024 = 0x80000010; // send SSTAT for master processor, so it is in right state for rebooting
#endif
blob_memcpy(
(void*) RESTARTSTART,
&blob_start,
&blob_end
);
clean_d_cache();
flush_caches();
/* Jump into the newly relocated code
Q: Why target/compiler-specific attribute long_call?
A: If in any case the base address passed to linker (-Ttext 0x40800000) doesnt fit because we
e.g. run at the cached address 0x00800000, we wont risk jumping into nirvana here.
This will not help when the offset is oddly misplaced, like the 0x120 fir offset. Why?
Because the code above (blob_memcpy) already made totally wrong assumptions about memory addresses.
*/
void __attribute__((long_call)) (*copy_and_run_ml)() = (void*) RESTARTSTART;
#endif /* __ARM__ */
copy_and_run_ml();
// Unreachable
while(1)
;
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...