Add support for console over UDP (compatible to Ingo Molnar's

netconsole patch under Linux)
This commit is contained in:
wdenk 2004-08-02 21:11:11 +00:00
parent 9aea95307f
commit 68ceb29e71
9 changed files with 308 additions and 2 deletions

View File

@ -2,6 +2,9 @@
Changes since U-Boot 1.1.1:
======================================================================
* Add support for console over UDP (compatible to Ingo Molnar's
netconsole patch under Linux)
* Patch by Jon Loeliger, 16 Jul 2004:
- support larger DDR memories up to 2G on the PC8540/8560ADS and
STXGP3 boards

View File

@ -201,6 +201,9 @@ int devices_init (void)
#ifdef CONFIG_USB_TTY
drv_usbtty_init ();
#endif
#ifdef CONFIG_NETCONSOLE
drv_nc_init ();
#endif
return (0);
}

68
doc/README.NetConsole Normal file
View File

@ -0,0 +1,68 @@
In U-Boot, we implemented the networked console via the standard
"devices" mechanism, which means that you can switch between the
serial and network input/output devices by adjusting the 'stdin' and
'stdout' environment variables. To switch to the networked console,
set either of these variables to "nc". Input and output can be
switched independently.
On the host side, please use this script to access the console:
+++++++++++++++++++++++++++++++++++++++++++
#! /bin/bash
TARGET_IP=$1
stty -icanon -echo intr ^T
nc -u -l -p 6666 < /dev/null &
nc -u ${TARGET_IP} 6666
stty icanon echo intr ^C
+++++++++++++++++++++++++++++++++++++++++++
For Linux, the network-based console needs special configuration.
Minimally, the host IP address needs to be specified. This can be
done either via the kernel command line, or by passing parameters
while loading the netconsole.o module (when used in a loadable module
configuration). Please refer to Documentation/networking/logging.txt
file for the original Ingo Molnar's documentation on how to pass
parameters to the loadable module.
The format of the kernel command line parameter (for the static
configuration) is as follows:
netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
where
src-port source for UDP packets
(defaults to 6665)
src-ip source IP to use
(defaults to the interface's address)
dev network interface
(defaults to eth0)
tgt-port port for logging agent
(defaults to 6666)
tgt-ip IP address for logging agent
(this is the required parameter)
tgt-macaddr ethernet MAC address for logging agent
(defaults to broadcast)
Examples:
netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc
or
netconsole=@/,@192.168.3.1/
Please note that for the Linux networked console to work, the
ethernet interface has to be up by the time the netconsole driver is
initialized. This means that in case of static kernel configuration,
the respective Ethernet interface has to be brought up using the "IP
Autoconfiguration" kernel feature, which is usually done by defaults
in the ELDK-NFS-based environment.
To browse the Linux network console output, use the 'netcat' tool invoked
as follows:
nc -u -l -p 6666

View File

@ -32,7 +32,7 @@ OBJS = 3c589.o 5701rls.o ali512x.o \
cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
e1000.o eepro100.o \
i8042.o i82365.o inca-ip_sw.o keyboard.o \
lan91c96.o natsemi.o netarm_eth.o \
lan91c96.o natsemi.o netarm_eth.o netconsole.o \
ns16550.o ns8382x.o ns87308.o omap1510_i2c.o \
pci.o pci_auto.o pci_indirect.o \
pcnet.o plb2800_eth.o \

204
drivers/netconsole.c Normal file
View File

@ -0,0 +1,204 @@
/*
* (C) Copyright 2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* 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., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#ifdef CONFIG_NETCONSOLE
#include <command.h>
#include <devices.h>
#include <net.h>
#ifndef CONFIG_NET_MULTI
#error define CONFIG_NET_MULTI to use netconsole
#endif
static uchar nc_buf = 0; /* input buffer */
static int input_recursion = 0;
static int output_recursion = 0;
static int net_timeout;
static void nc_wait_arp_handler (uchar * pkt, unsigned dest, unsigned src,
unsigned len)
{
NetState = NETLOOP_SUCCESS; /* got arp reply - quit net loop */
}
static void nc_handler (uchar * pkt, unsigned dest, unsigned src,
unsigned len)
{
if (nc_buf)
NetState = NETLOOP_SUCCESS; /* got input - quit net loop */
}
static void nc_timeout (void)
{
NetState = NETLOOP_SUCCESS;
}
void NcStart (void)
{
if (memcmp (NetServerEther, NetEtherNullAddr, 6)) {
/* going to check for input packet */
NetSetHandler (nc_handler);
NetSetTimeout (net_timeout, nc_timeout);
} else {
/* send arp request */
NetSetHandler (nc_wait_arp_handler);
NetSendUDPPacket (NetServerEther, NetServerIP, 6665, 6666, 0);
}
}
int nc_input_packet (uchar * pkt, unsigned dest, unsigned src, unsigned len)
{
if (dest != 6666 || !len)
return 0; /* not for us */
nc_buf = *pkt;
return 1;
}
static void nc_send_packet (const char *buf, int len)
{
DECLARE_GLOBAL_DATA_PTR;
struct eth_device *eth;
int inited = 0;
uchar *pkt;
if (!memcmp (NetServerEther, NetEtherNullAddr, 6))
return;
if ((eth = eth_get_dev ()) == NULL) {
return;
}
if (eth->state != ETH_STATE_ACTIVE) {
if (eth_init (gd->bd) < 0)
return;
inited = 1;
}
pkt = (uchar *) NetTxPacket + NetEthHdrSize () + IP_HDR_SIZE;
memcpy (pkt, buf, len);
NetSendUDPPacket (NetServerEther, NetServerIP, 6666, 6665, len);
if (inited)
eth_halt ();
}
int nc_start (void)
{
if (memcmp (NetServerEther, NetEtherNullAddr, 6))
return 0;
return NetLoop (NETCONS); /* wait for arp reply */
}
void nc_putc (char c)
{
if (output_recursion)
return;
output_recursion = 1;
nc_send_packet (&c, 1);
output_recursion = 0;
}
void nc_puts (const char *s)
{
if (output_recursion)
return;
output_recursion = 1;
int len = strlen (s);
if (len > 512)
len = 512;
nc_send_packet (s, len);
output_recursion = 0;
}
int nc_getc (void)
{
input_recursion = 1;
net_timeout = 0; /* no timeout */
while (!nc_buf)
NetLoop (NETCONS);
input_recursion = 0;
uchar tmp = nc_buf;
nc_buf = 0;
return tmp;
}
int nc_tstc (void)
{
struct eth_device *eth;
if (input_recursion)
return 0;
if (nc_buf)
return 1;
eth = eth_get_dev ();
if (eth && eth->state == ETH_STATE_ACTIVE)
return 0; /* inside net loop */
input_recursion = 1;
net_timeout = 1;
NetLoop (NETCONS); /* kind of poll */
input_recursion = 0;
return nc_buf != 0;
}
int drv_nc_init (void)
{
device_t dev;
int rc;
memset (&dev, 0, sizeof (dev));
strcpy (dev.name, "nc");
dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
dev.start = nc_start;
dev.putc = nc_putc;
dev.puts = nc_puts;
dev.getc = nc_getc;
dev.tstc = nc_tstc;
rc = device_register (&dev);
return (rc == 0) ? 1 : rc;
}
#endif /* CONFIG_NETCONSOLE */

View File

@ -97,6 +97,8 @@
CFG_CMD_IDE | \
CFG_CMD_DATE )
#define CONFIG_NETCONSOLE
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>

