Date: Sat, 15 Mar 1997 20:00:55 +1100 From: Bruce Evans <bde@zeta.org.au> To: bakul@torrentnet.com, hackers@FreeBSD.org Subject: Re: kernel remote debugging using gdb Message-ID: <199703150900.UAA30485@godzilla.zeta.org.au>
index | next in thread | raw e-mail
>- recompiled the boot program to always use COM1 as console and
> installed it on the primary disk on the test machine (called TEST).
>
>- used the following options in the TEST config file:
> options COMCONSOLE
> options DDB
> options BREAK_TO_DEBUGGER
You probably don't want COMCONSOLE. It forces a serial console. This
is inflexible, and serial consoles don't work right in conjunction with
remote gdb.
>- started kermit on DEVEL and connected to TEST @ 9600 baud
9600 baud is very slow. Paul Traina likes to use 115200. This is sometimes
affected by initialization bugs (all instances of 9600 need to be changed
to 115200 to get consistent initialization), and the throughput is still
limited to one packet per clock tick on FreeBSD hosts running sio since
the protocol is non-streaming and sio input is delivered to applications
only every clock tick.
>There are two problems:
>
>- Sendind a break in multiuser mode (before or after attaching gdb)
> does not seem to drop the kernel in the debugger. This seems to
> work occasionally but I haven't as yet figured out under what
> conditions.
I don't use breaks, but I saw cases where ordinary breakpoints didn't
work (and screwed up everything) because of transmission errors.
>- In single user mode when gdb is attached, you can not type anything
> on the console nor can you see any printf() output[1].
gdb and serial consoles don't mix well. At best you can multiplex them
manually.
>[1] Note that passing console device IO `through gdb' would be
> extremely useful as it will feel as if gdb is built in. Not
> sure if this works at all for the standard gdb remote protocol.
> At any rate adding it would not be hard.
The driver's support for multiple serial consoles could be improved,
but it would still be useful to multiplex through one console, since
having multiple physical connections may be inconvenient.
Bruce
I now configure serial consoles using device flags. Bit 0x20 does
the same thing as the current COMCONSOLE except it can be configured
at boot time. Bit 0x40 reserves the console for specialized low level
use (e.g., for gdb, which currently just grabs port 0 without checking
it it is available). Bit 0x10 must now be set to use a port for a
(high level) console. Setting it for sio0 gives the current default.
Setting it for other sio ports makes the first enabled one the serial
console. This will be standard if someone reviews it.
diff -c2 sio.c~ sio.c
*** sio.c~ Fri Jan 17 13:05:08 1997
--- sio.c Fri Jan 17 19:56:35 1997
***************
*** 116,119 ****
--- 116,122 ----
#endif /* COM_MULTIPORT */
+ #define COM_CONSOLE(dev) ((dev)->id_flags & 0x10)
+ #define COM_FORCECONSOLE(dev) ((dev)->id_flags & 0x20)
+ #define COM_LLCONSOLE(dev) ((dev)->id_flags & 0x40)
#define COM_LOSESOUTINTS(dev) ((dev)->id_flags & 0x08)
#define COM_NOFIFO(dev) ((dev)->id_flags & 0x02)
***************
*** 341,346 ****
static int comconsole = -1;
! static speed_t comdefaultrate = CONSPEED;
static u_int com_events; /* input chars + weighted output completions */
static int sio_timeout;
static int sio_timeouts_until_log;
--- 344,350 ----
static int comconsole = -1;
! static volatile speed_t comdefaultrate = CONSPEED;
static u_int com_events; /* input chars + weighted output completions */
+ static Port_t siocniobase;
static int sio_timeout;
static int sio_timeouts_until_log;
***************
*** 531,534 ****
--- 536,544 ----
}
+ if (COM_LLCONSOLE(dev)) {
+ printf("sio%d: reserved for low-level i/o\n", dev->id_unit);
+ return (0);
+ }
+
/*
* If the device is on a multiport card and has an AST/4
***************
*** 582,590 ****
* We don't want to to wait long enough to drain at 2 bps.
*/
! outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
! outb(iobase + com_dlbl, COMBRD(9600) & 0xff);
! outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8);
! outb(iobase + com_cfcr, CFCR_8BITS);
! DELAY((16 + 1) * 1000000 / (9600 / 10));
/*
--- 592,604 ----
* We don't want to to wait long enough to drain at 2 bps.
*/
! if (iobase == siocniobase)
! DELAY((16 + 1) * 1000000 / (comdefaultrate / 10));
! else {
! outb(iobase + com_cfcr, CFCR_DLAB | CFCR_8BITS);
! outb(iobase + com_dlbl, COMBRD(9600) & 0xff);
! outb(iobase + com_dlbh, (u_int) COMBRD(9600) >> 8);
! outb(iobase + com_cfcr, CFCR_8BITS);
! DELAY((16 + 1) * 1000000 / (9600 / 10));
! }
/*
***************
*** 2399,2404 ****
};
- static Port_t siocniobase;
-
static void siocnclose __P((struct siocnstate *sp));
static void siocnopen __P((struct siocnstate *sp));
--- 2447,2450 ----
***************
*** 2545,2563 ****
struct consdev *cp;
{
! int unit;
!
! /* XXX: ick */
! unit = DEV_TO_UNIT(CONUNIT);
! siocniobase = CONADDR;
!
! /* make sure hardware exists? XXX */
!
! /* initialize required fields */
! cp->cn_dev = makedev(CDEV_MAJOR, unit);
! #ifdef COMCONSOLE
! cp->cn_pri = CN_REMOTE; /* Force a serial port console */
! #else
! cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL;
! #endif
}
--- 2591,2628 ----
struct consdev *cp;
{
! struct isa_device *dvp;
! int s;
! struct siocnstate sp;
!
! /*
! * Find our first enabled console, if any. If it is a high-level
! * console device, then initialize it and return successfully.
! * If it is a low-level console device, then initialize it and
! * return unsuccessfully. It must be initialized in both cases
! * for early use by console drivers and debuggers. Initializing
! * the hardware is not necessary in all cases, since the i/o
! * routines initialize it on the fly, but it is necessary if
! * input might arrive while the hardware is switched back to an
! * uninitialized state. We can't handle multiple console devices
! * yet because our low-level routines don't take a device arg.
! * We trust the user to set the console flags properly so that we
! * don't need to probe.
! */
! cp->cn_pri = CN_DEAD;
! for (dvp = isa_devtab_tty; dvp->id_driver != NULL; dvp++)
! if (dvp->id_driver == &siodriver && dvp->id_enabled
! && COM_CONSOLE(dvp)) {
! siocniobase = dvp->id_iobase;
! s = spltty();
! siocnopen(&sp);
! splx(s);
! if (!COM_LLCONSOLE(dvp)) {
! cp->cn_dev = makedev(CDEV_MAJOR, dvp->id_unit);
! cp->cn_pri = COM_FORCECONSOLE(dvp)
! || boothowto & RB_SERIAL
! ? CN_REMOTE : CN_NORMAL;
! }
! break;
! }
}
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703150900.UAA30485>
