diff options
author | Mantas Mikulėnas | 2016-07-13 13:46:54 +0300 |
---|---|---|
committer | Mantas Mikulėnas | 2016-07-13 13:51:06 +0300 |
commit | 25f22c2e7c5e3a3d92562be9c33d5d8bd07a87d2 (patch) | |
tree | 30a404efe4a45555e1a27c7ef886edcfb580bbd8 | |
parent | 55300862ca5e1569b76ff8636c90ba9a1cc3ae76 (diff) | |
download | aur-prism2-usb-firmware.tar.gz |
build srec2fw locally
-rw-r--r-- | .SRCINFO | 10 | ||||
-rw-r--r-- | PKGBUILD | 22 | ||||
-rw-r--r-- | srec2fw.1 | 27 | ||||
-rw-r--r-- | srec2fw.c | 253 |
4 files changed, 298 insertions, 14 deletions
@@ -1,13 +1,15 @@ # Generated by mksrcinfo v8 -# Wed Jul 13 10:45:59 UTC 2016 +# Wed Jul 13 10:49:10 UTC 2016 pkgbase = prism2-usb-firmware pkgver = 0.2.9 - pkgrel = 1 + pkgrel = 2 arch = x86_64 - source = http://ftp.bg.debian.org/debian/pool/contrib/l/linux-wlan-ng/prism2-usb-firmware-installer_0.2.9+dfsg-5_amd64.deb source = git://git.shaftnet.org/linux-wlan-ng.git - sha256sums = c0ea25167f45eaafb07c75c7b20d6cefacefcba57c17f8f98ca793804f843ea1 + source = srec2fw.c::http://anonscm.debian.org/viewvc/linux-wlan-ng/trunk/debian/srec2fw.c?revision=200&view=co + source = srec2fw.1::http://anonscm.debian.org/viewvc/linux-wlan-ng/trunk/debian/srec2fw.1?revision=205&view=co sha256sums = SKIP + sha256sums = ef406281b2734be7b3e6ee837a0a859ff5920351ac47decdaaad9b4c2e705fc4 + sha256sums = 4ca9855fd8a15bf573ece48e839e9560fde93eab43c0dec76db27fcdb7258d50 pkgname = prism2-usb-firmware @@ -1,22 +1,24 @@ pkgname=prism2-usb-firmware pkgver=0.2.9 -pkgrel=1 +pkgrel=2 arch=(x86_64) -_deb="prism2-usb-firmware-installer_0.2.9+dfsg-5_amd64.deb" -source=("http://ftp.bg.debian.org/debian/pool/contrib/l/linux-wlan-ng/$_deb" - "git://git.shaftnet.org/linux-wlan-ng.git") -sha256sums=('c0ea25167f45eaafb07c75c7b20d6cefacefcba57c17f8f98ca793804f843ea1' - 'SKIP') +source=("git://git.shaftnet.org/linux-wlan-ng.git" + "srec2fw.c::http://anonscm.debian.org/viewvc/linux-wlan-ng/trunk/debian/srec2fw.c?revision=200&view=co" + "srec2fw.1::http://anonscm.debian.org/viewvc/linux-wlan-ng/trunk/debian/srec2fw.1?revision=205&view=co") +sha256sums=('SKIP' + 'ef406281b2734be7b3e6ee837a0a859ff5920351ac47decdaaad9b4c2e705fc4' + '4ca9855fd8a15bf573ece48e839e9560fde93eab43c0dec76db27fcdb7258d50') -prepare() { - bsdtar xf data.tar.gz +build() { + make srec2fw } package() { - install -Dm 755 usr/bin/srec2fw "$pkgdir/usr/bin/srec2fw" + install -Dm 755 srec2fw "$pkgdir/usr/bin/srec2fw" + install -Dm 644 srec2fw.1 "$pkgdir/usr/share/man/man1/srec2fw.1" for file in linux-wlan-ng/src/prism2/*.hex; do - usr/bin/srec2fw "$file" "${file/%.hex/.fw}" + ./srec2fw "$file" "${file/%.hex/.fw}" done for file in linux-wlan-ng/src/prism2/*.{hex,fw}; do diff --git a/srec2fw.1 b/srec2fw.1 new file mode 100644 index 000000000000..9c524f6ed41b --- /dev/null +++ b/srec2fw.1 @@ -0,0 +1,27 @@ +.\" +.\" This man page was written by Tormod Volden for Debian +.\" +.TH SREC2FW "1" +.SH NAME +srec2fw \- convert from SREC format to linux kernel format +.SH SYNOPSIS +.B srec2fw +[\fIOPTION\fR]... +[\fIsrc.hex\fR] [\fIdst.fw\fR] +.SH DESCRIPTION +Converts srec firmware files into binary representation for use by Linux kernel. +.PP +If the source file is `-' stdin will be read, and if destination file is `-' +the converted data will be written to stdout. +.TP +\fB\-w\fR +Source file uses wide records (16-bit length) +.SH "RETURN VALUE" +Returns 0 if no errors were encountered. +.SH EXAMPLES +.B srec2fw firmware.hex firmware.fw +.SH AUTHOR +Karl Relton <karllinuxtest.relton@ntlworld.com>, +David Woodhouse <dwmw2@infradead.org>, +Jan Harkes <jaharkes@cs.cmu.edu> + diff --git a/srec2fw.c b/srec2fw.c new file mode 100644 index 000000000000..2c881faa4073 --- /dev/null +++ b/srec2fw.c @@ -0,0 +1,253 @@ +/* + * Parser/loader for SREC formatted data. + * + * Adapted from ihex2fw.c + * + * Copyright © 2009 Karl Relton <karllinuxtest.relton@ntlworld.com> + * Copyright © 2008 David Woodhouse <dwmw2@infradead.org> + * Copyright © 2005 Jan Harkes <jaharkes@cs.cmu.edu> + * + * 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 <stdint.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <string.h> +#include <unistd.h> +#include <stdlib.h> +#define _GNU_SOURCE +#include <getopt.h> + +/* Define a special address for S7 start address records */ +#define S3ADDR_START (0xff400000UL) + + +struct srec_binrec { + struct srec_binrec *next; /* not part of the real data structure */ + uint32_t addr; + uint16_t len; + uint8_t data[]; +}; + +/** + * nybble/hex are little helpers to parse hexadecimal numbers to a byte value + **/ +static uint8_t nybble(const uint8_t n) +{ + if (n >= '0' && n <= '9') return n - '0'; + else if (n >= 'A' && n <= 'F') return n - ('A' - 10); + else if (n >= 'a' && n <= 'f') return n - ('a' - 10); + return 0; +} + +static uint8_t hex(const uint8_t *data, uint8_t *crc) +{ + uint8_t val = (nybble(data[0]) << 4) | nybble(data[1]); + *crc += val; + return val; +} + +static int process_srec(uint8_t *data, ssize_t size); +static void file_record(struct srec_binrec *record); +static int output_records(int outfd); + +static int wide_records = 0; + +int usage(void) +{ + fprintf(stderr, "srec2fw: Convert srec files into binary " + "representation for use by Linux kernel\n"); + fprintf(stderr, "usage: srec2fw [<options>] <src.hex> <dst.fw>\n"); + fprintf(stderr, " -w: wide records (16-bit length)\n"); + return 1; +} + +int main(int argc, char **argv) +{ + int infd, outfd; + struct stat st; + uint8_t *data; + int opt; + + while ((opt = getopt(argc, argv, "ws")) != -1) { + switch (opt) { + case 'w': + wide_records = 1; + break; + default: + return usage(); + } + } + + if (optind + 2 != argc) + return usage(); + + if (!strcmp(argv[optind], "-")) + infd = 0; + else + infd = open(argv[optind], O_RDONLY); + if (infd == -1) { + fprintf(stderr, "Failed to open source file: %s", + strerror(errno)); + return usage(); + } + if (fstat(infd, &st)) { + perror("stat"); + return 1; + } + data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, infd, 0); + if (data == MAP_FAILED) { + perror("mmap"); + return 1; + } + + if (!strcmp(argv[optind+1], "-")) + outfd = 1; + else + outfd = open(argv[optind+1], O_TRUNC|O_CREAT|O_WRONLY, 0644); + if (outfd == -1) { + fprintf(stderr, "Failed to open destination file: %s", + strerror(errno)); + return usage(); + } + if (process_srec(data, st.st_size)) + return 1; + + output_records(outfd); + return 0; +} + +static int process_srec(uint8_t *data, ssize_t size) +{ + struct srec_binrec *record, *record_new; + uint32_t offset = 0; + uint8_t type, crc, crcbyte = 0; + int i, j; + int line = 1; + int len; + + i = 0; +next_record: + /* search for the start of record character */ + while (i < size) { + if (data[i] == '\n') line++; + if (data[i++] == 'S') break; + } + + if (i >= size) return 0; + + /* Minimum record length would be about 10 characters */ + if (i + 10 > size) { + fprintf(stderr, "Can't find valid record at line %d\n", line); + return -EINVAL; + } + + crc = 1; /* CRC seeded with 1 for each line */ + type = nybble(data[i]); i++; + len = hex(data + i, &crc); i += 2; + if (wide_records) { + len <<= 8; + len += hex(data + i, &crc); i += 2; + } + len = len - 5; + record = malloc((sizeof (*record) + len + 3) & ~3); + if (!record) { + fprintf(stderr, "out of memory for records\n"); + return -ENOMEM; + } + memset(record, 0, (sizeof(*record) + len + 3) & ~3); + record->len = len; + + /* now check if we have enough data to read everything */ + if (i + 10 + (record->len * 2) > size) { + fprintf(stderr, "Not enough data to read complete record at line %d\n", + line); + return -EINVAL; + } + + record->addr = hex(data + i, &crc) << 24; i += 2; + record->addr |= hex(data + i, &crc) << 16; i += 2; + record->addr |= hex(data + i, &crc) << 8; i += 2; + record->addr |= hex(data + i, &crc); i += 2; + + for (j = 0; j < record->len; j++, i += 2) + record->data[j] = hex(data + i, &crc); + + /* check CRC */ + crcbyte = hex(data + i, &crc); i += 2; + if (crc != 0) { + fprintf(stderr, "CRC failure at line %d: got 0x%X, expected 0x%X\n", + line, crcbyte, (unsigned char)(crcbyte-crc)); + return -EINVAL; + } + + /* Done reading the record */ + switch (type) { + case 7: + /* S7 Start Address Record - we will mutate this + into a new S3 record, with the address becoming the + data portion */ + record_new = malloc((sizeof (*record) + 4 + 3) & ~3); + if (!record_new) { + fprintf(stderr, "out of memory for records\n"); + return -ENOMEM; + } + memset(record_new, 0, (sizeof(*record) + 4 + 3) & ~3); + record_new->len = 4; + record_new->addr = S3ADDR_START; + record->addr = htole32(record->addr); + memcpy(record_new->data, &(record->addr), 4); + file_record(record_new); + goto next_record; + + case 3: + /* S3 Address Record */ + file_record(record); + goto next_record; + + default: + fprintf(stderr, "Unknown record (type %02X)\n", type); + } + + return -EINVAL; +} + +static struct srec_binrec *records; + +static void file_record(struct srec_binrec *record) +{ + struct srec_binrec **p = &records; + + while ((*p) && ((*p)->addr < record->addr)) + p = &((*p)->next); + + record->next = *p; + *p = record; +} + +static int output_records(int outfd) +{ + unsigned char zeroes[6] = {0, 0, 0, 0, 0, 0}; + struct srec_binrec *p = records; + + while (p) { + uint16_t writelen = (p->len + 9) & ~3; + + p->addr = htonl(p->addr); + p->len = htons(p->len); + write(outfd, &p->addr, writelen); + p = p->next; + } + /* EOF record is zero length, since we don't bother to represent + the type field in the binary version */ + write(outfd, zeroes, 6); + return 0; +} |