sysmobts-v2: Introduce a recovery command to reflash the system image

When pressing the reset button on boot the system will enter the
recovery mode, this is done by setting a preboot command. Inside the
preboot command we will sleep and then check if the button is still
pressed, then tftp will be used to download the image and flash it. If
something fails after the DHCP state the network console will be
enabled.

recovery: Make it possible to force the recovery

For factory flashing it is the easiest if we can force the
recovery process. Parse the "force" from a potential second
argument and then skip the timeout.
This commit is contained in:
Holger Hans Peter Freyther 2012-07-14 13:16:49 +02:00 committed by Holger Hans Peter Freyther
parent 14b386f1dc
commit ef64beafdc
5 changed files with 170 additions and 3 deletions

View File

@ -32,6 +32,7 @@
#include <i2c.h>
#include <asm/arch/hardware.h>
#include <asm/arch/davinci_misc.h>
#include <asm/gpio.h>
#define DAVINCI_PLLM (0x01C40910) /* PLL 1 Multiplier */
#define DAVINCI_AWCCR (0x01E00004) /* EMIF-A async wait cycle config register. */
@ -139,12 +140,24 @@ int board_init(void)
lpsc_on(DAVINCI_LPSC_TIMER1);
timer_init();
/* configure LEDs */
status_led_set(0, CONFIG_LED_STATUS_OFF);
return(0);
}
int board_late_init(void)
{
#ifdef CONFIG_PREBOOT
/* remember if we are in reset */
if (gpio_get_value(38) == 0) {
setenv("preboot", "run_recovery");
status_led_set(0, CONFIG_LED_STATUS_ON);
} else {
/* configure LEDs */
status_led_set(0, CONFIG_LED_STATUS_OFF);
}
#endif
return 0;
}
int misc_init_r(void)
{
uint8_t eeprom_enetaddr[6];

View File

@ -63,6 +63,7 @@ ifdef CONFIG_CMD_USB
obj-y += usb.o usb_hub.o
obj-$(CONFIG_USB_STORAGE) += usb_storage.o
endif
obj-$(CONFIG_CMD_RECOVERY) += cmd_recovery.o
# others
obj-$(CONFIG_BOOTSTAGE) += bootstage.o

144
common/cmd_recovery.c Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright (C) 2012, 2013, 2015, 2017 sysmocom s.f.m.c. GmbH
* Author: Holger Hans Peter Freyther
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <common.h>
#include <command.h>
#include <status_led.h>
#include <asm/gpio.h>
#define BLINK_LED(LEN) \
do { \
int i; \
for (i = 0; i < LEN; ++i) { \
status_led_set(0, CONFIG_LED_STATUS_OFF); \
udelay(900); \
status_led_set(0, CONFIG_LED_STATUS_ON); \
} \
status_led_set(0, CONFIG_LED_STATUS_OFF); \
} while(0);
static int enable_netconsole(void)
{
printf("Enabling the network console.\n");
/* reset in 60s if it is not interrupted */
return run_command("setenv stdout nc; setenv stdin nc", 0);
}
static int env_failed(void)
{
printf("Environment clearing failed.\n");
BLINK_LED(7);
return -1;
}
static int dhcp_failed(void)
{
printf("DHCP failed. Giving up on recovery.\n");
BLINK_LED(10);
return -1;
}
static int tftp_failed(void)
{
printf("TFTP failed.\n");
BLINK_LED(13);
enable_netconsole();
return -1;
}
static int flash_failed(void)
{
printf("Flash failed.\n");
BLINK_LED(15);
enable_netconsole();
return -1;
}
/**
* This will run the recovery process.
* 1.) Enable the LED to give instant feedback.
* 2.) Clear the environment in case of bad configuration.
* 3.) Get a DHCP lease.
* 4.) Try to tftpboot
* 5.) Try to tftpboot with a different server
* 6.) Flash
* 7.) Reset or enter netconsole
*/
static int do_run_recovery(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int rc;
status_led_set(0, CONFIG_LED_STATUS_ON);
printf("Starting the recovery process.\n");
/* Wait a bit and check if the reset button is still pressed */
if (argc == 2 && strcmp(argv[1], "force") == 0) {
printf("Forcing the recovery process.\n");
} else {
run_command("sleep 5", 0);
if (gpio_get_value(38) != 0) {
printf("Recovery process aborted.\n");
run_command("dhcp", 0);
enable_netconsole();
BLINK_LED(4);
return 0;
}
}
BLINK_LED(5);
status_led_set(0, CONFIG_LED_STATUS_ON);
rc = run_command("mtdpart default; "
"nand erase.part U-Boot-Environment", 0);
if (rc != 0)
return env_failed();
rc = run_command("setenv autoload no; setenv netretry no; dhcp", 0);
if (rc != 0)
return dhcp_failed();
rc = run_command("setenv filesize 0; "
"tftp 85000000 sysmocom-recovery.ubi", 0);
if (rc != 0) {
rc = run_command("setenv filesize 0; "
"setenv serverip 255.255.255.255; "
"tftp 85000000 sysmocom-recovery.ubi", 0);
}
if (rc != 0)
return tftp_failed();
rc = run_command("nand erase.part RootFs; "
"nand write 85000000 RootFs ${filesize} ", 0);
if (rc != 0)
return flash_failed();
return run_command("reset", 0);
}
U_BOOT_CMD(
run_recovery, CONFIG_SYS_MAXARGS, 1, do_run_recovery,
"Run the sysmocom sysmoBTS recovery process",
"[force]"
);

View File

@ -189,6 +189,14 @@
#define CONFIG_DM644X_GPIO
#define CONFIG_CMD_GPIO
/*=======================*/
/* Recovery handling */
/*=======================*/
#define CONFIG_PREBOOT
#define CONFIG_CMD_RECOVERY
#define CONFIG_NETCONSOLE
#define CONFIG_BOARD_LATE_INIT
/* bdinfo should show the clocks */
#ifdef CONFIG_CMD_BDI

View File

@ -526,6 +526,7 @@ CONFIG_CMD_PCI_ENUM
CONFIG_CMD_PCMCIA
CONFIG_CMD_PORTIO
CONFIG_CMD_READ
CONFIG_CMD_RECOVERY
CONFIG_CMD_REGINFO
CONFIG_CMD_REISER
CONFIG_CMD_SANDBOX