redboot-tools-0.7build3/0000775000000000000000000000000011260157267012156 5ustar redboot-tools-0.7build3/redboot-install/0000775000000000000000000000000011260157267015260 5ustar redboot-tools-0.7build3/redboot-install/redboot-install0000775000000000000000000002132711260157267020315 0ustar #!/bin/bash # # redboot-install # - a tool to create a bootable SD card on a babbage board # # Copyright (c) 2009 Canonical # Authors: Oliver Grawert # Loïc Minier # # 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # # Required packages: redboot-imx51-babbage, redboot-tools, linux-imx51 # # TODO # - use safer -m flag of parted (needs a newer parted) DEV="" DIST="jaunty" FLAVOUR="imx51" BOARD="babbage" HWITER="-TO2" trap cleanup 0 1 2 3 6 cleanup() { if [ -d "${BUILDDIR}" ]; then echo "cleaning up ..." rm -rf $BUILDDIR echo "done ..." fi exit 0 } usage() { echo ' usage: redboot-install -d [option] required options: -d --device Target device to write redboot setup to additional options: -h --help This help -k --kernel Location of the vmlinuz/zImage file with full path Defaults to: /boot/vmlinuz-$(uname -r) -i --initrd Location of the initrd.gz file with full path Defaults to: /boot/initrd.img-$(uname -r) -c --cmdline Kernel commandline to use for booting Defaults to: root=UUID= ro quiet -n --nodev Allow argument to -d to not be a blockdevice (i.e. for use with an image file) ' exit 0 } checkparm() { if [ "$(echo $1|grep ^'\-')" ] || [ -z "$1" ];then echo "E: Need an argument" usage fi } ALLOW_IMAGE="" while [ ! -z "$1" ]; do case $1 in -h|--help) usage ;; -d|--device) checkparm $2 DEV="$2" ;; -k|--kernel) checkparm $2 KERNEL_FIS_DATA="$2" ;; -i|--initrd) checkparm $2 INITRD_FIS_DATA="$2" ;; -c|--cmdline) checkparm $2 CMDLINE="$2" ;; -n|--nodev) ALLOW_IMAGE="1" esac shift done if [ ! -n "${DEV}" ];then usage fi if [ ! -b "${DEV}" ] && [ -z "${ALLOW_IMAGE}" ];then echo "E: no such device: $DEV" exit 0 fi if [ ! -w "${DEV}" ];then echo "E: cannot write to: $DEV" exit 0 fi file_length() { stat -c %s "$1" } BUILDDIR=$(mktemp -d) CMDLINE="${CMDLINE:-ro quiet splash}" KERNEL_FIS_DATA="${KERNEL_FIS_DATA:-/boot/vmlinuz-$(uname -r)}" INITRD_FIS_DATA="${INITRD_FIS_DATA:-/boot/initrd.img-$(uname -r)}" # pick an arbitrary large enough size multiple of 512 (sector size) and of # 0x20000 (flash block size) FIS_SIZE="$((16 * 1024 * 1024))" hex2dec() { printf "%d\n" "$1" } # create partition table echo "initializing disk label (MBR and partition table)..." parted -s "$DEV" mklabel msdos echo "creating FIS partition..." # 512 bytes is the smallest offset where the partition can start; note that the # FIS starts on the first sector (LBA address 0 or offset 0); also note that # parted END address is inclusive, so we substract 1 from FIS_SIZE parted -s "$DEV" mkpart primary fat32 "512B" "$(($FIS_SIZE - 1))B" # hackish way to set partition type to "Non-FS data" (0xda); neither parted # not fdisk work well in all cases here; fdisk will complain about lack of # number of cylinders, and parted doesn't take arbitrary ids # partition table starts at 0x01BE, partition type is at +0x04 PART1_ID_OFFSET="$(hex2dec 0x1c2)" printf '\xda' | dd conv=notrunc bs="$PART1_ID_OFFSET" of="$DEV" seek=1 2>/dev/null # outputs actual partition start offset, end offset, and length, suffixed with # B get_part_data() { local n="$1" LANG=C parted -s "$DEV" unit B print | awk "/^ $n / { print \$2 \" \" \$3 \" \" \$4 }" # safer version using parted -m; needs newer parted #LANG=C parted -m -s "$DEV" unit B print | grep "^$n:" | cut -d: -f 2,3,4 --output-delimiter=" " } PART1_END_B="`(set -- $(get_part_data 1); echo "$2")`" if [ "$((${PART1_END_B%B} + 1))" -lt "$FIS_SIZE" ]; then echo "FIS partition ends at $PART1_END_B and doesn't leave enough room for FIS ${FIS_SIZE}B" fi REDBOOT_PKG="redboot-$FLAVOUR-$BOARD" REDBOOT_DATA="/usr/lib/redboot/$FLAVOUR-${BOARD}${HWITER}_redboot.bin" CONFIG_DATA="/usr/lib/redboot/$FLAVOUR-${BOARD}_fconfig.bin" # the FIS config depends of the target board; offsets are converted to decimal # for dd and "test" FIS_DIR_OFFSET="$(hex2dec 0x40000)" FIS_DIR_LENGTH="$(hex2dec 0x1F000)" FIS_DIR_ADDR="$(hex2dec 0x40000)" # where to actually write RedBoot REDBOOT_OFFSET="$(hex2dec 0x400)" # the address to write in the FIS entry; we could theoritically write 0x400 # here and decrease the entry length by the same amount, but eCos/RedBoot don't # like writing at addresses not aligned to 0x20000, so avoid that; it's not # clear whether the ROM loads 0x0 - 0x400 in memory, or whether the romupdate # command is clever enough to avoid this issue on write, but it's not a problem # because the romupdate command is a no-op when booting from SD REDBOOT_FIS_OFFSET="$(hex2dec 0x0)" REDBOOT_FIS_LENGTH="$(hex2dec 0x40000)" CONFIG_FIS_OFFSET="$(hex2dec 0x5F000)" CONFIG_FIS_LENGTH="$(hex2dec 0x1000)" CONFIG_FIS_ADDR="$(hex2dec 0x5F000)" KERNEL_FIS_OFFSET="$(hex2dec 0x60000)" KERNEL_FIS_LENGTH="$(hex2dec 0x500000)" KERNEL_FIS_ENTRY="$(hex2dec 0x100000)" KERNEL_FIS_ADDR="$(hex2dec 0x100000)" INITRD_FIS_OFFSET="$(hex2dec 0x560000)" INITRD_FIS_LENGTH="$(hex2dec 0x940000)" INITRD_FIS_ENTRY="$(hex2dec 0xFFFFFFFF)" INITRD_FIS_ADDR="$(hex2dec 0x1000000)" # wrapper to call the FIS command-line tool fis_do() { fis -d "$DEV" -o "$FIS_DIR_OFFSET" -s "$FIS_DIR_LENGTH" "$@" } # helper to write a file's data to the FIS at given offset; also checks the # file is smaller than length before writing # NB: this actually uses $offset memory, so don't use too large offsets fis_write() { local file="$1" local offset="$2" local max_length="$3" if [ "$(file_length "$1")" -gt "$max_length" ]; then echo "File $file is larger than maximum allowed size of $max_length" fi dd conv=notrunc bs="$offset" if="$file" of="$DEV" seek=1 2>/dev/null } echo "initializing fis directory..." fis_do init echo " 'RedBoot'" fis_do create "RedBoot" \ -f "$REDBOOT_FIS_OFFSET" \ -l "$REDBOOT_FIS_LENGTH" \ -c "$REDBOOT_DATA" fis_write "$REDBOOT_DATA" "$REDBOOT_OFFSET" "$REDBOOT_FIS_LENGTH" echo " 'FIS directory'" fis_do create "FIS directory" \ -f "$FIS_DIR_OFFSET" \ -l "$FIS_DIR_LENGTH" \ -r "$FIS_DIR_ADDR" echo "writing bootloader configuration..." # modified bootloader config # TODO use mktemp CONFIG_DATA_MODIFIED="fconfig.bin" cp "$CONFIG_DATA" "$CONFIG_DATA_MODIFIED" # set a config var to a value fconfig_set() { fconfig -s -w -d "$CONFIG_DATA_MODIFIED" -n "$1" -x "$2" } # launch boot script on boot fconfig_set boot_script TRUE # after 3 seconds fconfig_set boot_script_timeout 3 # actual boot script SCRIPT="fis load initrd\\" SCRIPT="${SCRIPT}fis load kernel\\" SCRIPT="${SCRIPT}exec -r $INITRD_FIS_ADDR -s $INITRD_FIS_LENGTH -c \"$CMDLINE\"\\" fconfig_set boot_script_data "$SCRIPT" # disable DHCP on boot fconfig_set bootp FALSE echo " 'RedBoot config'" fis_do create "RedBoot config" \ -f "$CONFIG_FIS_OFFSET" \ -l "$CONFIG_FIS_LENGTH" \ -r "$CONFIG_FIS_ADDR" \ -c "$CONFIG_DATA_MODIFIED" fis_write "$CONFIG_DATA_MODIFIED" "$CONFIG_FIS_OFFSET" "$CONFIG_FIS_LENGTH" # purge extracted RedBoot and RedBoot config data rm -rf usr echo " 'kernel'" fis_do create "kernel" \ -f "$KERNEL_FIS_OFFSET" \ -l "$KERNEL_FIS_LENGTH" \ -e "$KERNEL_FIS_ENTRY" \ -r "$KERNEL_FIS_ADDR" \ -c "$KERNEL_FIS_DATA" fis_write "$KERNEL_FIS_DATA" "$KERNEL_FIS_OFFSET" "$KERNEL_FIS_LENGTH" # pad initrd INITRD_FIS_DATA_LENGTH="$(file_length "$INITRD_FIS_DATA")" PADDED_INITRD_FIS_DATA="$INITRD_FIS_DATA.padded" if [ "$INITRD_FIS_DATA_LENGTH" -gt "$INITRD_FIS_LENGTH" ]; then echo "Initrd $INITRD_FIS_DATA too big for FIS initrd partition length ($INITRD_FIS_LENGTH)" fi PAD="$(expr "$INITRD_FIS_LENGTH" - "$INITRD_FIS_DATA_LENGTH")" ( cat "$INITRD_FIS_DATA" # pad with zeroes; this uses $PAD mem, not very elegant dd if=/dev/zero bs="$PAD" count=1 2>/dev/null ) | dd of="$PADDED_INITRD_FIS_DATA" bs=4k 2>/dev/null echo " 'initrd'" fis_do create "initrd" \ -f "$INITRD_FIS_OFFSET" \ -l "$INITRD_FIS_LENGTH" \ -e "$INITRD_FIS_ENTRY" \ -r "$INITRD_FIS_ADDR" \ -c "$PADDED_INITRD_FIS_DATA" fis_write "$PADDED_INITRD_FIS_DATA" "$INITRD_FIS_OFFSET" "$INITRD_FIS_LENGTH" rm -f "$PADDED_INITRD_FIS_DATA" redboot-tools-0.7build3/fis/0000775000000000000000000000000011260157267012737 5ustar redboot-tools-0.7build3/fis/crc.c0000664000000000000000000001073311260157267013656 0ustar /* * crc.c * * $Id: crc.c,v 1.1 2006/02/13 09:58:08 andrzej Exp $ * * Gary S. Brown's CRC * Code based on Gary S. Brown CRC (1986). * Generation polynomial is: * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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 #include "crc.h" static const uint32_t crc32_tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; uint32_t crc32(uint8_t *s, uint32_t len) { uint32_t i, val = 0; for (i = 0; i < len; i++) { val = crc32_tab[(val^s[i]) & 0xff] ^ (val >> 8); } return val; } redboot-tools-0.7build3/fis/fis.c0000664000000000000000000004155211260157267013673 0ustar // fis.c // see http://svn.chezphil.org/utils // Based on the C++ version in fis.cc // To compile, use --std=c99 // (C) 2007 Philip Endecott // 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 // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include #include #include #include #include #include #include #include #include "crc.h" // Report an error and terminate: static void fatal(const char* msg) { fputs(msg,stderr); fputc('\n',stderr); exit(1); } // Report a warning and continue: static void warning(const char* msg) { fputs(msg,stderr); fputc('\n',stderr); } // Macro to call a library function and check the result, printing an appropriate error // message if it fails. E.g. open() returns -1 if it fails, so you can write: // CHECK(fd=open(fn),-1); // (But you can't write CHECK(int fd=open...), even in c99 mode.) #define CHECK(what,errcode) if ((what)==errcode) { perror(#what); exit(1); } // Wrapper for malloc() that checks for out-of-memory and other errors: static void* chk_malloc(size_t size) { void* ptr = malloc(size); if (!ptr) { perror("malloc"); exit(1); } return ptr; } // Wrappers for read() and write() that check for error and unexpected conditions. static void chk_read(int fd, void* buf, size_t count) { size_t rc = read(fd,buf,count); if (rc!=count) { if ((int)rc==-1) { perror("read"); exit(1); } else { fatal("short read"); } } } static void chk_write(int fd, const void* buf, size_t count) { size_t rc = write(fd,buf,count); if (rc!=count) { if ((int)rc==-1) { perror("write"); exit(1); } else { fatal("short write"); } } } // Get the size of a file unsigned int filesize(int fd) { return lseek(fd,0,SEEK_END); } static uint32_t swap_end_32(uint32_t data) { uint32_t r = data>>24; r |= (data>>8)&0x0000ff00; r |= (data<<8)&0x00ff0000; r |= data<<24; return r; } // Parse a string containing a number. If it starts with 0x, parse the rest as hex. // !!! NOTE: also parses octal constants that start with '0' !!! static unsigned int str_to_int_maybe_hex(const char* s) { char* endptr; unsigned int i = strtoul(s,&endptr,0); if (*s!='\0' && *endptr=='\0') { return i; } fatal("junk after number"); } // This is taken from drivers/mtd/redboot.c in the Linux source struct fis_image_desc { unsigned char name[16]; // Null terminated name uint32_t flash_base; // Address within FLASH of image uint32_t mem_base; // Address in memory where it executes uint32_t size; // Length of image uint32_t entry_point; // Execution entry point uint32_t data_length; // Length of actual data uint32_t skips[53]; uint32_t desc_cksum; // Checksum over image descriptor uint32_t file_cksum; // Checksum over image data }; static void dump_desc(FILE* f, const struct fis_image_desc* d) { fprintf(f,"%16s: addr = 0x%08x, size = 0x%08x, entry = 0x%08x, length = 0x%08x, cksum = 0x%08x\n", d->name, d->flash_base, d->size, d->entry_point, d->data_length, d->file_cksum); for (unsigned int i=0; i<(sizeof(d->skips)/4); ++i) { if (d->skips[i]==0x736b6970 || d->skips[i]==0x70696b73) { // "skip" uint32_t offset = d->skips[i+1]; uint32_t length = d->skips[i+2]; fprintf(stderr," skip: %08x + %08x\n", offset,length); i+=2; } } } // Use a non-invasive list to represent the entire directory. // Yes, this probably does look a bit over-the-top, but it's a close match to what the // C++ version does, making the other code simpler. // Each element of the list has one of the following handle structures: struct dirnode { struct fis_image_desc* entry; struct dirnode* prev; struct dirnode* next; }; // The list is circularly linked, i.e. the last node's next pointer points to the first // node, and the first node's prev pointer points to the last node. The start of the // list is distinguished by the fact that the list as a whole is represented by a // pointer to the first node. // Functions that do read-only operations on a list take a dir_t parameter. Functions // that do read-write operations take a dir_t* since they may have to modify this // pointer if the first element changes. An empty list is represented by a NULL // pointer. // Functions that operate on particular elements of a list use an iter_t parameter. This // is just a pointer to a node handle, but can be treated as opaque. The for-each macro, // below, supplies iter_t iterators which the caller dereferences using get() to get the // struct fis_image_desc. typedef struct dirnode* dir_t; typedef struct dirnode* iter_t; static unsigned int dir_size_tail(dir_t d, struct dirnode* n) { if (n==d) { return 0; } else { return 1 + dir_size_tail(d,n->next); } } // Return the number of entries in a directory. static unsigned int dir_size(dir_t d) { if (!d) { return 0; } else { return 1 + dir_size_tail(d,d->next); } } // Create a new empty directory. static void dir_create(dir_t* dir) { *dir = NULL; } // Append an entry to a directory. // The list takes ownership of the new entry. static void dir_append(dir_t* dir, struct fis_image_desc* d) { struct dirnode* n = chk_malloc(sizeof(struct dirnode)); n->entry = d; if (*dir) { n->next = *dir; n->prev = (*dir)->prev; (*dir)->prev->next = n; (*dir)->prev = n; } else { n->next = n; n->prev = n; (*dir) = n; } } // Insert an entry into a directory after the entry referred to by the iterator 'after'. // If 'after' is NULL, insert at the beginning. // The list takes ownership of the new entry. static void dir_insert(dir_t* dir, iter_t after, struct fis_image_desc* d) { // Special case, directory is empty. if (!(*dir)) { dir_append(dir,d); return; } struct dirnode* n = chk_malloc(sizeof(struct dirnode)); n->entry = d; if (!after) { after = (*dir)->prev; *dir = n; } n->prev = after; n->next = after->next; after->next->prev = n; after->next = n; } // Remove an entry from a directory. // The entry is free()d. static void dir_erase(dir_t* dir, iter_t i) { // Erasing the first element: if (i==(*dir)) { // Erasing the first and only element: if (i->next==i) { *dir = NULL; } else { *dir = i->next; } } i->next->prev = i->prev; i->prev->next = i->next; free(i->entry); free(i); } // This macro can be used to iterate through a directory. // It takes the directory and an iterator, which it will declare, as parameters. // Example: // FOR_EACH_DIR_ENTRY(dir,i) { // dump_desc(stdout,get(i)); // } #define FOR_EACH_DIR_ENTRY(dir,iterator) \ for (iter_t iterator = dir; \ iterator; \ iterator = (iterator->next==dir) ? NULL : iterator->next) // Use this to get the struct fis_image_desc from the iterator: #define get(iterator) (iterator->entry) static void check_dev(const char* device) { if (!device[0]) { fatal("You must specify a device using -d"); } } void check_checksum(const struct fis_image_desc* d) { // This isn't checked by the kernel mtd driver, which has this // comment: "RedBoot doesn't actually write the desc_cksum field yet // AFAICT". I don't know what checksum is supposed to be used here. } void compute_checksum(struct fis_image_desc* d) { // ditto } static void swap_entry_endianness(struct fis_image_desc* d) { d->flash_base = swap_end_32(d->flash_base); d->mem_base = swap_end_32(d->mem_base); d->size = swap_end_32(d->size); d->entry_point = swap_end_32(d->entry_point); d->data_length = swap_end_32(d->data_length); for (unsigned int i=0; i<(sizeof(d->skips)/4); ++i) { d->skips[i] = swap_end_32(d->skips[i]); } } static void load_dir(int fd, int offset, int* size_p, bool swap_endianness, dir_t* dir) { dir_create(dir); if ((*size_p)==-1) { (*size_p) = filesize(fd)-offset; } CHECK(lseek(fd,offset,SEEK_SET),-1); int num_entries = (*size_p)/sizeof(struct fis_image_desc); for (int i=0; iname[0]!=0xff) { check_checksum(d); if (swap_endianness) { swap_entry_endianness(d); } dir_append(dir,d); } else if (d->name[1]==0xff) break; } } static void write_blank_entries(int fd, int n) { char dummy[sizeof(struct fis_image_desc)]; for (unsigned int i=0; iflash_base+get(i)->size) && end_addr>get(i)->flash_base) { warning("New partition overlaps existing partitions"); } } } static void fis_create(const char* device, int offset, int size, bool swap_endianness, char *name, int argc, char* argv[]) { struct fis_image_desc* existing = NULL; struct fis_image_desc* d = NULL; int fd; CHECK(fd=open(device,O_RDWR),-1); dir_t dir; load_dir(fd,offset,&size,swap_endianness,&dir); /* Search for an existing partition of this name. */ FOR_EACH_DIR_ENTRY(dir,i) { char* this_name = get(i)->name; if (strcmp(this_name,name)==0) { existing = get(i); break; } } /* If no existing partition found, then create a new one. */ if (existing == NULL) { d = chk_malloc(sizeof(struct fis_image_desc)); for (int j=0; j<16; j++) { char c = name[j]; d->name[j] = c; if (!c) { for (; j<16; ++j) { d->name[j]=0; } break; } } d->mem_base = 0; d->entry_point = 0; d->data_length = 0; for (unsigned int i=0; i<(sizeof(d->skips)/4); ++i) { d->skips[i] = 0; } d->desc_cksum = 0; d->file_cksum = 0; } else { d = existing; } for (int i=0; isize = str_to_int_maybe_hex(argv[i]); } else if (strcmp(arg,"-f")==0) { if (i==argc-1) { fatal("argumnet missing for -f"); } ++i; d->flash_base = str_to_int_maybe_hex(argv[i]); } else if (strcmp(arg,"-e")==0) { if (i==argc-1) { fatal("argumnet missing for -e"); } ++i; d->entry_point = str_to_int_maybe_hex(argv[i]); } else if (strcmp(arg,"-r")==0) { if (i==argc-1) { fatal("argumnet missing for -r"); } ++i; d->mem_base = str_to_int_maybe_hex(argv[i]); } else if (strcmp(arg,"-c")==0) { if (i==argc-1) { fatal("argumnet missing for -c"); } ++i; char* file = argv[i]; int fd; struct stat file_stat; CHECK(fd=open(file,O_RDONLY),-1); CHECK(fstat(fd,&file_stat),-1); d->data_length=file_stat.st_size; uint8_t *data; CHECK(data=mmap(0,d->data_length,PROT_READ,MAP_PRIVATE,fd,0),MAP_FAILED); d->file_cksum=crc32(data,d->data_length); munmap(data,d->data_length); } else { fputs("Unrecognised option '",stderr); fputs(arg,stderr); fputs("'\n",stderr); exit(1); } } /* Insert the new entry if it didn't already exist. */ if (existing == NULL) { check_overlap(dir,d->flash_base,d->size); iter_t after = NULL; FOR_EACH_DIR_ENTRY(dir,i) { if (get(i)->flash_base > d->flash_base) { break; } after = i; } dir_insert(&dir,after,d); } save_dir(fd,offset,size,swap_endianness,dir); } static void fis_delete(const char* device, int offset, int size, bool swap_endianness, char* name) { int fd; CHECK(fd=open(device,O_RDWR),-1); dir_t dir; load_dir(fd,offset,&size,swap_endianness,&dir); FOR_EACH_DIR_ENTRY(dir,i) { char* this_name = get(i)->name; if (strcmp(this_name,name)==0) { dir_erase(&dir,i); save_dir(fd,offset,size,swap_endianness,dir); return; } } fatal("No partition found with specified name"); } static void usage() { fputs("Usage:\n" " fis [options] list\n" " fis [options] init\n" " fis [options] create name [-f address] [-l size] [-e entry] [-r ram-addr] [-c contents]\n" " fis [options] delete name\n" "Options:\n" " -d device specify /dev/mtd* device containing directory\n" " -o offset specify offset into device of start of directory\n" " (in decimal; prefix with 0x for hex)\n" " -s size specify size of directory in bytes\n" " -e swap endianness\n", stderr); } int main(int argc, char* argv[]) { if (argc==1) { usage(); exit(1); } char* device=""; int offset=0; int size=-1; bool swap_endianness=false; for (int i=1; i=16) { fatal("name too long, max 16 chars including terminating null"); } check_dev(device); fis_create(device,offset,size,swap_endianness,name, argc-i-1,&argv[i+1]); break; } else if (strcmp(arg,"delete")==0) { if (i!=argc-2) { fatal("Exactly one argumnet required after 'delete'"); } ++i; char* name = argv[i]; check_dev(device); fis_delete(device,offset,size,swap_endianness,name); } else { fputs("unrecognised argument '",stderr); fputs(arg,stderr); fputs("'\n",stderr); usage(); exit(1); } } exit(0); } redboot-tools-0.7build3/fis/crc.h0000664000000000000000000000106611260157267013662 0ustar /* * crc.h * * $Id: crc.h,v 1.1 2006/02/13 09:58:08 andrzej Exp $ * * Gary S. Brown's CRC - header. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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. */ #ifndef CRC_H #define CRC_H #include uint32_t crc32(uint8_t *s, uint32_t len); #endif //CRC_H redboot-tools-0.7build3/fis/Makefile0000664000000000000000000000056411260157267014404 0ustar NAME = fis SRC = fis.c crc.c OBJ = $(subst .c,.o, $(SRC)) CFLAGS = --std=c99 all: $(NAME) %.d: %.c $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \ | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \ [ -s $@ ] || rm -f $@' ifneq ($(MAKECMDGOALS), clean) -include $(SRC:.c=.d) endif $(NAME): $(OBJ) $(CC) $(LDFLAGS) -o $@ $(OBJ) $(LDLIBS) clean: -rm -f $(NAME) *.d *.o redboot-tools-0.7build3/debian/0000775000000000000000000000000013260673206013376 5ustar redboot-tools-0.7build3/debian/rules0000775000000000000000000000031211260157267014454 0ustar #!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/rules/simple-patchsys.mk include /usr/share/cdbs/1/rules/utils.mk include /usr/share/cdbs/1/class/makefile.mk redboot-tools-0.7build3/debian/changelog0000664000000000000000000000431313260673206015251 0ustar redboot-tools (0.7build3) bionic; urgency=high * No change rebuild to pick up -fPIE compiler default -- Balint Reczey Tue, 03 Apr 2018 12:41:42 +0000 redboot-tools (0.7build2) quantal; urgency=low * Rebuild for new armel compiler default of ARMv5t. -- Colin Watson Mon, 08 Oct 2012 22:28:52 +0100 redboot-tools (0.7build1) lucid; urgency=low * rebuild rest of main for armel armv7/thumb2 optimization; UbuntuSpec:mobile-lucid-arm-gcc-v7-thumb2 -- Alexander Sack Sun, 07 Mar 2010 01:03:16 +0100 redboot-tools (0.7) karmic; urgency=low * add redboot-cmdline to the package to make kernel cmdline editing in fconfig data an easy task * add dependency on parted, redboot-install uses it -- Oliver Grawert Mon, 28 Sep 2009 18:04:31 +0200 redboot-tools (0.6) karmic; urgency=low * add -n/--nodev option to redboot-install to allow writing to image files instead of blockdevices * drop UUID from default cmdline, drop UUID generation as it would be empty anyway * add splash to default cmdline * inclue lool's debian-cd fixes to create fis partitions with an exact size instead of having parted include the last block (512 bytes) -- Oliver Grawert Fri, 25 Sep 2009 12:28:49 +0200 redboot-tools (0.5) karmic; urgency=low * add Vcs urls to upstream branches in debian/control -- Oliver Grawert Sun, 02 Aug 2009 10:10:14 +0200 redboot-tools (0.4) karmic; urgency=low * add HWITER variable to redboot-install, to enable selection of a redboot binary based on the board release -- Oliver Grawert Sun, 02 Aug 2009 10:04:48 +0200 redboot-tools (0.3) karmic; urgency=low * add redboot-install (LP: #348060) -- Oliver Grawert Fri, 31 Jul 2009 09:21:33 +0200 redboot-tools (0.2) jaunty; urgency=low * Move to cdbs and to debhelper compat level 5; update build-deps accordingly; this helps building in plain hardy. -- Loic Minier Tue, 24 Mar 2009 21:34:33 +0100 redboot-tools (0.1) jaunty; urgency=low * Initial release; LP: #XXXXXX. -- Loic Minier Tue, 24 Mar 2009 20:11:35 +0100 redboot-tools-0.7build3/debian/redboot-tools-udeb.install0000664000000000000000000000006011260157267020475 0ustar fconfig/fconfig usr/bin fis/fis usr/bin redboot-tools-0.7build3/debian/control0000664000000000000000000000332513260673206015004 0ustar Source: redboot-tools Section: utils Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Loic Minier Build-Depends: debhelper (>= 5), cdbs (>= 0.4.50) Standards-Version: 3.8.0 Vcs-Bzr: lp:redboot-tools/upstream-development Vcs-Browser: https://code.launchpad.net/~ubuntu-mobile/redboot-tools/ubuntu Package: redboot-tools Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, parted Description: Collection of utilities to manipulate RedBoot data fis is a tool to manipulate entries in a RedBoot FIS directory, similar to the fis command in the RedBoot interactive shell. . fconfig is a tool to manipulate RedBoot configuration data, similar to the fconfig command in the RedBoot interactive shell. . These utilities help create RedBoot data from scratch or querying/updating the data of an installed system. This can be used to generate images with RedBoot data or to change the boot data of devices. Package: redboot-tools-udeb Architecture: any Section: debian-installer Depends: ${shlibs:Depends}, ${misc:Depends} XC-Package-Type: udeb Description: Collection of utilities to manipulate RedBoot data (udeb) fis is a tool to manipulate entries in a RedBoot FIS directory, similar to the fis command in the RedBoot interactive shell. . fconfig is a tool to manipulate RedBoot configuration data, similar to the fconfig command in the RedBoot interactive shell. . These utilities help create RedBoot data from scratch or querying/updating the data of an installed system. This can be used to generate images with RedBoot data or to change the boot data of devices. . redboot-tools-udeb is a minimal package used by debian-installer. redboot-tools-0.7build3/debian/compat0000664000000000000000000000000211260157267014576 0ustar 5 redboot-tools-0.7build3/debian/copyright0000664000000000000000000000440411260157267015335 0ustar === fconfig === The fconfig/ dir is from fconfig-20080329.tar.gz downloaded from: http://andrzejekiert.ovh.org/software.html.en All fconfig/* files are: * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert and are licensed under the GPL version 2 or later: * 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.. === fis === The fis/ dir was exported from SVN at r6 from: http://svn.nslu2-linux.org/svnroot/fis/trunk/ fis/crc.c and fis/crc.h duplicate the files from fconfig and are: * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert and are licensed under the GPL version 2 or later: * 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.. fis/fis.c is derived from fis.cc as found at http://svn.chezphil.org/utils and is: // (C) 2007 Philip Endecott and is licensed under the GPL version 2 or later: // 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 // any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. === Packaging === The packaging was created by Loïc Minier and is: Copyright 2009 Canonical Ltd. and is licensed under GPLv2 or later. === Full license texts === On Debian and Ubuntu systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. redboot-tools-0.7build3/debian/redboot-tools.install0000664000000000000000000000020011260157267017554 0ustar fconfig/fconfig usr/bin fis/fis usr/bin redboot-install/redboot-install usr/bin redboot-cmdline/redboot-cmdline usr/bin redboot-tools-0.7build3/fconfig/0000775000000000000000000000000011260157267013571 5ustar redboot-tools-0.7build3/fconfig/debug.h0000775000000000000000000000145111260157267015034 0ustar /* * debug.h * * $Id: debug.h,v 1.1 2006/02/13 09:58:08 andrzej Exp $ * * Redboot Flash Configuration parser. * Debug utilities - header. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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. */ #ifndef DEBUG_H #define DEBUG_H #include #define VERB_LOW 1 #define VERB_NORMAL 2 #define VERB_HIGH 3 extern uint8_t verbosity; void hex_dump(void *buf, uint16_t len); #define MESSAGE(verb, args...) \ do { \ if (verb <= verbosity) { \ printf(args); \ } \ } while (0); #endif //DEBUG_H redboot-tools-0.7build3/fconfig/crunchfc.h0000775000000000000000000000205411260157267015541 0ustar /* * crunchfc.h * * $Id: crunchfc.h,v 1.3 2008/03/29 12:20:55 andrzej Exp $ * * Redboot Flash Configuration parser. * Configuration parsing routines - header. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * Changes: * 2008/03/29 - 'offset' option added by wimpunk * * 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. */ #ifndef CRUNCHFC_H #define CRUNCHFC_H #include struct config_data { int fd; int offset; uint32_t maxlen; uint32_t reallen; uint8_t swab; uint8_t *buf; }; int8_t verify_fconfig(struct config_data *data); int8_t get_key_value(struct config_data *data, uint8_t *nickname); int8_t set_key_value(struct config_data *data, uint8_t *nickname, void *value); int8_t list_keys(struct config_data *data); void recalculate_crc(struct config_data *data); #endif //CRUNCHFC_H redboot-tools-0.7build3/fconfig/crc.c0000775000000000000000000001073311260157267014513 0ustar /* * crc.c * * $Id: crc.c,v 1.1 2006/02/13 09:58:08 andrzej Exp $ * * Gary S. Brown's CRC * Code based on Gary S. Brown CRC (1986). * Generation polynomial is: * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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 #include "crc.h" static const uint32_t crc32_tab[] = { 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL }; uint32_t crc32(uint8_t *s, uint32_t len) { uint32_t i, val = 0; for (i = 0; i < len; i++) { val = crc32_tab[(val^s[i]) & 0xff] ^ (val >> 8); } return val; } redboot-tools-0.7build3/fconfig/fconfig.c0000775000000000000000000001654711260157267015370 0ustar /* * fconfig.c * * $Id: fconfig.c,v 1.3 2008/03/29 12:20:55 andrzej Exp $ * * Redboot Flash Configuration parser. * Main file. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * Changes: * 2007/10/21 - 'list' option added by Hamish Moffatt * 2008/03/29 - 'offset' option added by wimpunk * * 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. * * Usage hints: * The 'device' is probably going to be an MTD device. You may also operate * on an ordinary file. However, if you're working with MTD, it's highly * recommended to open it as a character device, not as a block device * (eg. open /dev/mtd[n], not /dev/mtdblock[n]). If an MTD device is emulating * a block device, then the OS will do heavy caching (a lot of unneccessary * reads), and will do block writes, while in character device mode it's * possible to actually write exactly these bytes, that have been changed * (see my 24xx I2C EEPROM driver - ee24.c). In case of operation with slow * I2C EEPROMs this allows to speed up things and to save on EEPROM wear-out. * * The above should explain why mmap() is not used in this application ;-) * (initially it was, but the performance was poor, when we're forced to work * with slow block devices). */ #include #include #include #include #include #include #include #include "debug.h" #include "ftypes.h" #include "crunchfc.h" /* * Parse type name, return type ID. * Type ID is the type number in the type table. */ /* static int8_t parse_type(uint8_t *type) { uint8_t i, ret = -1; MESSAGE(VERB_HIGH, "Parsing type: %s\n", type); for (i = 0; i < NUM_TYPES; i++) { if (strncmp(TYPE_NAME(i), type, MAX_TYPE_NAME)==0) { MESSAGE(VERB_HIGH, "Found type: ID = %d\n", i); ret = i; break; } } return ret; } */ /* * Print usage information. */ static void usage(void) { uint8_t i; if (verbosity == 0) { return; } fputs("Read, write or list Redboot configuration\n", stdout); fputs("usage: fconfig [-r|-w|-l]" " -d dev -o offset -n nickname -x value\n", stdout); fputs("'dev' may be a char device, block device or a file\n", stdout); fputs("'offset' is the offset in bytes on the device\n", stdout); fputs("Supported types: \n", stdout); for (i = 0; i < NUM_TYPES; i++) { printf(" - %s\n", TYPE_NAME(i)); } fputs("Additional switches: \n", stdout); fputs(" -v:\tVerbose mode, use more to increase verbosity\n", stdout); fputs(" -s:\tSilent mode, absolutely no messages printed\n", stdout); } /* * Open the file or device containing configuration and copy the configuration * data to a buffer. We could mmap() here and operate directly on mmaped data * (it'd make life easier later), but that would force us to work with MTD in * block device emulation mode (see comments at the top of this file). * * Remember, that the MTD partition is likely to be "forced read-only", * if the partition size is not equal to erase block size. */ static uint8_t buffer[MAX_CONFIG_DATA]; struct config_data *get_fconfig_handle(struct config_data *data, uint8_t *dev, int offset, mode_t mode) { uint16_t count; if ((data->fd = open(dev, mode)) < 0) { MESSAGE(VERB_LOW, "Failed to open device or file %s!\n", dev); return NULL; } data->offset = offset; if (data->offset > 0) { lseek(data->fd, data->offset, SEEK_SET); } count = read(data->fd, buffer, MAX_CONFIG_DATA); if (count <= 0) { MESSAGE(VERB_LOW, "Nothing read!\n"); close(data->fd); return NULL; } MESSAGE(VERB_NORMAL, "Read %d bytes\n", count); data->buf = buffer; data->maxlen = count; return data; } /* * Synchronize the data back and close the file or device containing * the configuration data. */ void close_fconfig_handle(struct config_data *data) { close(data->fd); } /* * Write mode of operation: set parameter values in the configuration. */ static int write_mode(uint8_t *device, int offset, uint8_t *nickname, uint8_t *value) { struct config_data data; if (value == NULL) { MESSAGE(VERB_LOW, "You must provide a value in WRITE mode\n"); return 1; } if (get_fconfig_handle(&data, device, offset, O_RDWR) == NULL) { MESSAGE(VERB_LOW, "Could not get a config data handle!\n"); return 1; } if (verify_fconfig(&data)) { MESSAGE(VERB_LOW, "Config verification failed!\n"); goto exit_fail; } if (set_key_value(&data, nickname, value)) { goto exit_fail; } recalculate_crc(&data); close_fconfig_handle(&data); return 0; exit_fail: close_fconfig_handle(&data); return 1; } /* * Read mode of operation: get parameter values from the configuration. */ static int read_mode(uint8_t *device, int offset, uint8_t *nickname) { struct config_data data; if (get_fconfig_handle(&data, device, offset, O_RDONLY) == NULL) { MESSAGE(VERB_LOW, "Could not get a config data handle!\n"); return 1; } if (verify_fconfig(&data)) { MESSAGE(VERB_LOW, "Config verification failed!\n"); goto exit_fail; } if (get_key_value(&data, nickname)) { goto exit_fail; } close_fconfig_handle(&data); return 0; exit_fail: close_fconfig_handle(&data); return 1; } /* * List mode of operation: list parameter values from the configuration. */ static int list_mode(uint8_t *device, int offset) { struct config_data data; if (get_fconfig_handle(&data, device, offset, O_RDONLY) == NULL) { MESSAGE(VERB_LOW, "Could not get a config data handle!\n"); return 1; } if (verify_fconfig(&data)) { MESSAGE(VERB_LOW, "Config verification failed!\n"); goto exit_fail; } if (list_keys(&data)) { goto exit_fail; } close_fconfig_handle(&data); return 0; exit_fail: close_fconfig_handle(&data); return 1; } #define MODE_NONE 0 #define MODE_WRITE 1 #define MODE_READ 2 #define MODE_LIST 3 /* * main(). ...nuff said. */ int main(int argc, char **argv) { int c, ret; uint8_t mode = MODE_NONE; uint8_t *nickname = NULL; uint8_t *value = NULL; uint8_t *device = NULL; int offset = 0; while ((c = getopt(argc, argv, "hrwlvsd:n:o:x:")) != -1) { switch (c) { case 'r': mode = MODE_READ; break; case 'w': mode = MODE_WRITE; break; case 'l': mode = MODE_LIST; break; case 'n': nickname = optarg; break; case 'o': sscanf(optarg, "%i", &(offset)); break; case 'x': value = optarg; break; case 'v': verbosity++; break; case 's': verbosity = 0; break; case 'd': device = optarg; break; case 'h': usage(); break; case '?': default: usage(); exit(1); break; } } MESSAGE(VERB_LOW, "Low verbosity messages are printed.\n"); MESSAGE(VERB_NORMAL, "Normal verbosity messages are printed.\n"); MESSAGE(VERB_HIGH, "High verbosity messages are printed.\n"); if ((nickname == NULL) && (mode != MODE_LIST)) { usage(); exit(1); } if (device == NULL) { MESSAGE(VERB_LOW, "You must provide a device name.\n"); exit(1); } switch (mode) { case MODE_WRITE : ret = write_mode(device, offset, nickname, value); break; case MODE_READ : ret = read_mode(device, offset, nickname); break; case MODE_LIST : ret = list_mode(device, offset); break; default : MESSAGE(VERB_LOW, "Unknown mode of operation\n"); usage(); ret = 1; } //switch return ret; } redboot-tools-0.7build3/fconfig/crunchfc.c0000775000000000000000000002516311260157267015542 0ustar /* * crunchfc.c * * $Id: crunchfc.c,v 1.3 2008/03/29 12:20:55 andrzej Exp $ * * Redboot Flash Configuration parser. * Configuration parsing routines. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * Changes: * 2007/10/21 - 'list' option added by Hamish Moffatt * 2008/03/29 - 'offset' option added by wimpunk * * 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 #include #include #include #include #include #include #include "crunchfc.h" #include "ftypes.h" #include "crc.h" #include "debug.h" /* * RedBoot configuration layout is the following: * 0 to 3 : len * 4 to 7 : CONFIG_KEY1 * 8 to len-9 : data * len-8 to len-5 : CONFIG_KEY2 * len-4 to len-1 : checksum * * Tested with RedBoot v. 2.02 */ #define CONFIG_KEY1 0x0BADFACE #define CONFIG_KEY2 0xDEADDEAD /* * Each data item is variable length, with the name, type and dependencies * encoded into the object. * offset contents * 0 data type * 1 length of name (N) * 2 enable sense * 3 length of enable key (M) * 4 key name * N+4 enable key * M+N+4 data value */ /* * Fix 32-bit number endianness. */ static inline void fix_endian32(void *vptr, uint8_t swab) { uint8_t *ptr = (uint8_t*)vptr; uint8_t tmp; if (!swab) { return; } tmp = *ptr; *ptr = *(ptr+3); *(ptr+3) = tmp; tmp = *(ptr+1); *(ptr+1) = *(ptr+2); *(ptr+2) = tmp; } /* * Configuration key description. */ struct fconfig_key { uint8_t type; uint8_t namelen, ensense, enlen; uint8_t *keyname; uint8_t *enkey; uint8_t *dataval; }; /* * Fill-in the key description structure. * * 'ptr' should point to the start of key data. There MUST BE at least 4 more * bytes in the buffer (and there should be more, if start address is valid). */ static uint8_t *get_key(uint8_t *ptr, struct fconfig_key *key) { key->type = *ptr++; key->namelen = *ptr++; key->ensense = *ptr++; key->enlen = *ptr++; key->keyname = ptr; ptr += key->namelen; key->enkey = ptr; ptr += key->enlen; /* Be warned: 'dataval' may be an odd pointer and may contain * an uint32_t. If the pointer is odd, then uint32_t will be unaligned. * Never try to cast it: *(uint32_t*)key->dataval. On many * architectures this will not work. */ key->dataval = ptr; if (!verify_ftype(key->type)) { MESSAGE(VERB_LOW, "Unsupported type: %d\n", key->type); return NULL; } ptr += TYPE_SIZE(key->type); return ptr; } /* * Print key data to the screen. * It is assumed that key has been filled-in by get_key(). */ static void print_key(struct fconfig_key *key, uint8_t verb, uint8_t swab) { uint8_t buf[MAX_TYPE_SIZE]; printer_t printer; MESSAGE(verb, "\n"); MESSAGE(verb, "Name length: %d\n", key->namelen); MESSAGE(verb, "Enable sense: %d\n", key->ensense); if (key->ensense==0) { MESSAGE(verb, "Enable key length: %d\n", key->enlen); MESSAGE(verb, "Enable key: %s\n", key->enkey); } MESSAGE(verb, "Key name: %s\n", key->keyname); MESSAGE(verb, "Value: "); if (verb <= verbosity) { memcpy(buf, key->dataval, TYPE_SIZE(key->type)); switch (key->type) { case CONFIG_BOOL : case CONFIG_INT : fix_endian32(buf, swab); break; default : break; } printer = TYPE_PRINTER(key->type); if (printer) { printer(buf); } } MESSAGE(verb, "\n"); } /* * Find the address, where a key with given 'nickname' starts. * 'data' should have been previously validated with verify_fconfig(). */ static uint8_t *locate_key(struct config_data *data, uint8_t *nickname) { struct fconfig_key key; uint32_t len = data->reallen; uint8_t *keyptr = NULL; uint8_t *ptr = data->buf+8; uint8_t *ptrend = data->buf+len-9; while (ptr < ptrend-4) { keyptr = ptr; ptr = get_key(ptr, &key); if (ptr == NULL) { MESSAGE(VERB_LOW, "Error in structure\n"); return NULL; } if (ptr > ptrend) { MESSAGE(VERB_LOW, "Parser went out of struct!\n"); return NULL; } if ((key.type == 0) && (key.namelen==0)) { MESSAGE(VERB_NORMAL, "EOF reached - key not found\n"); return NULL; } if (strncmp(nickname, key.keyname, key.namelen) == 0) { break; } } return keyptr; } /* * Verify the correctness of the configuration structure. */ static int8_t buf_check(struct config_data *data) { struct fconfig_key key; uint32_t len = data->reallen; uint8_t *ptr = data->buf+8; uint8_t *ptrend = data->buf+len-9; while (ptr < ptrend-4) { ptr = get_key(ptr, &key); if (ptr == NULL) { MESSAGE(VERB_LOW, "Error in structure\n"); return -1; } if (ptr > ptrend) { MESSAGE(VERB_LOW, "Parser went out of struct!\n"); return -1; } if ((key.type == 0) && (key.namelen==0)) { MESSAGE(VERB_HIGH, "EOF reached - structure OK\n"); return 0; } print_key(&key, VERB_HIGH, data->swab); } return 0; } /* * Check whether given buffer contains something that looks mostly like * a valid configuration. Try to automatically tell what the endianness is. * * You must call this function before doing anything else to the 'data' buffer. */ int8_t verify_fconfig(struct config_data *data) { uint32_t len; uint32_t key; uint32_t crc; uint32_t maxlen; uint8_t *buf; uint8_t swab; buf = data->buf; maxlen = data->maxlen; for (swab = 0; swab < 2; swab++) { memcpy(&key, buf+4, sizeof(key)); fix_endian32(&key, swab); if (key == CONFIG_KEY1) { break; } } if (swab == 0) { MESSAGE(VERB_HIGH, "Using native endianness\n"); } else if (swab == 1) { MESSAGE(VERB_HIGH, "Using non-native endianness\n"); } else { MESSAGE(VERB_NORMAL, "Key1 is not valid, terminating\n"); return -1; } memcpy(&len, buf, sizeof(len)); fix_endian32(&len, swab); MESSAGE(VERB_NORMAL, "Data length is %d, maxlen is %d\n", len, maxlen); if (len > maxlen) { MESSAGE(VERB_NORMAL, "This is too long.\n"); return -1; } memcpy(&key, buf+len-8, sizeof(key)); fix_endian32(&key, swab); if (key != CONFIG_KEY2) { MESSAGE(VERB_NORMAL, "Key2 is not valid, terminating\n"); return -1; } /* verify crc... */ memcpy(&crc, buf+len-4, sizeof(crc)); fix_endian32(&crc, swab); if (crc != crc32(buf, len-4)) { MESSAGE(VERB_NORMAL, "CRC verification failed.\n"); return -1; } MESSAGE(VERB_NORMAL, "CRC is valid.\n"); data->swab = swab; data->reallen = len; if (buf_check(data)) { MESSAGE(VERB_NORMAL, "Configuration structure is broken.\n"); return -1; } return 0; } /* * Find a key with given nickname, check its type and print value * Assumes that verify_fconfig() has been called on 'data' before. */ int8_t get_key_value(struct config_data *data, uint8_t *nickname) { printer_t printer; struct fconfig_key key; uint8_t *ptr; ptr = locate_key(data, nickname); if (ptr == NULL) { MESSAGE(VERB_LOW, "Unknown key.\n"); return -1; } if (get_key(ptr, &key) == NULL) { MESSAGE(VERB_LOW, "Erroneous key.\n"); return -1; } print_key(&key, VERB_HIGH, data->swab); printer = TYPE_PRINTER(key.type); if (printer == NULL) { MESSAGE(VERB_LOW, "Printer missing for type %d\n", key.type); return -1; } printer(key.dataval); return 0; } /* * List known keys. */ int8_t list_keys(struct config_data *data) { printer_t printer; struct fconfig_key key; uint32_t len = data->reallen; uint8_t *keyptr = NULL; uint8_t *ptr = data->buf+8; uint8_t *ptrend = data->buf+len-9; while (ptr < ptrend-4) { keyptr = ptr; ptr = get_key(ptr, &key); if (ptr == NULL) { MESSAGE(VERB_LOW, "Error in structure\n"); return -1; } if (ptr > ptrend) { MESSAGE(VERB_LOW, "Parser went out of struct!\n"); return -1; } if ((key.type == 0) && (key.namelen==0)) { MESSAGE(VERB_NORMAL, "EOF reached\n"); return -1; } print_key(&key, VERB_HIGH, data->swab); printf("%s: ", key.keyname); printer = TYPE_PRINTER(key.type); if (printer == NULL) { MESSAGE(VERB_LOW, "Printer missing for type %d\n", key.type); return -1; } printer(key.dataval); printf("\n"); } } /* * Find a key with given nickname, check its type and set value * Assumes that verify_fconfig() has been called on 'data' before. */ int8_t set_key_value(struct config_data *data, uint8_t *nickname, void *value) { uint32_t offset; uint8_t buf[MAX_TYPE_SIZE]; parser_t parser; struct fconfig_key key; uint8_t *ptr; ptr = locate_key(data, nickname); if (ptr == NULL) { MESSAGE(VERB_LOW, "Unknown key.\n"); return -1; } if (get_key(ptr, &key) == NULL) { MESSAGE(VERB_LOW, "Erroneous key.\n"); return -1; } MESSAGE(VERB_NORMAL, "\nBefore change:"); print_key(&key, VERB_NORMAL, data->swab); parser = TYPE_PARSER(key.type); if (parser == NULL) { MESSAGE(VERB_LOW, "Parser missing for type %d\n", key.type); return -1; } memset(buf, 0, MAX_TYPE_SIZE); if (parser(value, buf)) { MESSAGE(VERB_LOW, "Bad value.\n"); return -1; } offset = (uint32_t)(key.dataval - data->buf); MESSAGE(VERB_HIGH, "Writing %d bytes at offset %d\n", TYPE_SIZE(key.type), offset); /* do an actual write to the device or file */ if (lseek(data->fd, data->offset+offset, SEEK_SET) == -1) { MESSAGE(VERB_LOW, "lseek() failed\n"); return -1; } if (write(data->fd, buf, TYPE_SIZE(key.type)) == -1) { MESSAGE(VERB_LOW, "write() failed\n"); return -1; } /* keep our buffer in sync with the device or file */ memcpy(key.dataval, buf, TYPE_SIZE(key.type)); MESSAGE(VERB_NORMAL, "\nAfter change:"); print_key(&key, VERB_NORMAL, data->swab); return 0; } /* * Recalculate the checksum of a configuration buffer. * Assumes that verify_fconfig() has been called on 'data' before. */ void recalculate_crc(struct config_data *data) { uint32_t len; uint32_t crc; uint8_t *buf; uint8_t swab; len = data->reallen; buf = data->buf; swab = data->swab; /* Show old */ memcpy(&crc, buf+len-4, sizeof(crc)); fix_endian32(&crc, swab); MESSAGE(VERB_NORMAL, "Old CRC: %04x\n", crc); /* Set new */ crc = crc32(buf, len-4); fix_endian32(&crc, swab); MESSAGE(VERB_HIGH, "Writing CRC at offset %d\n", len-4); /* do an actual write to the device or file */ if (lseek(data->fd, data->offset+len-4, SEEK_SET) == -1) { MESSAGE(VERB_LOW, "CRC: lseek() failed\n"); return; } if (write(data->fd, &crc, sizeof(crc)) == -1) { MESSAGE(VERB_LOW, "CRC: write() failed\n"); return; } /* keep our buffer in sync with the device or file */ memcpy(buf+len-4, &crc, sizeof(crc)); /* Show new */ memcpy(&crc, buf+len-4, sizeof(crc)); fix_endian32(&crc, swab); MESSAGE(VERB_NORMAL, "New CRC: %04x\n", crc); } redboot-tools-0.7build3/fconfig/crc.h0000775000000000000000000000106611260157267014517 0ustar /* * crc.h * * $Id: crc.h,v 1.1 2006/02/13 09:58:08 andrzej Exp $ * * Gary S. Brown's CRC - header. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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. */ #ifndef CRC_H #define CRC_H #include uint32_t crc32(uint8_t *s, uint32_t len); #endif //CRC_H redboot-tools-0.7build3/fconfig/Makefile0000775000000000000000000000073411260157267015240 0ustar NAME = fconfig SRC = fconfig.c debug.c crc.c ftypes.c crunchfc.c OBJ = $(subst .c,.o, $(SRC)) all: $(NAME) %.d: %.c $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \ | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \ [ -s $@ ] || rm -f $@' ifneq ($(MAKECMDGOALS), clean) -include $(SRC:.c=.d) endif $(NAME): $(OBJ) $(CC) $(LDFLAGS) -o $@ $(OBJ) $(LDLIBS) romfs: [ "$(CONFIG_USER_FCONFIG_FCONFIG)" != y ] \ || cp $(NAME) $(ROMFSDIR)/bin/. clean: -rm -f $(NAME) *.d *.o redboot-tools-0.7build3/fconfig/debug.c0000775000000000000000000000140711260157267015030 0ustar /* * debug.c * * $Id: debug.c,v 1.1 2006/02/13 09:58:08 andrzej Exp $ * * Redboot Flash Configuration parser. * Debug utilities. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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 #include "debug.h" uint8_t verbosity = VERB_LOW; void hex_dump(void *buf, uint16_t len) { uint16_t i; for (i = 0 ; i < len; i++) { printf("%02x", ((uint8_t*)buf)[i]); if (i%2) { printf(" "); } if (15 == i%16) { printf("\n"); } } printf("\n"); } redboot-tools-0.7build3/fconfig/ftypes.h0000775000000000000000000000530311260157267015260 0ustar /* * ftypes.h * * $Id: ftypes.h,v 1.1 2006/02/13 09:58:08 andrzej Exp $ * * Redboot Flash Configuration parser. * Argument parsers - header. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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. */ #ifndef FTYPES_H #define FTYPES_H typedef int8_t (*parser_t)(uint8_t *text, void *buf); typedef void (*printer_t)(void *buf); /* * This is very unfortunate that RedBoot authors didn't encode these * constants in the configuration structure. */ //CYGNUM_REDBOOT_FLASH_SCRIPT_SIZE #define MAX_SCRIPT_LENGTH 512 //CYGNUM_REDBOOT_FLASH_STRING_SIZE #define MAX_STRING_LENGTH 128 //CYGNUM_REDBOOT_FLASH_CONFIG_SIZE #define MAX_CONFIG_DATA 4096 /* * RedBoot flash configuration type description. */ #define MAX_TYPE_NAME 16 #define MAX_TYPE_SIZE MAX_CONFIG_DATA typedef struct { uint8_t type_name[MAX_TYPE_NAME]; int16_t type_size; parser_t parser; printer_t printer; } type_t; #define NUM_TYPES 8 extern type_t types[NUM_TYPES]; /* * 'data type' field encoding */ #define CONFIG_EMPTY 0 #define CONFIG_BOOL 1 #define CONFIG_INT 2 #define CONFIG_STRING 3 #define CONFIG_SCRIPT 4 #define CONFIG_IP 5 #define CONFIG_ESA 6 #define CONFIG_NETPORT 7 /* * Size assumptions (may not be valid for all platforms!): * - bool: assuming 4 bytes (might be 2) * - int: assuming 4 bytes (might be 2) * MAX_STRING_LENGTH and MAX_SCRIPT_LENGTH depend on RedBoot configuration * and are not encoded anywhere within the structure. */ #define SIZE_EMPTY 0 #define SIZE_BOOL 4 #define SIZE_INT 4 #define SIZE_STRING MAX_STRING_LENGTH #define SIZE_SCRIPT MAX_SCRIPT_LENGTH #define SIZE_IP 4 #define SIZE_ESA 8 #define SIZE_NETPORT MAX_STRING_LENGTH #define TYPE_NAME(index) (types[index].type_name) #define TYPE_SIZE(index) (types[index].type_size) #define TYPE_PARSER(index) (types[index].parser) #define TYPE_PRINTER(index) (types[index].printer) int8_t verify_ftype(uint8_t type); int8_t parse_bool(uint8_t *text, void *buf); int8_t parse_int(uint8_t *text, void *buf); int8_t parse_script(uint8_t *text, void *buf); int8_t parse_string(uint8_t *text, void *buf); int8_t parse_ip(uint8_t *text, void *buf); int8_t parse_esa(uint8_t *text, void *buf); int8_t parse_netport(uint8_t *text, void *buf); void print_bool(void *buf); void print_int(void *buf); void print_string(void *buf); void print_script(void *buf); void print_ip(void *buf); void print_esa(void *buf); void print_netport(void *buf); #endif //FTYPES_H redboot-tools-0.7build3/fconfig/ftypes.c0000775000000000000000000001147711260157267015264 0ustar /* * parsers.c * * $Id: ftypes.c,v 1.3 2006/02/20 08:02:24 andrzej Exp $ * * Redboot Flash Configuration parser. * Argument parsers. * * Copyright (C) 2006 Ekiert sp z o.o. * Author: Andrzej Ekiert * * 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. */ /* For inet_aton() and inet_ntoa() */ #include #include #include /* For ether_aton */ #include #include #include #include #include #include #include #include #include "ftypes.h" #include "debug.h" /* * The table of all supported types. */ type_t types[NUM_TYPES] = { {"empty", SIZE_EMPTY, NULL, NULL}, {"bool", SIZE_BOOL, parse_bool, print_bool}, {"int", SIZE_INT, parse_int, print_int}, {"string", SIZE_STRING, parse_string, print_string}, {"script", SIZE_SCRIPT, parse_script, print_script}, {"ip", SIZE_IP, parse_ip, print_ip}, {"esa", SIZE_ESA, parse_esa, print_esa}, {"netport", SIZE_NETPORT, parse_netport, print_netport} }; int8_t verify_ftype(uint8_t type) { return (type < NUM_TYPES); } /* All parsers return non-zero code on failure */ /* * Convert a string to a boolean. * Buffer 'buf' must be at least 4 bytes long and aligned for uint32_t. */ int8_t parse_bool(uint8_t *text, void *buf) { if (strcasecmp(text, "TRUE")==0) { *(uint32_t*)buf = 1; return 0; } else if (strcasecmp(text, "FALSE")==0) { *(uint32_t*)buf = 0; return 0; } else { return -1; } return 0; } /* * Print 'TRUE' or 'FALSE'. */ void print_bool(void *buf) { uint32_t val; memcpy(&val, buf, sizeof(val)); if (val) { printf("TRUE"); } else { printf("FALSE"); } } /* * Convert a string to a 32 bit unsigned integer. * Buffer 'buf' must be at least 4 bytes long and aligned for uint32_t. */ int8_t parse_int(uint8_t *text, void *buf) { errno = 0; *(uint32_t*)buf = strtoul(text, (char**)NULL, 0); return errno; } /* * Print a 32 bit unsigned integer. * 'buf' should point to such integer. */ void print_int(void *buf) { uint32_t val; memcpy(&val, buf, sizeof(val)); printf("%d", val); } /* * Parsing a string is nothing but copying up to MAX_STRING_LENGTH-1 characters * from 'text' to 'buf'. Copying fails, if the result is not null-terminated. */ int8_t parse_string(uint8_t *text, void *buf) { uint8_t *dest = (uint8_t*)buf; dest[MAX_STRING_LENGTH-1]='\0'; strncpy(dest, text, MAX_STRING_LENGTH); if (dest[MAX_STRING_LENGTH-1]!='\0') { dest[MAX_STRING_LENGTH-1]='\0'; return -1; } return 0; } /* * Print a string. */ void print_string(void *buf) { uint8_t *str = (uint8_t*)buf; printf("%s", str); } /* * Parsing a script is nothing but copying up to MAX_SCRIPT_LENGTH-1 characters * from 'text' to 'buf', except that all '\' characters replaced with newlines. * Copying fails, if the result is not null-terminated. * Returns 0 on failure. */ int8_t parse_script(uint8_t *text, void *buf) { uint8_t *dest = (uint8_t*)buf; dest[MAX_SCRIPT_LENGTH-1]='\0'; strncpy(dest, text, MAX_SCRIPT_LENGTH); if (dest[MAX_SCRIPT_LENGTH-1]!='\0') { dest[MAX_SCRIPT_LENGTH-1]='\0'; return -1; } while (*dest!='\0') { if (*dest == '\\') { *dest = '\n'; } dest++; } return 0; } /* * Print a script. */ void print_script(void *buf) { uint8_t *str = (uint8_t*)buf; printf("%s", str); } /* * Convert dotted-decimal IPv4 address string into binary data. * Buffer 'buf' must be able to hold 'struct in_addr' (4 bytes currently). * The buffer must be aligned. */ int8_t parse_ip(uint8_t *text, void *buf) { return !inet_aton(text, buf); } /* * Print an IPv4 address in dotted-decimal notation. */ void print_ip(void *buf) { struct in_addr addr; memcpy(&addr, buf, sizeof(addr)); printf("%s", inet_ntoa(addr)); } /* * Convert a string containing ethernet MAC address * in a "01:23:45:67:89:ab" form to a 6 byte table. * Buffer 'buf' must be able to hold 'struct ether_addr' (6 bytes currently). */ int8_t parse_esa(uint8_t *text, void *buf) { struct ether_addr *addr = ether_aton(text); if (addr == NULL) { return -1; } memcpy(buf, addr, sizeof(struct ether_addr)); return 0; } /* * Convert to a standard colon-separated string and print * an ethernet MAC address. */ void print_esa(void *buf) { uint8_t *e = (uint8_t*)buf; printf("%02x:%02x:%02x:%02x:%02x:%02x", e[0], e[1], e[2], e[3], e[4], e[5]); } /* * Parse 'netport' name. * 'NETPORT' is just a string. */ int8_t parse_netport(uint8_t *text, void *buf) { return parse_string(text, buf); } /* * Print 'netport' name. * 'NETPORT' is just a string. */ void print_netport(void *buf) { print_string(buf); } redboot-tools-0.7build3/Makefile0000664000000000000000000000014611260157267013617 0ustar all clean: $(MAKE) -C fconfig $@ CFLAGS="$(CFLAGS)" $(MAKE) -C fis $@ CFLAGS="$(CFLAGS) --std=c99" redboot-tools-0.7build3/redboot-cmdline/0000775000000000000000000000000011260157267015225 5ustar redboot-tools-0.7build3/redboot-cmdline/redboot-cmdline0000775000000000000000000000426711260157267020233 0ustar #!/bin/sh # # redboot-cmdline # - a tool to easily edit the kernel cmdline in fconfig # # Copyright (c) 2009 Canonical # Author: Oliver Grawert # # 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. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. set -e DEV="/dev/mmcblk0" OFST="0x5F000" DO_READ="" CMDLINE="" usage() { echo "usage: $(basename $0) -r|-w \"\"" echo echo " -r read existing cmdline" echo " -w \"\" write \"\" to fis" echo " -d write to or image" echo " -o override to config data" echo exit 0 } checkparm() { if [ "$(echo $1|grep ^'\-')" ] || [ -z "$1" ];then echo "E: Need an argument" usage fi } while [ ! -z "$1" ]; do case $1 in -h|--help) usage ;; -d|--device) checkparm $2 DEV="$2" ;; -o|--offset) checkparm $2 OFST="$2" ;; -r|--read) DO_READ="True" ;; -w|--write) checkparm $2 CMDLINE="$2" esac shift done if [ ! -e "${DEV}" ] || [ ! -w "${DEV}" ];then echo "E: cannot access $DEV (does $DEV exist ?)" exit 0 fi CMD="fconfig -s -r -d ${DEV} -o ${OFST} -n boot_script_data" if [ -n "${DO_READ}" ];then echo $(echo $(${CMD})|sed -e 's/^.*\"\(.*\)\".*$/\1/') exit 0 fi if [ -n "${CMDLINE}" ];then NEWSCRIPT="$(echo "$(${CMD})"|sed s/\"[^]]*\"/\""${CMDLINE}"\"/g)\\" fconfig -s -w -d ${DEV} -o ${OFST} -n boot_script_data -x "${NEWSCRIPT}" exit 0 fi