Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
magic-lantern
magic-lantern
Commits
f7bdec492a8d
Commit
82fe3c86
authored
Jun 28, 2011
by
a1ex
Browse files
Added missing boot-hack.c
--HG-- branch : unified
parent
f474d27676af
Changes
1
Hide whitespace changes
Inline
Side-by-side
boot-hack.c
0 → 100644
View file @
f7bdec49
/** \file
* Code to run on the 5D once it has been relocated.
*
* This has been updated to work with the 2.0.3 firmware.
* IT DOES NOT WORK WITH 1.1.0 NOR 1.0.7 ANY MORE!
*/
/*
* 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 "dryos.h"
#include "config.h"
#include "version.h"
#include "bmp.h"
#include "menu.h"
#include "version.h"
#include "property.h"
#include "consts.h"
/** If CONFIG_EARLY_PORT is defined, only a few things will be enabled */
#undef CONFIG_EARLY_PORT
/** These are called when new tasks are created */
void
my_task_dispatch_hook
(
struct
context
**
);
void
my_init_task
(
void
);
void
my_bzero
(
uint8_t
*
base
,
uint32_t
size
);
/** This just goes into the bss */
#define RELOCSIZE 0x10000
static
uint8_t
_reloc
[
RELOCSIZE
];
#define RELOCADDR ((uintptr_t) _reloc)
/** Translate a firmware address into a relocated address */
#define INSTR( addr ) ( *(uint32_t*)( (addr) - ROMBASEADDR + RELOCADDR ) )
/** Fix a branch instruction in the relocated firmware image */
#define FIXUP_BRANCH( rom_addr, dest_addr ) \
INSTR( rom_addr ) = BL_INSTR( &INSTR( rom_addr ), (dest_addr) )
/** Was this an autoboot or firmware file load? */
int
autoboot_loaded
;
/** Specified by the linker */
extern
uint32_t
_bss_start
[],
_bss_end
[];
static
inline
void
zero_bss
(
void
)
{
uint32_t
*
bss
=
_bss_start
;
while
(
bss
<
_bss_end
)
*
(
bss
++
)
=
0
;
}
void
__attribute__
((
noreturn
,
noinline
,
naked
))
copy_and_restart
(
int
offset
)
{
zero_bss
();
// Set the flag if this was an autoboot load
autoboot_loaded
=
(
offset
==
0
);
// Copy the firmware to somewhere safe in memory
const
uint8_t
*
const
firmware_start
=
(
void
*
)
ROMBASEADDR
;
const
uint32_t
firmware_len
=
RELOCSIZE
;
uint32_t
*
const
new_image
=
(
void
*
)
RELOCADDR
;
blob_memcpy
(
new_image
,
firmware_start
,
firmware_start
+
firmware_len
);
/*
* in entry2() (0xff010134) make this change to
* return to our code before calling cstart().
* This should be a "BL cstart" instruction.
*/
INSTR
(
HIJACK_INSTR_BL_CSTART
)
=
RET_INSTR
;
/*
* in cstart() (0xff010ff4) make these changes:
* calls bzero(), then loads bs_end and calls
* create_init_task
*/
// Reserve memory after the BSS for our application
INSTR
(
HIJACK_INSTR_BSS_END
)
=
(
uintptr_t
)
_bss_end
;
// Fix the calls to bzero32() and create_init_task()
FIXUP_BRANCH
(
HIJACK_FIXBR_BZERO32
,
bzero32
);
FIXUP_BRANCH
(
HIJACK_FIXBR_CREATE_ITASK
,
create_init_task
);
// Set our init task to run instead of the firmware one
INSTR
(
HIJACK_INSTR_MY_ITASK
)
=
(
uint32_t
)
my_init_task
;
// Make sure that our self-modifying code clears the cache
clean_d_cache
();
flush_caches
();
// We enter after the signature, avoiding the
// relocation jump that is at the head of the data
thunk
reloc_entry
=
(
thunk
)(
RELOCADDR
+
0xC
);
reloc_entry
();
/*
* We're back!
* The RAM copy of the firmware startup has:
* 1. Poked the DMA engine with what ever it does
* 2. Copied the rw_data segment to 0x1900 through 0x20740
* 3. Zeroed the BSS from 0x20740 through 0x47550
* 4. Copied the interrupt handlers to 0x0
* 5. Copied irq 4 to 0x480.
* 6. Installed the stack pointers for CPSR mode D2 and D3
* (we are still in D3, with a %sp of 0x1000)
* 7. Returned to us.
*
* Now is our chance to fix any data segment things, or
* install our own handlers.
*/
#ifndef CONFIG_EARLY_PORT
// Install our task creation hooks
task_dispatch_hook
=
my_task_dispatch_hook
;
#endif
// This will jump into the RAM version of the firmware,
// but the last branch instruction at the end of this
// has been modified to jump into the ROM version
// instead.
void
(
*
ram_cstart
)(
void
)
=
(
void
*
)
&
INSTR
(
cstart
);
ram_cstart
();
// Unreachable
while
(
1
)
;
}
#ifndef CONFIG_EARLY_PORT
void
null_task
(
void
)
{
DebugMsg
(
DM_SYS
,
3
,
"%s created (and exiting)"
,
__func__
);
return
;
}
/**
* Called by DryOS when it is dispatching (or creating?)
* a new task.
*/
void
my_task_dispatch_hook
(
struct
context
**
context
)
{
if
(
!
context
)
return
;
// Do nothing unless a new task is starting via the trampoile
if
(
(
*
context
)
->
pc
!=
(
uint32_t
)
task_trampoline
)
return
;
// Determine the task address
struct
task
*
const
task
=
*
(
struct
task
**
)
HIJACK_TASK_ADDR
;
thunk
entry
=
(
thunk
)
task
->
entry
;
// Search the task_mappings array for a matching entry point
extern
struct
task_mapping
_task_overrides_start
[];
extern
struct
task_mapping
_task_overrides_end
[];
const
struct
task_mapping
*
mapping
=
_task_overrides_start
;
for
(
;
mapping
<
_task_overrides_end
;
mapping
++
)
{
thunk
original_entry
=
mapping
->
orig
;
if
(
original_entry
!=
entry
)
continue
;
/* -- can't call debugmsg from this context */
#if 0
DebugMsg( DM_SYS, 3, "***** Replacing task %x with %x",
original_entry,
mapping->replacement
);
#endif
task
->
entry
=
mapping
->
replacement
;
break
;
}
}
/** First task after a fresh rebuild.
*
* Try to dump the debug log after ten seconds.
* This requires the create_task(), dmstart(), msleep() and dumpf()
* routines to have been found.
*/
void
my_dump_task
(
void
)
{
dmstart
();
msleep
(
10000
);
dispcheck
();
dumpf
();
dmstop
();
}
struct
config
*
global_config
;
static
volatile
int
init_funcs_done
;
static
void
call_init_funcs
(
void
*
priv
)
{
// Call all of the init functions
extern
struct
task_create
_init_funcs_start
[];
extern
struct
task_create
_init_funcs_end
[];
struct
task_create
*
init_func
=
_init_funcs_start
;
for
(
;
init_func
<
_init_funcs_end
;
init_func
++
)
{
DebugMsg
(
DM_MAGIC
,
3
,
"Calling init_func %s (%x)"
,
init_func
->
name
,
(
unsigned
)
init_func
->
entry
);
thunk
entry
=
(
thunk
)
init_func
->
entry
;
entry
();
}
}
#endif // !CONFIG_EARLY_PORT
static
void
nop
(
void
)
{
}
void
menu_init
(
void
)
__attribute__
((
weak
,
alias
(
"nop"
)));
void
debug_init
(
void
)
__attribute__
((
weak
,
alias
(
"nop"
)));
int
magic_off
=
0
;
int
magic_is_off
()
{
return
magic_off
;
}
int
_hold_your_horses
=
1
;
// only after this task finished, the others are started
void
init_task_read_config
()
{
show_logo
();
display_clock
();
config_parse_file
(
"B:/magic.cfg"
);
debug_init_stuff
();
_hold_your_horses
=
0
;
}
void
hold_your_horses
(
int
showlogo
)
{
while
(
_hold_your_horses
)
{
msleep
(
500
);
}
}
/** Initial task setup.
*
* This is called instead of the task at 0xFF811DBC.
* It does all of the stuff to bring up the debug manager,
* the terminal drivers, stdio, stdlib and armlib.
*/
void
my_init_task
(
void
)
{
// Call their init task
init_task
();
#ifndef CONFIG_EARLY_PORT
// Overwrite the PTPCOM message
dm_names
[
DM_MAGIC
]
=
"[MAGIC] "
;
//~ dmstart(); // already called by firmware?
DebugMsg
(
DM_MAGIC
,
3
,
"Magic Lantern %s (%s)"
,
build_version
,
build_id
);
DebugMsg
(
DM_MAGIC
,
3
,
"Built on %s by %s"
,
build_date
,
build_user
);
#endif
// Re-write the version string.
// Don't use strcpy() so that this can be done
// before strcpy() or memcpy() are located.
extern
char
additional_version
[];
additional_version
[
0
]
=
'-'
;
additional_version
[
1
]
=
'm'
;
additional_version
[
2
]
=
'l'
;
additional_version
[
3
]
=
'-'
;
additional_version
[
4
]
=
build_version
[
0
];
additional_version
[
5
]
=
build_version
[
1
];
additional_version
[
6
]
=
build_version
[
2
];
additional_version
[
7
]
=
build_version
[
3
];
additional_version
[
8
]
=
build_version
[
4
];
additional_version
[
9
]
=
build_version
[
5
];
additional_version
[
10
]
=
build_version
[
6
];
additional_version
[
11
]
=
build_version
[
7
];
additional_version
[
12
]
=
build_version
[
8
];
additional_version
[
13
]
=
'\0'
;
#ifndef CONFIG_EARLY_PORT
msleep
(
1500
);
magic_off
=
FOCUS_CONFIRMATION_AF_PRESSED
?
1
:
0
;
if
(
magic_off
)
{
bmp_printf
(
FONT_LARGE
,
0
,
0
,
"Magic OFF"
);
additional_version
[
0
]
=
'-'
;
additional_version
[
1
]
=
'm'
;
additional_version
[
2
]
=
'l'
;
additional_version
[
3
]
=
'-'
;
additional_version
[
4
]
=
'o'
;
additional_version
[
5
]
=
'f'
;
additional_version
[
6
]
=
'f'
;
additional_version
[
7
]
=
'\0'
;
return
;
}
BMP_SEM
(
// block redraw events
msleep
(
1000
);
menu_init
();
debug_init
();
call_init_funcs
(
0
);
/* bmp_printf( FONT_MED, 0, 40,
"Magic Lantern v.%s (%s)\n"
"Built on %s by %s\n",
build_version,
build_id,
build_date,
build_user
);*/
// this is better in a separate task (not sure why, but causes instability if called right from here)
// let's try not to open files from here
task_create
(
"config_init"
,
0x1e
,
0x1000
,
init_task_read_config
,
0
);
hold_your_horses
(
0
);
// Create all of our auto-create tasks
extern
struct
task_create
_tasks_start
[];
extern
struct
task_create
_tasks_end
[];
struct
task_create
*
task
=
_tasks_start
;
int
ml_tasks
=
0
;
for
(
;
task
<
_tasks_end
;
task
++
)
{
//~ DebugMsg( DM_MAGIC, 3,
//~ "Creating task %s(%d) pri=%02x flags=%08x",
//~ task->name,
//~ task->arg,
//~ task->priority,
//~ task->flags
//~ );
task_create
(
task
->
name
,
task
->
priority
,
task
->
flags
,
task
->
entry
,
task
->
arg
);
ml_tasks
++
;
}
//~ bmp_printf( FONT_MED, 0, 85,
//~ "Magic Lantern is up and running... %d tasks started.",
//~ ml_tasks
//~ );
msleep
(
500
);
)
// end BMP_SEM
redraw
();
//~ DebugMsg( DM_MAGIC, 3, "magic lantern init done" );
#endif // !CONFIG_EARLY_PORT
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment