![]() |
PurposeThe purpose of this page is to help you get access to the RedBoot bootloader. The main reason for accessing the RedBoot bootloader is when you are attempting to Recover From A Bad Flash. About RedBootRedBoot is a bootloader. The bootloader's job is to load things into the computer's memory and start up the OS, in this case Linux or the original NSLU2 firmware (which is Linux based, as well). RedBoot is quite sophisticated, and has a user interface that you can access by telnet or serial. You can use it to load things into memory by TFTP, write to flash, and similar tasks. You should also be cautious when accessing RedBoot, as you can muck up the basic behaviour of the slug if you're not careful. For more information about RedBoot in general, consult Red Hat's website or use Google. How does RedBoot access work on the NSLU2?When the slug starts up, for a few seconds RedBoot will listen for telnet connections on port 9000. RedBoot will insist on being 192.168.0.1 for this window, regardless of what you've set the address of the normal Linux portion of your slug to be. If it doesn't receive a telnet connection during that window, it will attempt to load the Linux kernel into main memory from flash and execute it. Preparation for RedBoot accessBefore attempting to access RedBoot, there are some problem that you may need to sort out first.
Trying To Access RedBootThe main trick with accessing RedBoot is the shortness of the telnet window. Since the telnet port is only alive for 2 seconds, it can be a bit of a challenge to do everything required within that time frame. You must:
We will first describe basic manual methods of accessing RedBoot and then delve into more automated methods. Accessing RedBoot from *nixManual Methods
Accessing RedBoot from WindowsThis worked for me. You can use similar ideas for any other graphical environment.
With newer versions (2007) the LED colour scheme is different. Just power cycle the slug and watch how many pings get lost until the redboot time-window opens after powering up. Use a Ethernet switch if your NIC takes too long to link up with a crossover cable. Comment: Microsoft have seen fit to remove Hyper Terminal from Windows Vista. -- Dave Lane Another option:
A mouseless option:
NOTE: On some systems you should ensure that the "Speed & Duplex" setting of your network card is set to "100 Mbps Full". "Auto" won't work. --cweber An automatic Windows method:As long as the steps have been followed in the “Preparation for RedBoot access” section of this Wiki, and if Windows Script Host is installed on your system (It should be on 2000 and XP systems. If not it can be d/l’ed from the Microsoft website.) the following batch file should boot the slug into RedBoot, if it does not try it again. Sometimes the ping is not caught. Also, the line:
sets the time in milliseconds the script should wait for the before sending the ^C. You may have to change this if the RedBoot is not catching the SendKey. For those who do not know how to create a batch file: Open up Notepad and copy the code below and paste it into the Notepad window you just opened. Save the contents of the Notepad window to a file; it should end in “.txt”. In Windows Explorer, find the file you just saved and rename it “redBootSlug.bat”. You may get a message about changing the extension; if you do, just click yes. With the slug turned off, run the batch file. When the ping timeout notices start, turn on the slug, and with any luck in a few seconds you should be in RedBoot mode. Again, if the slug boots up normally, try the batch file again. To end a script that has not caught the ping message, just close the command window. The batch code follows: echo off
echo Set objShell = WScript.CreateObject("WScript.Shell") > redbootSlug.vbs
echo Set objExecObject = objShell.Exec("cmd /c ping -t -w 1 192.168.0.1") >> redbootSlug.vbs
echo Wscript.Echo "Start slug after first ping timeout..." >> redbootSlug.vbs
echo Do While Not objExecObject.StdOut.AtEndOfStream >> redbootSlug.vbs
echo strText = objExecObject.StdOut.ReadLine() >> redbootSlug.vbs
echo Wscript.Echo strText >> redbootSlug.vbs
echo If Instr(strText, "Reply") > 0 Then >> redbootSlug.vbs
echo Exit Do >> redbootSlug.vbs
echo End If >> redbootSlug.vbs
echo Loop >> redbootSlug.vbs
echo objShell.Run("Telnet 192.168.0.1 9000") >> redbootSlug.vbs
echo Do Until Success = True >> redbootSlug.vbs
echo Success = objShell.AppActivate("Telnet") >> redbootSlug.vbs
echo Loop >> redbootSlug.vbs
echo Wscript.Sleep 500 >> redbootSlug.vbs
echo objShell.SendKeys "^C" >> redbootSlug.vbs
echo Wscript.Echo "Done... You can close this command window." >> redbootSlug.vbs
echo Wscript.Quit >> redbootSlug.vbs
CALL CScript redbootSlug.vbs
del redbootSlug.vbs
This line is not part of the batch code… I hope this helps. --dmbaker Comment: Thanks a lot, this nice script really does the job automatically :)
Just a note for localized non-English WinXP versions:
In the following line
Comment: Users of Windows Vista will need to manually add Telnet support using the "Turn Windows Features on or off" link in Control Panel. -- Dave Lane Alternative automatic Windows Method With PuttyVista CompatibleFor whatever reason the above method did not work for me, so I decided to use Putty since Putty by default send "^C" upon establishing a telnet connection.
The batch code follows: echo off
echo Set objShell = WScript.CreateObject("WScript.Shell") > redbootSlug.vbs
echo Set objExecObject = objShell.Exec("cmd /c ping -t -w 1 192.168.0.1") >> redbootSlug.vbs
echo Wscript.Echo "Start slug after first ping timeout..." >> redbootSlug.vbs
echo Do While Not objExecObject.StdOut.AtEndOfStream >> redbootSlug.vbs
echo strText = objExecObject.StdOut.ReadLine() >> redbootSlug.vbs
echo Wscript.Echo strText >> redbootSlug.vbs
echo If Instr(strText, "Reply") > 0 Then >> redbootSlug.vbs
echo Exit Do >> redbootSlug.vbs
echo End If >> redbootSlug.vbs
echo Loop >> redbootSlug.vbs
echo objShell.Run("putty -load red") >> redbootSlug.vbs
echo Do Until Success = True >> redbootSlug.vbs
echo Success = objShell.AppActivate("putty") >> redbootSlug.vbs
echo Wscript.Sleep 200 >> redbootSlug.vbs
echo Loop >> redbootSlug.vbs
echo objShell.SendKeys "version" >> redbootSlug.vbs
echo objShell.SendKeys "{ENTER}" >> redbootSlug.vbs
echo Wscript.Echo "Done... You can close this command window." >> redbootSlug.vbs
echo Wscript.Quit >> redbootSlug.vbs
CALL CScript redbootSlug.vbs
del redbootSlug.vbs
Accessing RedBoot from FreeBSDA small variation on the OSX instructions worked under FreeBSD: # Ping using a fraction of a second (must be root to do so) # Turn off name lookup on telnet sudo ping -i .3 -o 192.168.0.1 ; telnet -N 192.168.0.1 9000 Automated MethodsNote: Once you succeed in connecting to 192.168.0.1 port 9000 and sending in a control-C to halt the automatic boot process, RedBoot will keep listening on 192.168.0.1:9000 until the next reboot. This means you that if you can automate catching the telnet you'll subsequently be able to telnet in manually. NetcatThis is a fully automated one-liner from the shell. I created it using the manual method and Ethereal, using netcat to mimick the codes (for CTRL-C) being sent. Somehow, root and -vvv seems needed to netcat for this to work (timing issue??). Tested from FC5. I could not further automate input to RedBoot (yet), which would be a very nice feature. This one-liner has been reformatted on to several lines, but should be executed on a single line. As root: echo -e "\0377\0364\0377\0375\0006" >break.bin; sudo /sbin/arping -f 192. 168.0.1; sudo nc -D -vvv 192.168.0.1 9000 <break.bin; telnet 192.168.0.1 9000 -- Leon Woestenberg (likewise @IRC). TCL ScriptThe following TCL script automates the process of telnet-ing in and issuing the control-C (and also dumps the RedBoot version info). Once the script has done the time-sensitive work you can telnet in at your leisure using your favorite telnet client. The script was written on Windows. Tested on Windows, OS X. Should Work: Linux, Unix. Preconditions: You need to run this from a machine can see the slug's 192.168.0.1 address. set done 0
set state START
proc on_nslu_writable { sock } {
global state
fileevent $sock writable ""
if { $state == "START" } {
puts "Connected to NSLU2..."
set state CONN
fileevent $sock readable [ list on_nslu_readable $sock ]
after 1000 [list puts $sock ""]
}
}
proc on_nslu_readable { sock } {
global done state
set data [read $sock]
if { [eof $sock] } { puts "Got EOF - Failed."; exit }
puts $data
if { [string first "enter ^C to abort" $data] > 0 } {
puts -nonewline $sock [format "%c" 3]
} elseif { [string first "RedBoot>" $data] >= 0 } {
if { $state == "SENTVER" } {
set done 1
puts ""
puts -nonewline " Success - You should now be able"
puts " to telnet to 192.168.0.1:9000"
} else {
puts $sock "version"
set state SENTVER
}
}
}
proc try_nslu { } {
global state
if { $state == "START" } {
set sock [socket -async "192.168.0.1" 9000]
fileevent $sock writable [ list on_nslu_writable $sock ]
fconfigure $sock -blocking false -buffering none
after 500 try_nslu
}
}
try_nslu
vwait done
Example Usage:
Connected to NSLU2... == Executing boot script in 1.800 seconds - enter ^C to abort ^C RedBoot> RedBoot(tm) bootstrap and debug environment [ROMRAM] Red Hat certified release, version 1.92 - built 15:16:07, Feb 3 2004 Platform: IXDP425 Development Platform (XScale) Copyright (C) 2000, 2001, 2002, Red Hat, Inc. RAM: 0x00000000-0x02000000, 0x000723a0-0x01ff3000 available FLASH: 0x50000000 - 0x50800000, 64 blocks of 0x00020000 bytes each. RedBoot> Success - You should now be able to telnet to 192.168.0.1:9000 -- Adrian Shotton Perl ScriptHere is a Perl script to automate the entire process.
#!/usr/bin/perl -w
# telnet_redboot.pl - ./upslug --reset;arping -f 192.168.0.1;telnet 192.168.0.1 9000
use Net::Telnet ();
my $host = '192.168.0.1';
system("/usr/local/bin/upslug -r");
printf("NSLU2 reset\n");
system("/sbin/arping -f $host");
printf("NSLU2 arping response\n");
my $t = new Net::Telnet (Port => 9000, Timeout => 30);
if(!defined($t)){
print "new Net::Telnet failed\n";
exit(1);
} # if
my $ok;
$ok = $t->errmode("return");
$ok = $t->open($host);
if(!defined($ok)){
print "open('$host') failed\n";
$t->close();
exit(1);
} # if
# == Executing boot script in 1.930 seconds - enter ^C to abort
my $line;
while($line = $t->getline()){
$line =~ s/[\r\n]//;
print "-> $line\n";
if($line =~ m/enter \^C to abort/){
$t->put(chr(3)); # send ^C
print "<- \^C\n";
$t->close();
sleep(1);
system("telnet $host 9000");
exit(0);
} # if
} # while
$t->close();
C program using Berkeley SocketsThe following C program will attempt a connection 10 times/second. After it successed it will send the control-C character, wait for a response, and then drop you into a telnet session. It's trivial to modify this program to run an arbitrary program with stdin/stdout connected to the slug instead of your terminal. The telnet session has the tilde '~' character as the escape code. That can be very useful if the connection isn't dropped after a reset! As always you can subsequently reconnect with telnet until the next reboot. Tested on Debian linux (2006-02-12). Preconditions: You need to run this from a machine can see the slug's 192.168.0.1 address. #include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netdb.h>
#define SLUG_IP "192.168.0.1"
#define SLUG_PORT "9000"
#define TELNET "/usr/bin/telnet"
char * const telnet_args[] = { "telnet", "-e", "~", SLUG_IP, SLUG_PORT, NULL };
int main()
{
struct sockaddr_in sin;
fd_set rfds, wfds;
struct timeval timeout;
int n;
char buffer[1024];
time_t stoptime = time(NULL);
char outbound[] = { 0x03, 0x00 };
char *out = outbound;
int s = socket(PF_INET, SOCK_STREAM, 0);
// set up socket address for port 9000 at 192.168.0.1
struct hostent *h = gethostbyname(SLUG_IP);
sin.sin_family = h->h_addrtype;
sin.sin_port = htons(atoi(SLUG_PORT));
memcpy(&sin.sin_addr, h->h_addr_list[0], h->h_length);
// attempt to connect to remote system.
while (connect(s, (struct sockaddr *) &sin, sizeof sin) == -1) {
switch (errno) {
case ECONNREFUSED:
case ENETUNREACH:
case EHOSTUNREACH:
timeout.tv_sec = 0;
timeout.tv_usec = 100000; // every 100 ms
select(1, NULL, NULL, NULL, &timeout);
continue;
default:
fprintf(stderr, "connect error: %s (%s)\n",
strerror(errno), h->h_name);
return errno;
}
}
FD_ZERO(&rfds);
FD_ZERO(&wfds);
stoptime = time(NULL) + 15;
while (difftime(stoptime, time(NULL)) > 0) {
FD_SET(s, &rfds);
FD_SET(s, &wfds);
timeout.tv_sec = 0;
timeout.tv_usec = 10000; // every 10 ms
n = select(s+1, &rfds, &wfds, NULL, &timeout);
if (n == -1) {
fprintf(stderr, "select error: %s\n", strerror(errno));
return errno;
}
if (n == 0) { continue; }
if (*out != 0 && FD_ISSET(s, &wfds)) { write(s, out++, 1); }
if (FD_ISSET(s, &rfds)) {
n = read(s, buffer, sizeof buffer);
write(1, buffer, n);
close(s);
execv(TELNET, telnet_args);
fprintf(stderr, "exec (%s): %s\n", TELNET, strerror(errno));
exit(0); // just in case
}
}
fprintf(stderr, "could not capture telnet port");
close(s);
return 0;
}
-- Bear Example using Red Hat LinuxYou have to do the Ctrl+C really really quick. [root@dual root]# arping -f 192.168.0.1;telnet 192.168.0.1 9000
ARPING 192.168.0.1 from 192.168.1.253 eth0
Unicast reply from 192.168.0.1 [00:0F:66:7B:FE:96] 9.641ms
Sent 7 probes (7 broadcast(s))
Received 1 response(s)
Trying 192.168.0.1...
Connected to 192.168.0.1 (192.168.0.1).
Escape character is '^]'.
== Executing boot script in 1.820 seconds - enter ^C to abort
^C
RedBoot>
The animated version. Sources: [http://groups.yahoo.com/group/nslu2-linux/message/1096][http://groups.yahoo.com/group/nslu2-linux/message/1106] Example using UbuntuI open a terminal and use the following command to get a root prompt: sudo su I then use the following command to be able to access the NSLU2. My network is otherwise the typical 192.168.1.x: route add 192.168.0.1 eth0 My WRT54G router subnet is 255.255.255.0, and my NSLU2 is connected through a network switch, but this worked fine anyway.
This is so I have all the time in the world to hit Ctrl-C when arping gets a reply. Now I use the following command to wait for telnet contact: arping -f 192.168.0.1; telnet 192.168.0.1 9000 The terminal now shows the following and waits for the NSLU2 to respond, which of course it won't do until I power it on: ARPING 192.168.0.1 from 192.168.1.102 eth0
Then I watch the terminal for a reply, such as the following: Unicast reply from 192.168.0.1 [00:18:39:31:64:A4] 6.125ms Sent 103 probes (103 broadcast(s)) Received 1 response(s) Trying 192.168.0.1... Connected to 192.168.0.1. Escape character is '^]'. == Executing boot script in 1.910 seconds - enter ^C to abort Finally, I immediately hit Ctrl-C and receive the RedBoot prompt in the terminal as shown below: ^C
RedBoot>
view ·
edit ·
print ·
history ·
Last edited by fcarolo.
Based on work by Jim Gasbarro, fcarolo, lithiumc, Dave Lane, pedxing, mwester, loan rate, mortgage refinance, marceln, jimbaker, Al, YvonneM, Mannkind, DonV, Anguel Stankov, heinz, dmbaker, dean, CatMarieS, Reedy Boy, Rob Lockhart, Jerome Paschoud, ckl, Leon 'likewise' Woestenberg, Pascal Charest, JH, cStyle, Phil S-J, Bear, dharple, frankvh, dougbo, thx1011, cweber, Adrian Shotton, mschnell, jerobins, yvasilev, tman, EddyP, crh, barrym, willpost, repvik, Dave Redfern, saylerthewalrusorg, tjyang, kamcgough, jsilence, pbnexuscouk, sfo, ka6sox, CodeWhacker, and rwhitby. Originally by rwhitby. Page last modified on October 01, 2007, at 09:21 PM
|