Serial Console mini HOWTO

Larry McVoy (lm@neteng.engr.sgi.com)
1 May 1996 19:46:10 GMT


I suffered to get this to work, you shouldn't have to. There is a patch below
that you need to apply, I'll ship it to Linus too.

[Wed May 1 00:11:41 PDT 1996 - lm@sgi.com - version 0.9]

This is a mini HOWTO on setting up your system to have a serial "console".

It's mostly aimed at kernel hackers who are used to Silicon Valley calls
the kernel hacker setup: two machines, one without a graphics head that
is used for debugging, and the other a complete machine that is used for
development.

If you are a kernel hack, you'll be disappointed to learn that this HOWTO
does not describe how you could do remote debugging via gdb/ptrace. In
other words, you don't have anything listening on the serial "console"
until a getty starts running.

You'll also be bummed to learn that while you can lose the graphics card
and monitor, most motherboards seem to want a keyboard plugged in to boot.
If anyone has a trick to get rid of this limitation (I'll bet you can
hot wire it somehow), let me know.

Finally, you'll probably need a graphics card and head to set this up
(although it is possible to do it without one if you have a network
connection, or you just know your setup well enough).

Still here? OK, here's the scoop:

Let's call the two machines DEV and DEBUG. DEBUG has no graphics so
that's the one we need a console for.

You need a null modem cable. Connect that from a port in one box to the
other.

Let's assume that DEBUG's port is what prints as

tty00 at 0x03f8 (irq = 4) is a 16550A

at boot time.

My /etc/lilo.conf on DEBUG looks like

prompt
timeout=0
boot = /dev/sda
vga = normal # force sane state
install = /boot/boot.b
message = /boot/message
image = /vmlinuz
root = /dev/sda1
label = cnd
append = "console=0x3f8 ether=0,0,4,eth0 ether=0,0,eth1"

The critical line is the append= line. That says to use the tty at 0x3f8
for the serial console.

At next boot, the first line you should see is:

Serial console on ttyS1

This is all you have to do if all you want is to see the kernel printk
messages. Other things you probably want are /dev/console messages and
a getty on the serial port.

/dev/console messages: I link /dev/ttyS1 to /dev/console and under Red
Hat startup, this link is honored (in other words, they don't stomp on
it as part of the rc scripts. Your mileage may vary).

Login prompt (getty): you need to add one of the following to your
/etc/inittab

# Red Hat style
S0:234:respawn:/sbin/getty ttyS0 DT9600 vt100

# Slackware style
s1:45:respawn:/sbin/agetty 9600 ttyS1

# Rasta style
s9:45:respawn:/usr/games/smoke big_spliff ja rasta

Just kidding on that last one :-)

To allow root logins (you want this) add "console" to the /etc/securetty
file if it isn't there. If you don't do the link (or you are just
paranoid), add ttyS0 as well.

That's it. As the serial HOWTO frequently says, rejoice!

Problems you might have: I have an ASUS motherboard where tty01 would
speak but not listen (typical human behavior, didn't expect it from a
computer). That motherboard has two ports (as do most) and the cable
connections on the motherboard are the same. I just flipped the cables
so that the 9 pin port was COM2 and the 25 pin was COM1 and that worked.
I still have one bad port but I'm not using it so who cares. This was
faster than waiting for the stores to open to buy a new card (and cheaper
too). Try this if things are not working for you.

Handshaking on the modem: I think a full null modem will work. Read the
serial HOWTO for more info. I know that if you do the hack that wires
RTS to CTS, etc., that works because that's what I'm using.

Cool stuff for the future: wouldn't it be neat if we actually made
serial consoles a fully support thing so you could do gdb -r? Yes, it
would and a volunteer needs to step forward :-)

----------------------------------------------------------------------------

Patch for the console= stuff. You will want to apply this by hand, I cut &
pasted it on an xterm and the tabs will be all messed up. It's very simple.

*** 3.91/init/main.c Tue Apr 16 00:27:09 1996
--- linux/init/main.c Tue Apr 30 11:30:10 1996
***************
*** 57,62 ****
--- 57,63 ----
extern long pci_init(long, long);
extern void sysctl_init(void);

