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>
next in thread | raw e-mail | index | archive | help
>- 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; ! } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199703150900.UAA30485>