一、首先把tty驱动在linux中的分层结构理清楚:本文引用地址:http://www.eepw.com.cn/article/201610/305940.htm

自上而下分为TTY核心层、TTY线路规程、TTY驱动。

二、TTY核心层与线路规程层分析

用户空间的程序直接对tty核心层进行读写等相关操作,在tty_io.c中:

int__init tty_init(void)

{

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'tregister /dev/tty driver\n);

device_create(tty_class,NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, tty);

………

以上的一段初始化代码可以获取以下信息:

注册了一个字符驱动,用户空间操作对应到tty_fops结构体里的函数:

staticconst 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,

};

对于字符设备驱动,我们知道,读写操作一一对应于fops.

tty_open:

static int tty_open(struct inode *inode, struct file *filp)

{

int index;

dev_tdevice = inode->i_rdev;

structtty_driver *driver;

……

driver= get_tty_driver(device, index);

……

tty= tty_init_dev(driver, index, 0);

……

retval= tty_add_file(tty, filp);

……

if(tty->ops->open)

retval= tty->ops->open(tty, filp);

get_tty_driver是根据设备号device,通过查找tty_drivers全局链表来查找tty_driver.

tty_init_dev是初始化一个tty结构体:

tty->driver= driver;

tty->ops= driver->ops;

并建立线路规程:

ldops= tty_ldiscs[N_TTY];

ld->ops= ldops;

tty->ldisc= ld;

其实tty_ldiscs[N_TTY]在console_init中确定,该函数在内核启动的时候调用。

tty_register_ldisc(N_TTY,tty_ldisc_N_TTY);

则:tty_ldiscs[N_TTY]=tty_ldisc_N_TTY;

struct tty_ldisc_ops tty_ldisc_N_TTY = {

。magic = TTY_LDISC_MAGIC,

。name = n_tty,

。open = n_tty_open,

。close = n_tty_close,

。flush_buffer = n_tty_flush_buffer,

。chars_in_buffer= n_tty_chars_in_buffer,

。read = n_tty_read,

。write = n_tty_write,

。ioctl = n_tty_ioctl,

。set_termios = n_tty_set_termios,

。poll = n_tty_poll,

。receive_buf = n_tty_receive_buf,

。write_wakeup = n_tty_write_wakeup

};

tty_add_file主要是将tty保存到file的私有变量private_data中。

tty->ops->open的调用,实则上就是应用driver->ops->open.这样,我们就从tty核心层到tty驱动层了。

tty_write:

static ssize_t tty_write(struct file *file, const char __user *buf,

size_t count, loff_t *ppos)

{

………

ld= tty_ldisc_ref_wait(tty);

if(!ld->ops->write)

ret= -EIO;

else

ret= do_tty_write(ld->ops->write, tty, file, buf, count);

………

}

从以上这个函数里,可以看到tty_write调用路线规程的write函数,所以,我们来看ldisc中的write函数是怎样的。经过一些操作后,最终调用:

tty->ops->flush_chars(tty);

tty->ops->write(tty,b, nr);

显然,这两个函数,都调用了tty_driver操作函数,因为在之前的tty_open函数中有了tty->ops=driver-> ops这样的操作。那么这个tty_driver是怎样的呢,在TTY系统中,tty_driver是需要在驱动层注册的。注册的时候就初始化了ops, 也就是说,接下来的事情要看tty_driver的了。

tty_read:

static ssize_t tty_read(struct file *file, char __user *buf, size_t count,

loff_t *ppos)

{

………

ld= tty_ldisc_ref_wait(tty);

if(ld->ops->read)

i= (ld->ops->read)(tty, file, buf, count);

else

i= -EIO;

……

}

像tty_write的一样,在tty_read里,也调用了线路规程的对应read函数。不同的是,这个read没有调用tty_driver里ops的read,而是这样:

uncopied= copy_from_read_buf(tty, b, nr);

uncopied+= copy_from_read_buf(tty, b, nr);

从函数名来看copy_from_read_buf,就是从read_buf这个缓冲区拷贝数据。实际上是在tty->read_buf的末尾 tty->read_tail中读取数据。那么read_buf中的数据是怎么来的呢?猜想,那肯定是tty_driver干的事了。

tty_ioctl:

long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

{

……

switch(cmd) {

case… …… :

linux 字符驱动 tty,打通linux的tty驱动的数据链路相关推荐

  1. linux字符驱动头文件路径,Linux 字符设备驱动例子

    编写好驱动,通过挂载的方法将驱动程序挂载到内核里面,大致步骤如下: 一:  1>建立以.c为后缀的c语言程序文件 (里面包含了设备名及设备号等) 2>建立Makefile文件(作用是通过m ...

  2. linux字符界面播放vcd,linux下刻录vcd的方法

    linux下刻录vcd的方法 [日期:2006-11-20] 来源: 作者: [字体:大 中 小] 刻录vcd的命令行工具:制作vcd光盘影像:vcdtools,刻录影像到光盘:cdrdao 安装:d ...

  3. Linux字符界面的cat,Linux命令之cat详解

    cat [选项] [文件] 将文件或标准输入组合输出到标准输出 如果没有指定文件,或文件为'-',则从标准输入读取 注意:当文件较大时,文本在屏幕上迅速闪过(滚屏),用户往往看不清显示的内容.因此,一 ...

  4. 使用NDB调试Linux字符设备

    使用NDB调试Linux字符设备 cdev_init 在Linux中字符设备通过cdev结构体来表示,为了观察Linux上面的字符设备的创建过程,就需要在cdev_init处设置断点. 给cdev_i ...

  5. 打通linux的tty驱动的数据链路,tty驱动

    一.首先把tty驱动在linux中的分层结构理清楚: 自上而下分为TTY核心层.TTY线路规程.TTY驱动. 二.TTY核心层与线路规程层分析 用户空间的程序直接对tty核心层进行读写等相关操作,在t ...

  6. linux tty连wifi,打通linux的tty驱动的数据链路

    一.首先把tty驱动在linux中的分层结构理清楚: 自上而下分为TTY核心层.TTY线路规程.TTY驱动. 二.TTY核心层与线路规程层分析 用户空间的程序直接对tty核心层进行读写等相关操作,在t ...

  7. 浅谈Linux tty体系,理清tty驱动层次与各种概念

    虽然Linux内核是由C语言写的,但处处体现面向对象的设计思想,这对很多只会C语言的朋友来说,理解比较困难,尤其是tty体系,涉及很多混乱的概念. 1. 上古时期的tty.terminal和conso ...

  8. linux tty设备驱动,18.1. 一个小 TTY 驱动

    ## 18.1. 一个小 TTY 驱动 为解释 tty 核心如何工作, 我们创建一个小 tty 驱动, 可以被加载, 以及写入读出, 并且卸载. 任何一个 tty 驱动的主要数据结构是 struct ...

  9. linux 串口驱动 4412,⑮tiny4412 Linux驱动开发之tty子系统(UART)驱动程序

    本次说一下tty子系统的驱动编程,因为UART相关的寄存器比较多,同时,应用比较广泛,所以本次的驱动程序量也不少,而且只是完成和特定CPU相关的一部分,通用的部分本次都没有涉及到.在写驱动之前,我们先 ...

  10. ()shi linux字符设备,Linux字符设备驱动基础(三)

    Linux字符设备驱动基础(三) 6 创建设备节点 6.1 手动创建设备节点 查看申请的设备名及主设备号: cat /proc/devices # cat /proc/devices Characte ...

最新文章

  1. 4 . 2 存储系统
  2. AIDL注意细节 简单Demo
  3. how is native onClick event passed to application handler
  4. Hibernate应用程序级可重复读取
  5. 12月10日习题答案大剖析!小伙伴们再接再厉
  6. java 标识符命名规则_java语言基础之标识符和命名规则详解
  7. 刘强东夫妇向英国捐赠大量防疫物资:在英华侨及留学生可免费认领
  8. 深入探讨运维驱动的可监控性设计
  9. 三态门三个状态vhdl_人防门施工方案
  10. Photoshop插件-删除所有亮度通道蒙板-脚本开发-PS插件
  11. unity Curvy Splines基础操作:创建可视赛道
  12. MacBook 右键查询英文查词无法翻译成中文
  13. 业务流程图设计-Visio设计
  14. linux----创建主分区、扩展分区、在扩展分区上建立逻辑分区。
  15. assimp批量转模型_IGS模型批量转换成STL模型
  16. logstash中无法解析nginx日志中的\x09类似字符导致服务停止
  17. 读取excel文件并使用matplotlib绘图(含柱状图、柱状图加数值的显示和直方图)
  18. 蓝牙技术|了解蓝牙LE Audio的Auracast广播音频
  19. 信息系统项目管理师-项目整合管理
  20. cogs 1487. 麻球繁衍(概率dp)

热门文章

  1. arm平台下的反汇编pdf_stm32逆向与安全科普,bin文件逆向反汇编
  2. python编一个答题程序_从0到1使用python开发一个半自动答题小程序的实现
  3. python中的三种排序方法,使用冒泡对列表排序,使用自带sort方法进行排序
  4. 转:Git: 对象原理
  5. 中国网和七牛云达成战略合作,携手打造国际化融媒中心
  6. OC 计算幂集 - 递归法
  7. Mysql + keepalived 实现双主热备读写分离
  8. oracle --union和union all
  9. 【权值分块】bzoj1588 [HNOI2002]营业额统计
  10. Daily Scrum 10.23