+ extern void console_setup(char *str, int *ints);
extern void no_scroll(char *str, int *ints);
extern void swap_setup(char *str, int *ints);
extern void buff_setup(char *str, int *ints);
***************
*** 213,218 ****
--- 221,227 ----
} bootsetups[] = {
{ "reserve=", reserve_setup },
{ "profile=", profile_setup },
+ { "console=", console_setup },
#ifdef CONFIG_BLK_DEV_RAM
{ "ramdisk_start=", ramdisk_start_setup },
{ "load_ramdisk=", load_ramdisk },

*** old/drivers/char/console.c Wed Mar 20 01:39:51 1996
--- linux/drivers/char/console.c Wed May 1 00:43:16 1996
***************
*** 183,188 ****
--- 183,189 ----
static long blank_origin, blank__origin, unblank_origin;


+ #define CONFIG_SERIAL_ECHO
#ifdef CONFIG_SERIAL_ECHO

#include <linux/serial_reg.h>
***************
*** 190,201 ****
extern int serial_echo_init (int base);
extern int serial_echo_print (const char *s);

- /*
- * this defines the address for the port to which printk echoing is done
- * when CONFIG_SERIAL_ECHO is defined
- */
- #define SERIAL_ECHO_PORT 0x3f8 /* COM1 */
-
static int serial_echo_port = 0;

#define serial_echo_outb(v,a) outb((v),(a)+serial_echo_port)
***************
*** 292,302 ****
--- 287,309 ----
comstat = serial_echo_inb(UART_RX); /* COM? RBR */
serial_echo_outb(0x00, UART_IER); /* Disable all interrupts */

+ printk("Serial console on ttyS%d\n", base == 0x2f8 ? 0 : 1);
+
return(0);
}

#endif /* CONFIG_SERIAL_ECHO */

+ void console_setup(char *str, int *ints)
+ {
+ #ifdef CONFIG_SERIAL_ECHO
+ if (ints[0] == 1) {
+ serial_echo_port = ints[1];
+ }
+ #endif
+ }
+
+

int vc_cons_allocated(unsigned int i)
{
***************
*** 2065,2085 ****
set_origin(currcons);
csi_J(currcons, 0);

/* Figure out the size of the screen and screen font so we
can figure out the appropriate screen size should we load
a different font */

- printable = 1;
if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC
|| video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC )
{
default_font_height = video_font_height = ORIG_VIDEO_POINTS;
/* This may be suboptimal but is a safe bet - go with it */
video_scan_lines = video_font_height * video_num_lines;
-
- #ifdef CONFIG_SERIAL_ECHO
- serial_echo_init(SERIAL_ECHO_PORT);
- #endif /* CONFIG_SERIAL_ECHO */

printk("Console: %ld point font, %ld scans\n",
video_font_height, video_scan_lines);
--- 2072,2092 ----
set_origin(currcons);
csi_J(currcons, 0);

+ printable = 1;
+ #ifdef CONFIG_SERIAL_ECHO
+ serial_echo_init(serial_echo_port);
+ #endif /* CONFIG_SERIAL_ECHO */
+
/* Figure out the size of the screen and screen font so we
can figure out the appropriate screen size should we load
a different font */

if ( video_type == VIDEO_TYPE_VGAC || video_type == VIDEO_TYPE_EGAC
|| video_type == VIDEO_TYPE_EGAM || video_type == VIDEO_TYPE_TGAC )
{
default_font_height = video_font_height = ORIG_VIDEO_POINTS;
/* This may be suboptimal but is a safe bet - go with it */
video_scan_lines = video_font_height * video_num_lines;

printk("Console: %ld point font, %ld scans\n",
video_font_height, video_scan_lines);

--
---
Larry McVoy     lm@sgi.com     http://reality.sgi.com/lm     (415) 933-1804
Copyright 1996, all rights reserved.   Microsoft Network is prohibited from
redistributing this work in any form, in whole or in part without license.
License to distribute this work is available to Microsoft at $500.
Transmission without permission constitutes an agreement to these terms.