change main.c for relocatable reGNUal
This commit is contained in:
25
src/main.c
25
src/main.c
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* main.c - main routine of Gnuk
|
* main.c - main routine of Gnuk
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
|
* Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
|
||||||
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
@@ -321,6 +321,23 @@ led_blink (int spec)
|
|||||||
chEvtSignalFlags (main_thread, spec);
|
chEvtSignalFlags (main_thread, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In Gnuk 1.0.[12], reGNUal was not relocatable.
|
||||||
|
* Now, it's relocatable, but we need to calculate its entry address
|
||||||
|
* based on it's pre-defined address.
|
||||||
|
*/
|
||||||
|
#define REGNUAL_START_ADDRESS_COMPATIBLE 0x20001400
|
||||||
|
static uint32_t
|
||||||
|
calculate_regnual_entry_address (const uint8_t *addr)
|
||||||
|
{
|
||||||
|
const uint8_t *p = addr + 4;
|
||||||
|
uint32_t v = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24);
|
||||||
|
|
||||||
|
v -= REGNUAL_START_ADDRESS_COMPATIBLE;
|
||||||
|
v += (uint32_t)addr;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Entry point.
|
* Entry point.
|
||||||
@@ -332,6 +349,7 @@ int
|
|||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
uint32_t entry;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
@@ -438,6 +456,7 @@ main (int argc, char *argv[])
|
|||||||
port_disable ();
|
port_disable ();
|
||||||
/* Set vector */
|
/* Set vector */
|
||||||
SCB->VTOR = (uint32_t)&_regnual_start;
|
SCB->VTOR = (uint32_t)&_regnual_start;
|
||||||
|
entry = calculate_regnual_entry_address (&_regnual_start);
|
||||||
#ifdef DFU_SUPPORT
|
#ifdef DFU_SUPPORT
|
||||||
#define FLASH_SYS_START_ADDR 0x08000000
|
#define FLASH_SYS_START_ADDR 0x08000000
|
||||||
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
|
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
|
||||||
@@ -456,12 +475,12 @@ main (int argc, char *argv[])
|
|||||||
flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
|
flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
|
||||||
|
|
||||||
/* Leave Gnuk to exec reGNUal */
|
/* Leave Gnuk to exec reGNUal */
|
||||||
(*func) (*((void (**)(void))(&_regnual_start+4)));
|
(*func) ((void (*)(void))entry);
|
||||||
for (;;);
|
for (;;);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Leave Gnuk to exec reGNUal */
|
/* Leave Gnuk to exec reGNUal */
|
||||||
flash_erase_all_and_exec (*((void (**)(void))(&_regnual_start+4)));
|
flash_erase_all_and_exec ((void (*)(void))entry);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Never reached */
|
/* Never reached */
|
||||||
|
|||||||
Reference in New Issue
Block a user