X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Far71xx%2Ffiles%2Farch%2Fmips%2Fath79%2Frouterboot.c;fp=target%2Flinux%2Far71xx%2Ffiles%2Farch%2Fmips%2Fath79%2Frouterboot.c;h=3c6f9aaeb371133087e5b5f9a5848e7348142aeb;hb=ccabe4a1b447e9bc7efd0a7eb19e843bc46702b1;hp=0000000000000000000000000000000000000000;hpb=2323120d5eacf1b1b25e1419cebe895e2dd0288a;p=openwrt%2Fopenwrt.git diff --git a/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c new file mode 100644 index 0000000000..3c6f9aaeb3 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/routerboot.c @@ -0,0 +1,100 @@ +/* + * RouterBoot helper routines + * + * Copyright (C) 2012 Gabor Juhos + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + +#include +#include +#include + +#include "routerboot.h" + +static u32 get_u32(void *buf) +{ + u8 *p = buf; + + return ((u32) p[3] + ((u32) p[2] << 8) + ((u32) p[1] << 16) + + ((u32) p[0] << 24)); +} + +static u16 get_u16(void *buf) +{ + u8 *p = buf; + + return (u16) p[1] + ((u16) p[0] << 8); +} + +__init int +routerboot_find_tag(u8 *buf, unsigned int buflen, u16 tag_id, + u8 **tag_data, u16 *tag_len) +{ + uint32_t magic; + int ret; + + if (buflen < 4) + return -EINVAL; + + magic = get_u32(buf); + switch (magic) { + case RB_MAGIC_HARD: + /* skip magic value */ + buf += 4; + buflen -= 4; + break; + + case RB_MAGIC_SOFT: + if (buflen < 8) + return -EINVAL; + + /* skip magic and CRC value */ + buf += 8; + buflen -= 8; + + break; + + default: + return -EINVAL; + } + + ret = -ENOENT; + while (buflen > 2) { + u16 id; + u16 len; + + len = get_u16(buf); + buf += 2; + buflen -= 2; + + if (buflen < 2) + break; + + id = get_u16(buf); + buf += 2; + buflen -= 2; + + if (id == RB_ID_TERMINATOR) + break; + + if (buflen < len) + break; + + if (id == tag_id) { + if (tag_len) + *tag_len = len; + if (tag_data) + *tag_data = buf; + ret = 0; + break; + } + + buf += len; + buflen -= len; + } + + return ret; +}