Revision 1388380fd906a25491ca7704b99aacf59ee68849 authored by a1ex on 11 December 2011, 16:50:59 UTC, committed by a1ex on 11 December 2011, 16:50:59 UTC
1 parent 10d522b
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 "arm-mcr.h"
asm(
".text\n"
".globl _start\n"
"_start:\n"
" b 1f\n"
".ascii \"gaonisoy\"\n" // 0x124, 128
"1:\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"
" ldr sp, =0x1900\n" // 0x130
" mov fp, #0\n"
" b cstart\n"
);
/** Include the relocatable shim code */
extern uint8_t blob_start;
extern uint8_t blob_end;
asm(
".text\n"
".align 12\n" // 2^12 == 4096 bytes
".globl blob_start\n"
"blob_start:\n"
".incbin \"magiclantern.bin\"\n" //
".align 12\n"
"blob_end:\n"
".globl blob_end\n"
);
/** Determine the in-memory offset of the code.
* If we are autobooting, there is no offset (code is loaded at
* 0x800000). If we are loaded via a firmware file then there
* is a 0x120 byte header infront of our code.
*
* Note that mov r0, pc puts pc+8 into r0.
*/
static int
__attribute__((noinline))
find_offset( void )
{
uintptr_t pc;
asm __volatile__ (
"mov %0, %%pc"
: "=&r"(pc)
);
return pc - 8 - (uintptr_t) find_offset;
}
void
__attribute__((noreturn))
cstart( void )
{
#if 0
set_i_tcm( 0x40000006 );
set_control_reg( read_control_reg() | 0x10000 );
// Install the memory regions
setup_memory_region( 0, 0x0000003F );
setup_memory_region( 1, 0x0000003D );
setup_memory_region( 2, 0xE0000039 );
setup_memory_region( 3, 0xC0000039 );
setup_memory_region( 4, 0xFF80002D );
setup_memory_region( 5, 0x00000039 );
setup_memory_region( 6, 0xF780002D );
setup_memory_region( 7, 0x00000000 );
set_d_cache_regions( 0x70 );
set_i_cache_regions( 0x70 );
set_d_buffer_regions( 0x70 );
set_d_rw_regions( 0x3FFF );
set_i_rw_regions( 0x3FFF );
set_control_reg( read_control_reg() | 0xC000107D );
select_normal_vectors();
#endif
// Copy the copy-and-restart blob somewhere
// there is a bug in that we are 0x120 bytes off from
// where we should be, so we must offset the blob start.
ssize_t offset = find_offset();
blob_memcpy(
(void*) RESTARTSTART,
&blob_start + offset,
&blob_end + offset
);
clean_d_cache();
flush_caches();
// Jump into the newly relocated code
void __attribute__((noreturn))(*copy_and_restart)(int)
= (void*) RESTARTSTART;
void __attribute__((noreturn))(*firmware_start)(void)
= (void*) ROMBASEADDR;
if( 1 )
copy_and_restart(offset);
else
firmware_start();
// Unreachable
while(1)
;
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...