mirror of
https://github.com/openwrt/openwrt.git
synced 2025-02-22 10:01:03 +00:00
packages/boot: remove rbcfg
The new sysfs soft_config driver makes buggy rbcfg obsolete and entirely replaces it. Signed-off-by: Thibaut VARÈNE <hacks@slashdirt.org>
This commit is contained in:
parent
48b14b9cbe
commit
f10da7cb4d
@ -1,47 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
|
|
||||||
#
|
|
||||||
# This is free software, licensed under the GNU General Public License v2.
|
|
||||||
# See /LICENSE for more information.
|
|
||||||
#
|
|
||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
|
||||||
|
|
||||||
PKG_NAME:=rbcfg
|
|
||||||
PKG_RELEASE:=3
|
|
||||||
|
|
||||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
|
||||||
|
|
||||||
PKG_FLAGS:=nonshared
|
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
|
||||||
|
|
||||||
define Package/rbcfg
|
|
||||||
SECTION:=utils
|
|
||||||
CATEGORY:=Utilities
|
|
||||||
SUBMENU:=Boot Loaders
|
|
||||||
TITLE:=RouterBOOT configuration tool
|
|
||||||
DEPENDS:=@(TARGET_ar71xx||TARGET_ath79)
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Package/rbcfg/description
|
|
||||||
This package contains an utility to manipulate RouterBOOT configuration on the
|
|
||||||
MikroTIK RB-4XX devices.
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Build/Configure
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Build/Compile
|
|
||||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
|
||||||
CC="$(TARGET_CC)" \
|
|
||||||
CFLAGS="$(TARGET_CFLAGS) -Wall" \
|
|
||||||
LDFLAGS="$(TARGET_LDFLAGS)"
|
|
||||||
endef
|
|
||||||
|
|
||||||
define Package/rbcfg/install
|
|
||||||
$(INSTALL_DIR) $(1)/usr/sbin
|
|
||||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/rbcfg $(1)/usr/sbin/
|
|
||||||
endef
|
|
||||||
|
|
||||||
$(eval $(call BuildPackage,rbcfg))
|
|
@ -1,14 +0,0 @@
|
|||||||
CC = gcc
|
|
||||||
CFLAGS = -Wall
|
|
||||||
OBJS = main.o cyg_crc32.o
|
|
||||||
|
|
||||||
all: rbcfg
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
rbcfg: $(OBJS)
|
|
||||||
$(CC) -o $@ $(OBJS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f rbcfg *.o
|
|
@ -1,109 +0,0 @@
|
|||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// crc.h
|
|
||||||
//
|
|
||||||
// Interface for the CRC algorithms.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
//####ECOSGPLCOPYRIGHTBEGIN####
|
|
||||||
// -------------------------------------------
|
|
||||||
// This file is part of eCos, the Embedded Configurable Operating System.
|
|
||||||
// Copyright (C) 2002 Andrew Lunn
|
|
||||||
//
|
|
||||||
// eCos 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 or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
||||||
//
|
|
||||||
// As a special exception, if other files instantiate templates or use macros
|
|
||||||
// or inline functions from this file, or you compile this file and link it
|
|
||||||
// with other works to produce a work based on this file, this file does not
|
|
||||||
// by itself cause the resulting work to be covered by the GNU General Public
|
|
||||||
// License. However the source code for this file must still be made available
|
|
||||||
// in accordance with section (3) of the GNU General Public License.
|
|
||||||
//
|
|
||||||
// This exception does not invalidate any other reasons why a work based on
|
|
||||||
// this file might be covered by the GNU General Public License.
|
|
||||||
//
|
|
||||||
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
|
||||||
// at http://sources.redhat.com/ecos/ecos-license/
|
|
||||||
// -------------------------------------------
|
|
||||||
//####ECOSGPLCOPYRIGHTEND####
|
|
||||||
//==========================================================================
|
|
||||||
//#####DESCRIPTIONBEGIN####
|
|
||||||
//
|
|
||||||
// Author(s): Andrew Lunn
|
|
||||||
// Contributors: Andrew Lunn
|
|
||||||
// Date: 2002-08-06
|
|
||||||
// Purpose:
|
|
||||||
// Description:
|
|
||||||
//
|
|
||||||
// This code is part of eCos (tm).
|
|
||||||
//
|
|
||||||
//####DESCRIPTIONEND####
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
#ifndef _SERVICES_CRC_CRC_H_
|
|
||||||
#define _SERVICES_CRC_CRC_H_
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#include <cyg/infra/cyg_type.h>
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef uint32_t cyg_uint32;
|
|
||||||
typedef uint16_t cyg_uint16;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __externC
|
|
||||||
# ifdef __cplusplus
|
|
||||||
# define __externC extern "C"
|
|
||||||
# else
|
|
||||||
# define __externC extern
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Compute a CRC, using the POSIX 1003 definition
|
|
||||||
|
|
||||||
__externC cyg_uint32
|
|
||||||
cyg_posix_crc32(unsigned char *s, int len);
|
|
||||||
|
|
||||||
// Gary S. Brown's 32 bit CRC
|
|
||||||
|
|
||||||
__externC cyg_uint32
|
|
||||||
cyg_crc32(unsigned char *s, int len);
|
|
||||||
|
|
||||||
// Gary S. Brown's 32 bit CRC, but accumulate the result from a
|
|
||||||
// previous CRC calculation
|
|
||||||
|
|
||||||
__externC cyg_uint32
|
|
||||||
cyg_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len);
|
|
||||||
|
|
||||||
// Ethernet FCS Algorithm
|
|
||||||
|
|
||||||
__externC cyg_uint32
|
|
||||||
cyg_ether_crc32(unsigned char *s, int len);
|
|
||||||
|
|
||||||
// Ethernet FCS algorithm, but accumulate the result from a previous
|
|
||||||
// CRC calculation.
|
|
||||||
|
|
||||||
__externC cyg_uint32
|
|
||||||
cyg_ether_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len);
|
|
||||||
|
|
||||||
// 16 bit CRC with polynomial x^16+x^12+x^5+1
|
|
||||||
|
|
||||||
__externC cyg_uint16
|
|
||||||
cyg_crc16(unsigned char *s, int len);
|
|
||||||
|
|
||||||
#endif // _SERVICES_CRC_CRC_H_
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
|||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// crc32.c
|
|
||||||
//
|
|
||||||
// Gary S. Brown's 32 bit CRC
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
//####ECOSGPLCOPYRIGHTBEGIN####
|
|
||||||
// -------------------------------------------
|
|
||||||
// This file is part of eCos, the Embedded Configurable Operating System.
|
|
||||||
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
|
||||||
// Copyright (C) 2002 Gary Thomas
|
|
||||||
//
|
|
||||||
// eCos 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 or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
|
||||||
//
|
|
||||||
// As a special exception, if other files instantiate templates or use macros
|
|
||||||
// or inline functions from this file, or you compile this file and link it
|
|
||||||
// with other works to produce a work based on this file, this file does not
|
|
||||||
// by itself cause the resulting work to be covered by the GNU General Public
|
|
||||||
// License. However the source code for this file must still be made available
|
|
||||||
// in accordance with section (3) of the GNU General Public License.
|
|
||||||
//
|
|
||||||
// This exception does not invalidate any other reasons why a work based on
|
|
||||||
// this file might be covered by the GNU General Public License.
|
|
||||||
//
|
|
||||||
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
|
||||||
// at http://sources.redhat.com/ecos/ecos-license/
|
|
||||||
// -------------------------------------------
|
|
||||||
//####ECOSGPLCOPYRIGHTEND####
|
|
||||||
//==========================================================================
|
|
||||||
//#####DESCRIPTIONBEGIN####
|
|
||||||
//
|
|
||||||
// Author(s): gthomas
|
|
||||||
// Contributors: gthomas,asl
|
|
||||||
// Date: 2001-01-31
|
|
||||||
// Purpose:
|
|
||||||
// Description:
|
|
||||||
//
|
|
||||||
// This code is part of eCos (tm).
|
|
||||||
//
|
|
||||||
//####DESCRIPTIONEND####
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#include <cyg/crc/crc.h>
|
|
||||||
#else
|
|
||||||
#include "cyg_crc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ====================================================================== */
|
|
||||||
/* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */
|
|
||||||
/* code or tables extracted from it, as desired without restriction. */
|
|
||||||
/* */
|
|
||||||
/* First, the polynomial itself and its table of feedback terms. The */
|
|
||||||
/* 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 */
|
|
||||||
/* */
|
|
||||||
/* ====================================================================== */
|
|
||||||
|
|
||||||
static const cyg_uint32 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
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but
|
|
||||||
accumulate the CRC into the result of a previous CRC. */
|
|
||||||
cyg_uint32
|
|
||||||
cyg_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
|
|
||||||
}
|
|
||||||
return crc32val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is the standard Gary S. Brown's 32 bit CRC algorithm */
|
|
||||||
cyg_uint32
|
|
||||||
cyg_crc32(unsigned char *s, int len)
|
|
||||||
{
|
|
||||||
return (cyg_crc32_accumulate(0,s,len));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a 32-bit CRC of the contents of the buffer accumulating the
|
|
||||||
result from a previous CRC calculation. This uses the Ethernet FCS
|
|
||||||
algorithm.*/
|
|
||||||
cyg_uint32
|
|
||||||
cyg_ether_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (s == 0) return 0L;
|
|
||||||
|
|
||||||
crc32val = crc32val ^ 0xffffffff;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8);
|
|
||||||
}
|
|
||||||
return crc32val ^ 0xffffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return a 32-bit CRC of the contents of the buffer, using the
|
|
||||||
Ethernet FCS algorithm. */
|
|
||||||
cyg_uint32
|
|
||||||
cyg_ether_crc32(unsigned char *s, int len)
|
|
||||||
{
|
|
||||||
return cyg_ether_crc32_accumulate(0,s,len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,922 +0,0 @@
|
|||||||
/*
|
|
||||||
* RouterBOOT configuration utility
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
|
|
||||||
* Copyright (C) 2017 Thibaut VARENE <varenet@parisc-linux.org>
|
|
||||||
*
|
|
||||||
* 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 <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <linux/limits.h>
|
|
||||||
|
|
||||||
#include "rbcfg.h"
|
|
||||||
#include "cyg_crc.h"
|
|
||||||
|
|
||||||
#define RBCFG_TMP_FILE "/tmp/.rbcfg"
|
|
||||||
#define RBCFG_MTD_NAME "soft_config"
|
|
||||||
|
|
||||||
#define RB_ERR_NOTFOUND 1
|
|
||||||
#define RB_ERR_INVALID 2
|
|
||||||
#define RB_ERR_NOMEM 3
|
|
||||||
#define RB_ERR_IO 4
|
|
||||||
#define RB_ERR_NOTWANTED 5
|
|
||||||
|
|
||||||
#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0]))
|
|
||||||
|
|
||||||
struct rbcfg_ctx {
|
|
||||||
char *mtd_device;
|
|
||||||
char *tmp_file;
|
|
||||||
char *buf;
|
|
||||||
unsigned buflen;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rbcfg_value {
|
|
||||||
const char *name;
|
|
||||||
const char *desc;
|
|
||||||
union {
|
|
||||||
uint32_t u32;
|
|
||||||
const char *raw;
|
|
||||||
} val;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RBCFG_ENV_TYPE_U32 0
|
|
||||||
|
|
||||||
struct rbcfg_env {
|
|
||||||
const char *name;
|
|
||||||
int type;
|
|
||||||
uint16_t id;
|
|
||||||
const struct rbcfg_value *values;
|
|
||||||
int num_values;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CMD_FLAG_USES_CFG 0x01
|
|
||||||
|
|
||||||
struct rbcfg_command {
|
|
||||||
const char *command;
|
|
||||||
const char *usage;
|
|
||||||
int flags;
|
|
||||||
int (*exec)(int argc, const char *argv[]);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rbcfg_soc {
|
|
||||||
const char *needle;
|
|
||||||
const int type;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void usage(void);
|
|
||||||
|
|
||||||
/* Globals */
|
|
||||||
|
|
||||||
static struct rbcfg_ctx *rbcfg_ctx;
|
|
||||||
static char *rbcfg_name;
|
|
||||||
|
|
||||||
#define CFG_U32(_name, _desc, _val) { \
|
|
||||||
.name = (_name), \
|
|
||||||
.desc = (_desc), \
|
|
||||||
.val.u32 = (_val), \
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_boot_delay[] = {
|
|
||||||
CFG_U32("1", "1 second", RB_BOOT_DELAY_1SEC),
|
|
||||||
CFG_U32("2", "2 seconds", RB_BOOT_DELAY_2SEC),
|
|
||||||
CFG_U32("3", "3 seconds", RB_BOOT_DELAY_3SEC),
|
|
||||||
CFG_U32("4", "4 seconds", RB_BOOT_DELAY_4SEC),
|
|
||||||
CFG_U32("5", "5 seconds", RB_BOOT_DELAY_5SEC),
|
|
||||||
CFG_U32("6", "6 seconds", RB_BOOT_DELAY_6SEC),
|
|
||||||
CFG_U32("7", "7 seconds", RB_BOOT_DELAY_7SEC),
|
|
||||||
CFG_U32("8", "8 seconds", RB_BOOT_DELAY_8SEC),
|
|
||||||
CFG_U32("9", "9 seconds", RB_BOOT_DELAY_9SEC),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_boot_device[] = {
|
|
||||||
CFG_U32("eth", "boot over Ethernet",
|
|
||||||
RB_BOOT_DEVICE_ETHER),
|
|
||||||
CFG_U32("nandeth", "boot from NAND, if fail then Ethernet",
|
|
||||||
RB_BOOT_DEVICE_NANDETH),
|
|
||||||
CFG_U32("ethnand", "boot Ethernet once, then NAND",
|
|
||||||
RB_BOOT_DEVICE_ETHONCE),
|
|
||||||
CFG_U32("nand", "boot from NAND only",
|
|
||||||
RB_BOOT_DEVICE_NANDONLY),
|
|
||||||
CFG_U32("flash", "boot in flash configuration mode",
|
|
||||||
RB_BOOT_DEVICE_FLASHCFG),
|
|
||||||
CFG_U32("flashnand", "boot in flash configuration mode once, then NAND",
|
|
||||||
RB_BOOT_DEVICE_FLSHONCE),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_boot_key[] = {
|
|
||||||
CFG_U32("any", "any key", RB_BOOT_KEY_ANY),
|
|
||||||
CFG_U32("del", "<Delete> key only", RB_BOOT_KEY_DEL),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_boot_protocol[] = {
|
|
||||||
CFG_U32("bootp", "BOOTP protocol", RB_BOOT_PROTOCOL_BOOTP),
|
|
||||||
CFG_U32("dhcp", "DHCP protocol", RB_BOOT_PROTOCOL_DHCP),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_uart_speed[] = {
|
|
||||||
CFG_U32("115200", "", RB_UART_SPEED_115200),
|
|
||||||
CFG_U32("57600", "", RB_UART_SPEED_57600),
|
|
||||||
CFG_U32("38400", "", RB_UART_SPEED_38400),
|
|
||||||
CFG_U32("19200", "", RB_UART_SPEED_19200),
|
|
||||||
CFG_U32("9600", "", RB_UART_SPEED_9600),
|
|
||||||
CFG_U32("4800", "", RB_UART_SPEED_4800),
|
|
||||||
CFG_U32("2400", "", RB_UART_SPEED_2400),
|
|
||||||
CFG_U32("1200", "", RB_UART_SPEED_1200),
|
|
||||||
CFG_U32("off", "disable console output", RB_UART_SPEED_OFF),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_cpu_mode[] = {
|
|
||||||
CFG_U32("powersave", "power save", RB_CPU_MODE_POWERSAVE),
|
|
||||||
CFG_U32("regular", "regular (better for -0c environment)",
|
|
||||||
RB_CPU_MODE_REGULAR),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_cpu_freq_dummy[] = {
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_cpu_freq_qca953x[] = {
|
|
||||||
CFG_U32("-2", "-100MHz", RB_CPU_FREQ_L2),
|
|
||||||
CFG_U32("-1", "- 50MHz", RB_CPU_FREQ_L1),
|
|
||||||
CFG_U32("0", "Factory", RB_CPU_FREQ_N0),
|
|
||||||
CFG_U32("+1", "+ 50MHz", RB_CPU_FREQ_H1),
|
|
||||||
CFG_U32("+2", "+100MHz", RB_CPU_FREQ_H2),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_cpu_freq_ar9344[] = {
|
|
||||||
CFG_U32("-2", "-100MHz", RB_CPU_FREQ_L2),
|
|
||||||
CFG_U32("-1", "- 50MHz", RB_CPU_FREQ_L1),
|
|
||||||
CFG_U32("0", "Factory", RB_CPU_FREQ_N0),
|
|
||||||
CFG_U32("+1", "+ 50MHz", RB_CPU_FREQ_H1),
|
|
||||||
CFG_U32("+2", "+100MHz", RB_CPU_FREQ_H2),
|
|
||||||
CFG_U32("+3", "+150MHz", RB_CPU_FREQ_H3),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct rbcfg_value rbcfg_booter[] = {
|
|
||||||
CFG_U32("regular", "load regular booter", RB_BOOTER_REGULAR),
|
|
||||||
CFG_U32("backup", "force backup-booter loading", RB_BOOTER_BACKUP),
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct rbcfg_env rbcfg_envs[] = {
|
|
||||||
{
|
|
||||||
.name = "boot_delay",
|
|
||||||
.id = RB_ID_BOOT_DELAY,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_boot_delay,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_boot_delay),
|
|
||||||
}, {
|
|
||||||
.name = "boot_device",
|
|
||||||
.id = RB_ID_BOOT_DEVICE,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_boot_device,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_boot_device),
|
|
||||||
}, {
|
|
||||||
.name = "boot_key",
|
|
||||||
.id = RB_ID_BOOT_KEY,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_boot_key,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_boot_key),
|
|
||||||
}, {
|
|
||||||
.name = "boot_protocol",
|
|
||||||
.id = RB_ID_BOOT_PROTOCOL,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_boot_protocol,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_boot_protocol),
|
|
||||||
}, {
|
|
||||||
.name = "booter",
|
|
||||||
.id = RB_ID_BOOTER,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_booter,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_booter),
|
|
||||||
}, {
|
|
||||||
.name = "cpu_mode",
|
|
||||||
.id = RB_ID_CPU_MODE,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_cpu_mode,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_cpu_mode),
|
|
||||||
}, {
|
|
||||||
.name = "cpu_freq",
|
|
||||||
.id = RB_ID_CPU_FREQ,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_cpu_freq_dummy,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_cpu_freq_dummy),
|
|
||||||
}, {
|
|
||||||
.name = "uart_speed",
|
|
||||||
.id = RB_ID_UART_SPEED,
|
|
||||||
.type = RBCFG_ENV_TYPE_U32,
|
|
||||||
.values = rbcfg_uart_speed,
|
|
||||||
.num_values = ARRAY_SIZE(rbcfg_uart_speed),
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline uint16_t
|
|
||||||
get_u16(const void *buf)
|
|
||||||
{
|
|
||||||
const uint8_t *p = buf;
|
|
||||||
|
|
||||||
return ((uint16_t) p[1] + ((uint16_t) p[0] << 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t
|
|
||||||
get_u32(const void *buf)
|
|
||||||
{
|
|
||||||
const uint8_t *p = buf;
|
|
||||||
|
|
||||||
return ((uint32_t) p[3] + ((uint32_t) p[2] << 8) +
|
|
||||||
((uint32_t) p[1] << 16) + ((uint32_t) p[0] << 24));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
put_u32(void *buf, uint32_t val)
|
|
||||||
{
|
|
||||||
uint8_t *p = buf;
|
|
||||||
|
|
||||||
p[3] = val & 0xff;
|
|
||||||
p[2] = (val >> 8) & 0xff;
|
|
||||||
p[1] = (val >> 16) & 0xff;
|
|
||||||
p[0] = (val >> 24) & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_find_tag(struct rbcfg_ctx *ctx, uint16_t tag_id, uint16_t *tag_len,
|
|
||||||
void **tag_data)
|
|
||||||
{
|
|
||||||
uint16_t id;
|
|
||||||
uint16_t len;
|
|
||||||
char *buf = ctx->buf;
|
|
||||||
unsigned int buflen = ctx->buflen;
|
|
||||||
int ret = RB_ERR_NOTFOUND;
|
|
||||||
|
|
||||||
/* skip magic and CRC value */
|
|
||||||
buf += 8;
|
|
||||||
buflen -= 8;
|
|
||||||
|
|
||||||
while (buflen > 2) {
|
|
||||||
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) {
|
|
||||||
ret = RB_ERR_NOTWANTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buflen < len)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (id == tag_id) {
|
|
||||||
*tag_len = len;
|
|
||||||
*tag_data = buf;
|
|
||||||
ret = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf += len;
|
|
||||||
buflen -= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RB_ERR_NOTFOUND == ret)
|
|
||||||
fprintf(stderr, "no tag found with id=%u\n", tag_id);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_get_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t *val)
|
|
||||||
{
|
|
||||||
void *tag_data;
|
|
||||||
uint16_t tag_len;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
*val = get_u32(tag_data);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_set_u32(struct rbcfg_ctx *ctx, uint16_t id, uint32_t val)
|
|
||||||
{
|
|
||||||
void *tag_data;
|
|
||||||
uint16_t tag_len;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = rbcfg_find_tag(ctx, id, &tag_len, &tag_data);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
put_u32(tag_data, val);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *rbcfg_find_mtd(const char *name, int *erase_size)
|
|
||||||
{
|
|
||||||
FILE *f;
|
|
||||||
int mtd_num;
|
|
||||||
char dev[PATH_MAX];
|
|
||||||
char *ret = NULL;
|
|
||||||
struct stat s;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
f = fopen("/proc/mtd", "r");
|
|
||||||
if (!f)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
char *p;
|
|
||||||
p = fgets(dev, sizeof(dev), f);
|
|
||||||
if (!p)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!strstr(dev, name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
err = sscanf(dev, "mtd%d: %08x", &mtd_num, erase_size);
|
|
||||||
if (err != 2)
|
|
||||||
break;
|
|
||||||
|
|
||||||
sprintf(dev, "/dev/mtdblock%d", mtd_num);
|
|
||||||
err = stat(dev, &s);
|
|
||||||
if (err < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((s.st_mode & S_IFBLK) == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ret = malloc(strlen(dev) + 1);
|
|
||||||
if (ret == NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
strncpy(ret, dev, strlen(dev) + 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_check_tmp(struct rbcfg_ctx *ctx)
|
|
||||||
{
|
|
||||||
struct stat s;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = stat(ctx->tmp_file, &s);
|
|
||||||
if (err < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if ((s.st_mode & S_IFREG) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (s.st_size != ctx->buflen)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_load(struct rbcfg_ctx *ctx)
|
|
||||||
{
|
|
||||||
uint32_t magic;
|
|
||||||
uint32_t crc_orig, crc;
|
|
||||||
char *name;
|
|
||||||
int tmp;
|
|
||||||
int fd;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
tmp = rbcfg_check_tmp(ctx);
|
|
||||||
name = (tmp) ? ctx->tmp_file : ctx->mtd_device;
|
|
||||||
|
|
||||||
fd = open(name, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
fprintf(stderr, "unable to open %s\n", name);
|
|
||||||
err = RB_ERR_IO;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = read(fd, ctx->buf, ctx->buflen);
|
|
||||||
if (err != ctx->buflen) {
|
|
||||||
fprintf(stderr, "unable to read from %s\n", name);
|
|
||||||
err = RB_ERR_IO;
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
magic = get_u32(ctx->buf);
|
|
||||||
if (magic != RB_MAGIC_SOFT) {
|
|
||||||
fprintf(stderr, "invalid configuration\n");
|
|
||||||
err = RB_ERR_INVALID;
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
crc_orig = get_u32(ctx->buf + 4);
|
|
||||||
put_u32(ctx->buf + 4, 0);
|
|
||||||
crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen);
|
|
||||||
if (crc != crc_orig) {
|
|
||||||
fprintf(stderr, "configuration has CRC error\n");
|
|
||||||
err = RB_ERR_INVALID;
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = 0;
|
|
||||||
|
|
||||||
err_close:
|
|
||||||
close(fd);
|
|
||||||
err:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_open()
|
|
||||||
{
|
|
||||||
char *mtd_device;
|
|
||||||
struct rbcfg_ctx *ctx;
|
|
||||||
int buflen;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
mtd_device = rbcfg_find_mtd(RBCFG_MTD_NAME, &buflen);
|
|
||||||
if (!mtd_device) {
|
|
||||||
fprintf(stderr, "unable to find configuration\n");
|
|
||||||
return RB_ERR_NOTFOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = malloc(sizeof(struct rbcfg_ctx) + buflen);
|
|
||||||
if (ctx == NULL) {
|
|
||||||
err = RB_ERR_NOMEM;
|
|
||||||
goto err_free_mtd;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->mtd_device = mtd_device;
|
|
||||||
ctx->tmp_file = RBCFG_TMP_FILE;
|
|
||||||
ctx->buflen = buflen;
|
|
||||||
ctx->buf = (char *) &ctx[1];
|
|
||||||
|
|
||||||
err = rbcfg_load(ctx);
|
|
||||||
if (err)
|
|
||||||
goto err_free_ctx;
|
|
||||||
|
|
||||||
rbcfg_ctx = ctx;
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_free_ctx:
|
|
||||||
free(ctx);
|
|
||||||
err_free_mtd:
|
|
||||||
free(mtd_device);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_update(int tmp)
|
|
||||||
{
|
|
||||||
struct rbcfg_ctx *ctx = rbcfg_ctx;
|
|
||||||
char *name;
|
|
||||||
uint32_t crc;
|
|
||||||
int fd;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
put_u32(ctx->buf, RB_MAGIC_SOFT);
|
|
||||||
put_u32(ctx->buf + 4, 0);
|
|
||||||
crc = cyg_ether_crc32((unsigned char *) ctx->buf, ctx->buflen);
|
|
||||||
put_u32(ctx->buf + 4, crc);
|
|
||||||
|
|
||||||
name = (tmp) ? ctx->tmp_file : ctx->mtd_device;
|
|
||||||
fd = open(name, O_WRONLY | O_CREAT, 0640);
|
|
||||||
if (fd < 0) {
|
|
||||||
fprintf(stderr, "unable to open %s for writing\n", name);
|
|
||||||
err = RB_ERR_IO;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = write(fd, ctx->buf, ctx->buflen);
|
|
||||||
if (err != ctx->buflen) {
|
|
||||||
err = RB_ERR_IO;
|
|
||||||
goto out_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
fsync(fd);
|
|
||||||
err = 0;
|
|
||||||
|
|
||||||
out_close:
|
|
||||||
close(fd);
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
rbcfg_close(void)
|
|
||||||
{
|
|
||||||
struct rbcfg_ctx *ctx;
|
|
||||||
|
|
||||||
ctx = rbcfg_ctx;
|
|
||||||
free(ctx->mtd_device);
|
|
||||||
free(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct rbcfg_value *
|
|
||||||
rbcfg_env_find(const struct rbcfg_env *env, const char *name)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < env->num_values; i++) {
|
|
||||||
const struct rbcfg_value *v = &env->values[i];
|
|
||||||
|
|
||||||
if (strcmp(v->name, name) == 0)
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct rbcfg_value *
|
|
||||||
rbcfg_env_find_u32(const struct rbcfg_env *env, uint32_t val)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < env->num_values; i++) {
|
|
||||||
const struct rbcfg_value *v = &env->values[i];
|
|
||||||
|
|
||||||
if (v->val.u32 == val)
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
rbcfg_env_get_u32(const struct rbcfg_env *env)
|
|
||||||
{
|
|
||||||
const struct rbcfg_value *v;
|
|
||||||
uint32_t val;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
err = rbcfg_get_u32(rbcfg_ctx, env->id, &val);
|
|
||||||
if (err)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
v = rbcfg_env_find_u32(env, val);
|
|
||||||
if (v == NULL) {
|
|
||||||
fprintf(stderr, "unknown value %08x found for %s\n",
|
|
||||||
val, env->name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return v->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_env_set_u32(const struct rbcfg_env *env, const char *data)
|
|
||||||
{
|
|
||||||
const struct rbcfg_value *v;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
v = rbcfg_env_find(env, data);
|
|
||||||
if (v == NULL) {
|
|
||||||
fprintf(stderr, "invalid value '%s'\n", data);
|
|
||||||
return RB_ERR_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = rbcfg_set_u32(rbcfg_ctx, env->id, v->val.u32);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
rbcfg_env_get(const struct rbcfg_env *env)
|
|
||||||
{
|
|
||||||
const char *ret = NULL;
|
|
||||||
|
|
||||||
switch (env->type) {
|
|
||||||
case RBCFG_ENV_TYPE_U32:
|
|
||||||
ret = rbcfg_env_get_u32(env);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_env_set(const struct rbcfg_env *env, const char *data)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
switch (env->type) {
|
|
||||||
case RBCFG_ENV_TYPE_U32:
|
|
||||||
ret = rbcfg_env_set_u32(env, data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_cmd_apply(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
return rbcfg_update(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_cmd_help(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
usage();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_cmd_get(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
int err = RB_ERR_NOTFOUND;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (argc != 1) {
|
|
||||||
usage();
|
|
||||||
return RB_ERR_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
|
|
||||||
const struct rbcfg_env *env = &rbcfg_envs[i];
|
|
||||||
const char *value;
|
|
||||||
|
|
||||||
if (strcmp(env->name, argv[0]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
value = rbcfg_env_get(env);
|
|
||||||
if (value) {
|
|
||||||
fprintf(stdout, "%s\n", value);
|
|
||||||
err = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_cmd_set(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
int err = RB_ERR_INVALID;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
/* not enough parameters */
|
|
||||||
usage();
|
|
||||||
return RB_ERR_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
|
|
||||||
const struct rbcfg_env *env = &rbcfg_envs[i];
|
|
||||||
|
|
||||||
if (strcmp(env->name, argv[0]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
err = rbcfg_env_set(env, argv[1]);
|
|
||||||
if (err == 0)
|
|
||||||
err = rbcfg_update(1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rbcfg_cmd_show(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (argc != 0) {
|
|
||||||
usage();
|
|
||||||
return RB_ERR_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
|
|
||||||
const struct rbcfg_env *env = &rbcfg_envs[i];
|
|
||||||
const char *value;
|
|
||||||
|
|
||||||
value = rbcfg_env_get(env);
|
|
||||||
if (value)
|
|
||||||
fprintf(stdout, "%s=%s\n", env->name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct rbcfg_command rbcfg_commands[] = {
|
|
||||||
{
|
|
||||||
.command = "apply",
|
|
||||||
.usage = "apply\n"
|
|
||||||
"\t- write configuration to the mtd device",
|
|
||||||
.flags = CMD_FLAG_USES_CFG,
|
|
||||||
.exec = rbcfg_cmd_apply,
|
|
||||||
}, {
|
|
||||||
.command = "help",
|
|
||||||
.usage = "help\n"
|
|
||||||
"\t- show this screen",
|
|
||||||
.exec = rbcfg_cmd_help,
|
|
||||||
}, {
|
|
||||||
.command = "get",
|
|
||||||
.usage = "get <name>\n"
|
|
||||||
"\t- get value of the configuration option <name>",
|
|
||||||
.flags = CMD_FLAG_USES_CFG,
|
|
||||||
.exec = rbcfg_cmd_get,
|
|
||||||
}, {
|
|
||||||
.command = "set",
|
|
||||||
.usage = "set <name> <value>\n"
|
|
||||||
"\t- set value of the configuration option <name> to <value>",
|
|
||||||
.flags = CMD_FLAG_USES_CFG,
|
|
||||||
.exec = rbcfg_cmd_set,
|
|
||||||
}, {
|
|
||||||
.command = "show",
|
|
||||||
.usage = "show\n"
|
|
||||||
"\t- show value of all configuration options",
|
|
||||||
.flags = CMD_FLAG_USES_CFG,
|
|
||||||
.exec = rbcfg_cmd_show,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage(void)
|
|
||||||
{
|
|
||||||
char buf[255];
|
|
||||||
int len;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
fprintf(stderr, "Usage: %s <command>\n", rbcfg_name);
|
|
||||||
|
|
||||||
fprintf(stderr, "\nCommands:\n");
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) {
|
|
||||||
const struct rbcfg_command *cmd;
|
|
||||||
cmd = &rbcfg_commands[i];
|
|
||||||
|
|
||||||
len = snprintf(buf, sizeof(buf), "%s", cmd->usage);
|
|
||||||
buf[len] = '\0';
|
|
||||||
fprintf(stderr, "%s\n", buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "\nConfiguration options:\n");
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
|
|
||||||
const struct rbcfg_env *env;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
env = &rbcfg_envs[i];
|
|
||||||
fprintf(stderr, "\n%s:\n", env->name);
|
|
||||||
for (j = 0; j < env->num_values; j++) {
|
|
||||||
const struct rbcfg_value *v = &env->values[j];
|
|
||||||
fprintf(stderr, "\t%-12s %s\n", v->name, v->desc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(stderr, "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#define RBCFG_SOC_UNKNOWN 0
|
|
||||||
#define RBCFG_SOC_QCA953X 1
|
|
||||||
#define RBCFG_SOC_AR9344 2
|
|
||||||
|
|
||||||
static const struct rbcfg_soc rbcfg_socs[] = {
|
|
||||||
{
|
|
||||||
.needle = "QCA953",
|
|
||||||
.type = RBCFG_SOC_QCA953X,
|
|
||||||
}, {
|
|
||||||
.needle = "AR9344",
|
|
||||||
.type = RBCFG_SOC_AR9344,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CPUINFO_BUFSIZE 128 /* lines of interest are < 80 chars */
|
|
||||||
|
|
||||||
static int cpuinfo_find_soc(void)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
char temp[CPUINFO_BUFSIZE];
|
|
||||||
char *haystack, *needle;
|
|
||||||
int i, found = 0, soc_type = RBCFG_SOC_UNKNOWN;
|
|
||||||
|
|
||||||
fp = fopen("/proc/cpuinfo", "r");
|
|
||||||
if (!fp)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* first, extract the system type line */
|
|
||||||
needle = "system type";
|
|
||||||
while(fgets(temp, CPUINFO_BUFSIZE, fp)) {
|
|
||||||
if (!strncmp(temp, needle, strlen(needle))) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
/* failsafe in case cpuinfo format changes */
|
|
||||||
if (!found)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* skip the field header */
|
|
||||||
haystack = strchr(temp, ':');
|
|
||||||
|
|
||||||
/* then, try to identify known SoC, stop at first match */
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_socs); i++) {
|
|
||||||
if ((strstr(haystack, rbcfg_socs[i].needle))) {
|
|
||||||
soc_type = rbcfg_socs[i].type;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
return soc_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fixup_rbcfg_envs(void)
|
|
||||||
{
|
|
||||||
int i, num_val, soc_type;
|
|
||||||
const struct rbcfg_value * env_value;
|
|
||||||
|
|
||||||
/* detect SoC */
|
|
||||||
soc_type = cpuinfo_find_soc();
|
|
||||||
|
|
||||||
/* update rbcfg_envs */
|
|
||||||
switch (soc_type) {
|
|
||||||
case RBCFG_SOC_QCA953X:
|
|
||||||
env_value = rbcfg_cpu_freq_qca953x;
|
|
||||||
num_val = ARRAY_SIZE(rbcfg_cpu_freq_qca953x);
|
|
||||||
break;
|
|
||||||
case RBCFG_SOC_AR9344:
|
|
||||||
env_value = rbcfg_cpu_freq_ar9344;
|
|
||||||
num_val = ARRAY_SIZE(rbcfg_cpu_freq_ar9344);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_envs); i++) {
|
|
||||||
if (RB_ID_CPU_FREQ == rbcfg_envs[i].id) {
|
|
||||||
if (RBCFG_SOC_UNKNOWN == soc_type)
|
|
||||||
rbcfg_envs[i].id = RB_ID_TERMINATOR;
|
|
||||||
else {
|
|
||||||
rbcfg_envs[i].values = env_value;
|
|
||||||
rbcfg_envs[i].num_values = num_val;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, const char *argv[])
|
|
||||||
{
|
|
||||||
const struct rbcfg_command *cmd = NULL;
|
|
||||||
int ret;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rbcfg_name = (char *) argv[0];
|
|
||||||
|
|
||||||
fixup_rbcfg_envs();
|
|
||||||
|
|
||||||
if (argc < 2) {
|
|
||||||
usage();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(rbcfg_commands); i++) {
|
|
||||||
if (strcmp(rbcfg_commands[i].command, argv[1]) == 0) {
|
|
||||||
cmd = &rbcfg_commands[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd == NULL) {
|
|
||||||
fprintf(stderr, "unknown command '%s'\n", argv[1]);
|
|
||||||
usage();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
argc -= 2;
|
|
||||||
argv += 2;
|
|
||||||
|
|
||||||
if (cmd->flags & CMD_FLAG_USES_CFG) {
|
|
||||||
ret = rbcfg_open();
|
|
||||||
if (ret)
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = cmd->exec(argc, argv);
|
|
||||||
|
|
||||||
if (cmd->flags & CMD_FLAG_USES_CFG)
|
|
||||||
rbcfg_close();
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Mikrotik's RouterBOOT configuration defines
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _RBCFG_H
|
|
||||||
#define _RBCFG_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Magic numbers
|
|
||||||
*/
|
|
||||||
#define RB_MAGIC_SOFT 0x74666f53 /* 'Soft' */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ID values for Software settings
|
|
||||||
*/
|
|
||||||
#define RB_ID_TERMINATOR 0
|
|
||||||
#define RB_ID_UART_SPEED 1
|
|
||||||
#define RB_ID_BOOT_DELAY 2
|
|
||||||
#define RB_ID_BOOT_DEVICE 3
|
|
||||||
#define RB_ID_BOOT_KEY 4
|
|
||||||
#define RB_ID_CPU_MODE 5
|
|
||||||
#define RB_ID_FW_VERSION 6
|
|
||||||
#define RB_ID_SOFT_07 7
|
|
||||||
#define RB_ID_SOFT_08 8
|
|
||||||
#define RB_ID_BOOT_PROTOCOL 9
|
|
||||||
#define RB_ID_SOFT_10 10
|
|
||||||
#define RB_ID_SOFT_11 11
|
|
||||||
#define RB_ID_CPU_FREQ 12
|
|
||||||
#define RB_ID_BOOTER 13
|
|
||||||
|
|
||||||
#define RB_UART_SPEED_115200 0
|
|
||||||
#define RB_UART_SPEED_57600 1
|
|
||||||
#define RB_UART_SPEED_38400 2
|
|
||||||
#define RB_UART_SPEED_19200 3
|
|
||||||
#define RB_UART_SPEED_9600 4
|
|
||||||
#define RB_UART_SPEED_4800 5
|
|
||||||
#define RB_UART_SPEED_2400 6
|
|
||||||
#define RB_UART_SPEED_1200 7
|
|
||||||
#define RB_UART_SPEED_OFF 8
|
|
||||||
|
|
||||||
#define RB_BOOT_DELAY_1SEC 1
|
|
||||||
#define RB_BOOT_DELAY_2SEC 2
|
|
||||||
#define RB_BOOT_DELAY_3SEC 3
|
|
||||||
#define RB_BOOT_DELAY_4SEC 4
|
|
||||||
#define RB_BOOT_DELAY_5SEC 5
|
|
||||||
#define RB_BOOT_DELAY_6SEC 6
|
|
||||||
#define RB_BOOT_DELAY_7SEC 7
|
|
||||||
#define RB_BOOT_DELAY_8SEC 8
|
|
||||||
#define RB_BOOT_DELAY_9SEC 9
|
|
||||||
|
|
||||||
#define RB_BOOT_DEVICE_ETHER 0
|
|
||||||
#define RB_BOOT_DEVICE_NANDETH 1
|
|
||||||
#define RB_BOOT_DEVICE_CFCARD 2
|
|
||||||
#define RB_BOOT_DEVICE_ETHONCE 3
|
|
||||||
#define RB_BOOT_DEVICE_NANDONLY 5
|
|
||||||
#define RB_BOOT_DEVICE_FLASHCFG 7
|
|
||||||
#define RB_BOOT_DEVICE_FLSHONCE 8
|
|
||||||
|
|
||||||
#define RB_BOOT_KEY_ANY 0
|
|
||||||
#define RB_BOOT_KEY_DEL 1
|
|
||||||
|
|
||||||
#define RB_CPU_MODE_POWERSAVE 0
|
|
||||||
#define RB_CPU_MODE_REGULAR 1
|
|
||||||
|
|
||||||
#define RB_BOOT_PROTOCOL_BOOTP 0
|
|
||||||
#define RB_BOOT_PROTOCOL_DHCP 1
|
|
||||||
|
|
||||||
#define RB_CPU_FREQ_L2 (0 << 3)
|
|
||||||
#define RB_CPU_FREQ_L1 (1 << 3)
|
|
||||||
#define RB_CPU_FREQ_N0 (2 << 3)
|
|
||||||
#define RB_CPU_FREQ_H1 (3 << 3)
|
|
||||||
#define RB_CPU_FREQ_H2 (4 << 3)
|
|
||||||
#define RB_CPU_FREQ_H3 (5 << 3)
|
|
||||||
|
|
||||||
#define RB_BOOTER_REGULAR 0
|
|
||||||
#define RB_BOOTER_BACKUP 1
|
|
||||||
|
|
||||||
#endif /* _RBCFG_H */
|
|
@ -43,7 +43,7 @@ TARGET_DEVICES += nand-large-ac
|
|||||||
define Device/rb-nor-flash-16M
|
define Device/rb-nor-flash-16M
|
||||||
$(Device/mikrotik)
|
$(Device/mikrotik)
|
||||||
DEVICE_TITLE := MikroTik RouterBoard (16 MB SPI NOR)
|
DEVICE_TITLE := MikroTik RouterBoard (16 MB SPI NOR)
|
||||||
DEVICE_PACKAGES := rbcfg rssileds -nand-utils kmod-ledtrig-gpio
|
DEVICE_PACKAGES := rssileds -nand-utils kmod-ledtrig-gpio
|
||||||
IMAGE_SIZE := 16000k
|
IMAGE_SIZE := 16000k
|
||||||
KERNEL_INSTALL := 1
|
KERNEL_INSTALL := 1
|
||||||
SUPPORTED_DEVICES := rb-750-r2 rb-750up-r2 rb-750p-pbr2 rb-911-2hn rb-911-5hn rb-931-2nd rb-941-2nd rb-951ui-2nd rb-952ui-5ac2nd rb-962uigs-5hact2hnt rb-lhg-5nd rb-map-2nd rb-mapl-2nd rb-wap-2nd rb-wapr-2nd rb-sxt-2nd-r3
|
SUPPORTED_DEVICES := rb-750-r2 rb-750up-r2 rb-750p-pbr2 rb-911-2hn rb-911-5hn rb-931-2nd rb-941-2nd rb-951ui-2nd rb-952ui-5ac2nd rb-962uigs-5hact2hnt rb-lhg-5nd rb-map-2nd rb-mapl-2nd rb-wap-2nd rb-wapr-2nd rb-sxt-2nd-r3
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
define Device/mikrotik
|
define Device/mikrotik
|
||||||
DEVICE_VENDOR := MikroTik
|
DEVICE_VENDOR := MikroTik
|
||||||
DEVICE_PACKAGES := rbcfg
|
|
||||||
LOADER_TYPE := elf
|
LOADER_TYPE := elf
|
||||||
KERNEL := kernel-bin | append-dtb | lzma | loader-kernel
|
KERNEL := kernel-bin | append-dtb | lzma | loader-kernel
|
||||||
KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel
|
KERNEL_INITRAMFS := kernel-bin | append-dtb | lzma | loader-kernel
|
||||||
|
Loading…
x
Reference in New Issue
Block a user