您的位置:首页 > 运维架构 > Linux

linux tty core 源码分析(1)

2014-07-12 18:03 405 查看
转载:http://blog.csdn.net/sirzjp/article/details/6129001

本文以linux 2.6.27内核为基础,阅读tty core 源码并作注解,自己接触时间不长,希望与爱好者共同分享,错误之处还望指正。

linux tty core 是建立在字符设备驱动的基础之上,并为tty类型设备(串口、控制台、虚拟终端)提供一个公用的平台。所以任何一个tty设备驱动的注册都是作为一个字符设备驱动而操作的。下面我们看看代码中是如何处理的:

/* 3/2004 jmc: why do these devices exist? */

//tty核心默认在内核中实现的字符型tty设备驱动

static struct cdev tty_cdev, console_cdev;

#ifdef CONFIG_UNIX98_PTYS

static struct cdev ptmx_cdev;

#endif

#ifdef CONFIG_VT

static struct cdev vc0_cdev;

#endif

/*

* Ok, now we can initialize the rest of the tty devices and can count

* on memory allocations, interrupts etc..

*/

static int __init tty_init(void)

{

//在字符设备模型中加入注册tty_cdev驱动并加入/dev/tty这样的设备

cdev_init(&tty_cdev, &tty_fops);

if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||

register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)

panic("Couldn't register /dev/tty driver/n");

device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,

"tty");

//在字符设备模型中加入注册console_cdev驱动并加入/dev/console这样的设备

cdev_init(&console_cdev, &console_fops);

if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||

register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)

panic("Couldn't register /dev/console driver/n");

device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,

"console");

//在字符设备模型中加入注册ptmx_cdev驱动并加入/dev/ptmx这样的设备

#ifdef CONFIG_UNIX98_PTYS

cdev_init(&ptmx_cdev, &ptmx_fops);

if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||

register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)

panic("Couldn't register /dev/ptmx driver/n");

device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");

#endif

//在字符设备模型中加入注册vc0_cdev驱动并加入/dev/tty0这样的设备

#ifdef CONFIG_VT

cdev_init(&vc0_cdev, &console_fops);

if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||

register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)

panic("Couldn't register /dev/tty0 driver/n");

device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");

vty_init(); //这里暂时不做解释

#endif

return 0;

}

//上面是本身加入的,也就是我们系统一般都有的设备,而且这几种设备都是指向其他的设备,在tty_open中我们将看到以后都会指向其

//他具体的设备。对这几种设备大多数人都存在一定的混淆,这里我就自己的理解解释下:

// /dev/console (5,1) 表示系统的控制台

// /dev/tty (5,0) 表示进程的控制终端

// /dev/tty0 (4,0) 表示当前使用的虚拟终端

// 这样的解释也不是很清楚,这得从历史说起,以前计算机还是比较昂贵的时候,一台电脑上一般接有很多键盘与显示器的组合设备用以

//操作计算机这样的组合设备就是所谓的终端,而还存在一种直接和电脑连接键盘和显示器这就是控制台。而现在的应用环境发生了变化,

//一般把能直接显示系统信息的终端称呼为系统控制台,而其他设备则称呼虚拟终端。也就是当前虚拟终端作控制台。

static const struct file_operations tty_fops = {

.llseek = no_llseek,

.read = tty_read,

.write = tty_write,

.poll = tty_poll,

.unlocked_ioctl = tty_ioctl,

.compat_ioctl = tty_compat_ioctl,

.open = tty_open,

.release = tty_release,

.fasync = tty_fasync,

};

#ifdef CONFIG_UNIX98_PTYS

static const struct file_operations ptmx_fops = {

.llseek = no_llseek,

.read = tty_read,

.write = tty_write,

.poll = tty_poll,

.unlocked_ioctl = tty_ioctl,

.compat_ioctl = tty_compat_ioctl,

.open = ptmx_open,

.release = tty_release,

.fasync = tty_fasync,

};

#endif

static const struct file_operations console_fops = {

.llseek = no_llseek,

.read = tty_read,

.write = redirected_tty_write,

.poll = tty_poll,

.unlocked_ioctl = tty_ioctl,

.compat_ioctl = tty_compat_ioctl,

.open = tty_open,

.release = tty_release,

.fasync = tty_fasync,

};

//从上面看几个驱动的操作函数大致相同,只有ptmx_fops的open方法和console_fops的write方法不同其他操作都是相同的所以在其

//他操作上要兼顾各种设备

//下面我们介绍下tty_driver结构和tty_struct 结构。tty_driver表示一个具体的tty设备的驱动程序,而tty_struct 表示tty设备在

//具体的分析中介绍其成员。

struct tty_driver {

int magic; /* magic number for this structure */

struct kref kref; /* Reference management */

struct cdev cdev;//可见tty设备驱动是一个字符设备设备驱动

struct module *owner;

const char *driver_name;//这里是指驱动程序的名字

const char *name;//tty设备的命名相关

int name_base; /* offset of printed name */

int major; /* major device number */

int minor_start; /* start of minor device number */

int minor_num; /* number of *possible* devices */

int num; /* number of devices allocated */

short type; /* type of tty driver */

short subtype; /* subtype of tty driver */

struct ktermios init_termios; /* Initial termios */

int flags; /* tty driver flags */

struct proc_dir_entry *proc_entry; /* /proc fs entry */

struct tty_driver *other; /* only used for the PTY driver */

/*

* Pointer to the tty data structures

*/

struct tty_struct **ttys;//驱动操作的具体tty设备

struct ktermios **termios;

struct ktermios **termios_locked;

void *driver_state;

/*

* Driver methods

*/

const struct tty_operations *ops;

struct list_head tty_drivers; //用于链接tty驱动全局链表

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: