change main.c for relocatable reGNUal

This commit is contained in:
NIIBE Yutaka
2013-03-09 10:04:36 +09:00
parent b6970672ac
commit c90358dd5a

View File

@@ -1,7 +1,7 @@
/*
* 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>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -321,6 +321,23 @@ led_blink (int 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.
@@ -332,6 +349,7 @@ int
main (int argc, char *argv[])
{
unsigned int count = 0;
uint32_t entry;
(void)argc;
(void)argv;
@@ -438,6 +456,7 @@ main (int argc, char *argv[])
port_disable ();
/* Set vector */
SCB->VTOR = (uint32_t)&_regnual_start;
entry = calculate_regnual_entry_address (&_regnual_start);
#ifdef DFU_SUPPORT
#define FLASH_SYS_START_ADDR 0x08000000
#define FLASH_SYS_END_ADDR (0x08000000+0x1000)
@@ -456,12 +475,12 @@ main (int argc, char *argv[])
flash_write (FLASH_SYS_START_ADDR, &_sys, 0x1000);
/* Leave Gnuk to exec reGNUal */
(*func) (*((void (**)(void))(&_regnual_start+4)));
(*func) ((void (*)(void))entry);
for (;;);
}
#else
/* Leave Gnuk to exec reGNUal */
flash_erase_all_and_exec (*((void (**)(void))(&_regnual_start+4)));
flash_erase_all_and_exec ((void (*)(void))entry);
#endif
/* Never reached */