这个结构体的定义位于include/linux/serial_core.h,它定义了UART要实现的操作:/** This structure describes all the operations that can be* done on the physical hardware.*/struct uart_ops {unsignedint(*tx_empty)(struct uart_port *);void(*set_mctrl)(struct uart_port *, unsignedint mctrl);unsignedint(*get_mctrl)(struct uart_port *);void(*stop_tx)(struct uart_port *);void(*start_tx)(struct uart_port *);void(*send_xchar)(struct uart_port *, char ch);void(*stop_rx)(struct uart_port *);void(*enable_ms)(struct uart_port *);void(*break_ctl)(struct uart_port *, int ctl);int(*startup)(struct uart_port *);void(*shutdown)(struct uart_port *);void(*set_termios)(struct uart_port *, struct ktermios *new,struct ktermios *old);void(*pm)(struct uart_port *, unsignedint state,unsignedint oldstate);int(*set_wake)(struct uart_port *, unsignedint state);/** Return a string describing the type of the port*/constchar *(*type)(struct uart_port *);/** Release IO and memory resources used by the port.* This includes iounmap if necessary.*/void(*release_port)(struct uart_port *);/** Request IO and memory resources used by the port.* This includes iomapping the port if necessary.*/int(*request_port)(struct uart_port *);void(*config_port)(struct uart_port *, int);int(*verify_port)(struct uart_port *, struct serial_struct *);int(*ioctl)(struct uart_port *, unsignedint, unsignedlong);};
这个结构体的定义位于include/linux/serial_core.h,从它的位置可以看出,这是一个与具体硬件无关的结构体,它提供了对UART的描述信息,对于某个具体的UART,可能只使用其中的某些字段。struct uart_port {spinlock_tlock;/* port lock */unsignedintiobase;/* in/out[bwl] */unsignedchar __iomem*membase;/* read/write[bwl] */unsignedintirq;/* irq number */unsignedintuartclk;/* base uart clock */unsignedintfifosize;/* tx fifo size */unsignedcharx_char;/* xon/xoff char */unsignedcharregshift;/* reg offset shift */unsignedchariotype;/* io access style */unsignedcharunused1;unsignedintread_status_mask;/* driver specific */unsignedintignore_status_mask;/* driver specific */struct uart_info*info;/* pointer to parent info */struct uart_icounticount;/* statistics */struct console*cons;/* struct console, if any */upf_tflags;unsignedintmctrl;/* current modem ctrl settings */unsignedinttimeout;/* character-based timeout */unsignedinttype;/* port type */conststruct uart_ops*ops;unsignedintcustom_divisor;unsignedintline;/* port index */unsignedlongmapbase;/* for ioremap */struct device*dev;/* parent device */unsignedcharhub6;/* this should be in the 8250 driver */unsignedcharunused[3];void*private_data;/* generic platform data pointer */};在内核中,没有为uart_port定义独立的变量,它将从属于某个具体的serial_port,对于bf561,它将从属于bfin_serial_port这一结构体。实际上内核只使用了以下几个成员:luartclk:这个值将设置为BF561的系统时钟频率,在我的系统中,它将为99M。lops:定义对UART的操作函数,指向bfin_serial_pops这一变量。lline:串口序号,只有一个串口,恒为0。liotype:取UPIO_MEM,即直接寄存器访问方式。lmembase:指向UART_THR(0xFFC0 0400),即UART的发送寄存器。lmapbase:与membase相同。lirq:内核中中断描述数组(irq_desc)的序号,指UART接收中断(IRQ_UART_RX)。lflags:配置为UPF_BOOT_AUTOCONF。
这个结构体的定义在include/linux/console.h中,它定义了一个console驱动需要提供的信息及其必须实现的一些操作:/** The interface for a console, or any other device that wants to capture* console messages (printer driver?)** If a console driver is marked CON_BOOT then it will be auto-unregistered* when the first real console is registered.This is for early-printk drivers.*/struct console {charname[16];void(*write)(struct console *, constchar *, unsigned);int(*read)(struct console *, char *, unsigned);struct tty_driver *(*device)(struct console *, int *);void(*unblank)(void);int(*setup)(struct console *, char *);shortflags;shortindex;intcflag;void*data;structconsole *next;};在内核中,对此结构体初始化为:staticstruct console bfin_serial_console = {.name= BFIN_SERIAL_NAME,// 即”ttyBF”.write= bfin_serial_console_write,.device= uart_console_device,.setup= bfin_serial_console_setup,.flags= CON_PRINTBUFFER,.index= -1,.data= &bfin_serial_reg,};而console中的cflag则保存了串口配置,如CREAD | HUPCL | CLOCAL | B57600 | CS8,使用它即可知道当前的串口配置。flags的值在初始化完成后则变成了CON_PRINTBUFFER | CON_ENABLED | CON_CONSDEV。index的值在初始化完成后变成0,因为只使用serial console。这里值得注意的是setup回调函数,当console初始化时,它需要初始化与此console相关的硬件,此时它将调用setup这一回调函数来完成此工作。