1
0
mirror of git://projects.qi-hardware.com/antorcha.git synced 2024-11-01 11:28:26 +02:00
antorcha/fw/fw.c
Werner Almesberger 56476539cf fw/: addition of boot loader (WIP) and assorted cleanup and improvements
The boot loader currently uses the protocol switch intended for the
application. This makes it too big to fit in the very limiting
constraints the ATmega168 poses - and there's not even cryptographic
authentication yet. We'll have to dumb it down quite a bit.
2012-06-18 10:56:43 -03:00

134 lines
2.3 KiB
C

/*
* fw/fw.h - Firmware upload protocols
*
* Written 2012 by Werner Almesberger
* Copyright 2012 Werner Almesberger
*
* 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.
*/
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include "hash.h"
#include "flash.h"
#include "proto.h"
#include "dispatch.h"
#include "fw.h"
static const uint8_t unlock_secret[] = {
#include "unlock-secret.inc"
};
static void panic(void)
{
/* ??? */
}
/* ----- Unlocking --------------------------------------------------------- */
static bool unlocked = 0;
static bool unlock_failed;
static bool unlock_first(const uint8_t *payload)
{
hash_init();
hash_merge(unlock_secret, sizeof(unlock_secret));
hash_merge(payload, PAYLOAD);
unlocked = 0;
unlock_failed = 0;
return 1;
}
static bool unlock_more(uint8_t seq, uint8_t limit, const uint8_t *payload)
{
switch (seq) {
case 1:
hash_merge(payload, PAYLOAD);
hash_end();
break;
case 2:
if (!hash_eq(payload, PAYLOAD, 0))
unlock_failed = 1;
break;
case 3:
if (unlock_failed)
return 1;
if (hash_eq(payload, PAYLOAD, PAYLOAD))
unlocked = 1;
else
unlock_failed = 1;
break;
default:
return 0;
}
return 1;
}
static const struct handler unlock_proto = {
.type = UNLOCK,
.first = unlock_first,
.more = unlock_more,
};
/* ----- Firmware upload --------------------------------------------------- */
static bool fw_first(const uint8_t *payload)
{
// if (!unlocked)
// return 0;
hash_init();
hash_merge(payload, PAYLOAD);
flash_start(APP_ADDR);
flash_write(payload, PAYLOAD);
return 1;
}
static bool fw_more(uint8_t seq, uint8_t limit, const uint8_t *payload)
{
if (!flash_can_write(PAYLOAD))
return 0;
if (seq != limit) {
hash_merge(payload, PAYLOAD);
flash_write(payload, PAYLOAD);
return 1;
}
flash_end_write();
hash_end();
if (!hash_eq(payload, PAYLOAD, 0))
panic();
return 1;
}
static const struct handler fw_proto = {
.type = FIRMWARE,
.first = fw_first,
.more = fw_more,
};
/* ----- Protocol table ---------------------------------------------------- */
const struct handler *fw_protos[] = {
&unlock_proto,
&fw_proto,
NULL
};