https://bitbucket.org/hudson/magic-lantern
Raw File
Tip revision: 7e280c83205f602a1711323e343f071b95f51e3f authored by alex@thinkpad on 29 June 2012, 09:00:21 UTC
Fixed black level (was disabled in backend but enabled in menu)
Tip revision: 7e280c8
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)
        ;
}

back to top