View File

@ -108,5 +108,8 @@ int drv_keyboard_init (void);
#ifdef CONFIG_USB_TTY
int drv_usbtty_init (void);
#endif
#ifdef CONFIG_NETCONSOLE
int drv_nc_init (void);
#endif
#endif /* _DEVICES_H_ */

View File

@ -314,6 +314,7 @@ extern volatile uchar * NetRxPkt; /* Current receive packet */
extern int NetRxPktLen; /* Current rx packet length */
extern unsigned NetIPID; /* IP ID (counting) */
extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */
extern uchar NetEtherNullAddr[6];
#define VLAN_NONE 4095 /* untagged */
#define VLAN_IDMASK 0x0fff /* mask of valid vlan id */
@ -334,7 +335,7 @@ extern int NetState; /* Network loop state */
extern int NetRestartWrap; /* Tried all network devices */
#endif
typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP } proto_t;
typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS, NFS, CDP, NETCONS } proto_t;
/* from net/net.c */
extern char BootFile[128]; /* Boot File name */

View File

@ -148,6 +148,11 @@ static void PingStart(void);
static void CDPStart(void);
#endif
#ifdef CONFIG_NETCONSOLE
void NcStart(void);
int nc_input_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len);
#endif
volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */
@ -308,6 +313,7 @@ restart:
#if (CONFIG_COMMANDS & CFG_CMD_PING)
case PING:
#endif
case NETCONS:
case TFTP:
NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
NetOurGatewayIP = getenv_IPaddr ("gatewayip");
@ -319,6 +325,7 @@ restart:
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
case NETCONS:
case TFTP:
NetServerIP = getenv_IPaddr ("serverip");
break;
@ -403,6 +410,11 @@ restart:
case CDP:
CDPStart();
break;
#endif
#ifdef CONFIG_NETCONSOLE
case NETCONS:
NcStart();
break;
#endif
default:
break;
@ -1259,6 +1271,9 @@ NetReceive(volatile uchar * inpkt, int len)
/* save address for later use */
memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6);
#ifdef CONFIG_NETCONSOLE
(*packetHandler)(0,0,0,0);
#endif
/* modify header, and transmit it */
memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6);
(void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize);
@ -1377,6 +1392,12 @@ NetReceive(volatile uchar * inpkt, int len)
return;
}
#ifdef CONFIG_NETCONSOLE
nc_input_packet((uchar *)ip +IP_HDR_SIZE,
ntohs(ip->udp_dst),
ntohs(ip->udp_src),
ntohs(ip->udp_len) - 8);
#endif
/*
* IP header OK. Pass the packet to the current handler.
*/
@ -1406,6 +1427,7 @@ static int net_check_prereq (proto_t protocol)
#if (CONFIG_COMMANDS & CFG_CMD_NFS)
case NFS:
#endif
case NETCONS:
case TFTP:
if (NetServerIP == 0) {
puts ("*** ERROR: `serverip' not set\n");