学习笔记 --- LINUX TTY子系统框架分析

本文详细解析了 Linux 中 tty 设备驱动的工作原理,包括字符设备的创建与注册过程,以及如何通过设备节点找到对应的驱动并进行操作。特别介绍了 UART 驱动的注册流程及其与 tty 设备之间的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

入口:tty_init
1 创建tty_cdev字符设备
cdev_init     /*设置字符设备操作函数为tty_fops*/
cdev_add        /* 注册字符设备*/
2 创建console_cdev字符设备(用于终端打印)
cdev_init     /*设置字符设备操作函数为console_fops*/
cdev_add      /* 注册字符设备*/

操作tty就是操作字符设备那样,这里以open为例说明。

打开一个tty设备时,调用tty_fops里的:
open 
		ret = __tty_open(inode, filp);
				dev_t device = inode->i_rdev; //通过设备节点找到设备号
				driver = get_tty_driver(device, &index)  //通过设备号,找到驱动与index
						list_for_each_entry(p, &tty_drivers, tty_drivers) {  //遍历链表
							dev_t base = MKDEV(p->major, p->minor_start);
							if (device < base || device >= base + p->num)
								continue;
							*index = device - base;
							return tty_driver_kref_get(p);
						}
				tty = tty_init_dev(driver, index, 0)  //用driver数据初始化一个新的tty_struct
						tty = alloc_tty_struct();
						initialize_tty_struct(tty, driver, idx);
						tty->driver = driver;
						tty->ops = driver->ops;
						tty->index = idx;
				retval = tty_driver_install_tty(driver, tty); //安装tty_struct
				retval = tty->ops->open(tty, filp);   //driver->ops里面的open
上面可以知道:操作tty时,通过设备节点找到设备号,再找到驱动,再调用驱动的抽象操作driver->ops,那么这个驱动怎样注册的?
以uart为例,注册驱动时:
ret = uart_register_driver(&s3c24xx_uart_drv)  //uart_driver转换成tty_driver再注册
		normal  = alloc_tty_driver(drv->nr);
		drv->tty_driver = normal;
		normal->driver_state    = drv; //s3c24xx_uart_drv设置为tty_driver的driver_state
		tty_set_operations(normal, &uart_ops)   
				driver->ops = op;  //设置好驱动的操作抽象:driver->ops
		retval = tty_register_driver(normal)
				list_add(&driver->tty_drivers, &tty_drivers);  //添加到链表
上面的操作抽象driver->ops里面的接口最终调用normal->driver_state的操作函数,而normal->driver_state= drv,所以这里调用的s3c24xx_uart_drv;
比如之前说过再open一个tty时,调用的是driver->ops里面的open,这里就是uart_ops里面的uart_open,这个uart_open是怎么找到他对应的硬件操作的?

uart_open
		struct uart_driver *drv = (struct uart_driver *)tty->driver->driver_state  
		/*driver_state就是s3c24xx_uart_drv,在uart_register_driver(&s3c24xx_uart_drv)的时候设置的:normal->driver_state=drv;*/
		line = tty->index
		state = uart_get(drv, line);  //state = drv->state + line;
		uart_startup
				struct uart_port *uport = state->uart_port;
				retval = uport->ops->startup(uport); //uart_open的实际硬件操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值