Serial Driver and Console

From LinuxMIPS
Revision as of 09:32, 9 November 2004 by ThomasPetazzoni (Talk | contribs)

Jump to: navigation, search

While early printk is rather useful, you still need to get the real serial driver working.

Assuming you have a standard serial port, there are two ways to add serial support: static defines and run-time setup.

With static defines, you modify the 'include/asm-mips/serial.h' file. Looking through the code, it is not difficult to figure out how to add support for your board's serial port(s).

As more boards are supported by Linux/MIPS, the 'serial.h' file gets crowded. One potential solution is to do run-time serial setup. Sometimes run-time serial setup is necessary if any of the parameters can only be detected at the run-time where settings are read from a non-volatile memory device or an option is passed on the kernel command line.

There are two elements to consider for doing run-time serial setup:

  • Reserve the 'rs_table[]' size, see the 'drivers/char/serial.c' file. Unfortunately there is not a clean way to accomplish this yet. A temporary workaround is to define CONFIG_SERIAL_MANY_PORTS in 'arch/mips/' for your board. This configuration reserves up to 64 serial port entries for your board!
  • Call the 'early_serial_setup()' routine in your board setup routine. Here is a piece of sample run-time initialization code.

Serial parameters

Most of the parameter settings are rather obvious. Here is a list of some less obvious ones:

Only used for run-time serial configuration. It is the index into the 'rs_table[] array'.
io_type determines how your serial registers are accessed. Two common types are SERIAL_IO_PORT and SERIAL_IO_MEM. A SERIAL_IO_PORT type driver uses the inb/outb macros to access registers whose base address is at port. In other words, if you specify SERIAL_IO_PORT as the io_type, you should also specify the port parameter.

For SERIAL_IO_MEM, the driver uses readb/writeb macros to access regsiters whose address is at iomem_base plus a shifted offset. The number of digits shifted is specified by iomem_reg_shift. For example, all the serial registers are placed at 4-byte boundary, then you have an iomem_reg_shift of 2.

Generally SERIAL_IO_PORT is for serial ports on an ISA bus and SERIAL_IO_MEM is for memory-mapped serial ports. There are also SERIAL_IO_HUB6 and SERIAL_IO_GSC. The HUB6 was a multi-port serial card produced by Bell Technologies. The GSC is a special bus found on PA-RISC systems. These options will not be used on any MIPS boards.

Non-standard serial ports

If you have a non-standard serial port, you will have to write your own serial driver.

Some people derive their code from the standard serial driver. Unfortunately this is a very daunting task. The 'drivers/char/serial.c' file has over 6000 lines of code!

The generic serial way

Fortunately, there is an alternative [THANKS: Fillod Stephane]. There is a generic serial driver, 'drivers/char/generic_serial.c'. This file provides a set of serial routines that are hardware independent. Then your task is to provide only the routines that are hardware dependent such as the interrupt handler routine and low-level I/O functions. There are plenty of examples. Just look inside the 'drivers/char/Makefile' and look for drivers that link with 'generic_serial.o' file.

[HELP: Would appreciate if you can share your experience of writing proprietary serial driver code or using the 'generic_serial.c' file.]

The drivers/serial way

There is an other, even simpler alternative to the generic serial way described above. It consists in using the drivers/serial/serial_core.c infrastructure, which allows to write a very simple serial driver.

Next page: KGDB