- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
TTY的初始化
我一直都以为tty-init这个过程是很简单的,实际上不是。比我想象的要复杂得多(或许我还没有接触到更复杂的内存管理和进程调度,我才会这样说:)
几点以前模糊的概念:
在linux-0.01中的tty-init()函数实际就做两个事情。一 初始化串口1、2。二 初始化控制台(包括显示设备终端,和模拟的控制台)。
串口和控制台终端都属于字符设备。因此他们的相关代码在charact device下。
初始化的目的其实就是把相关设备的驱动程序“挂”到系统中。其实相关数据和中断服务程序的初始化等等(不过不是完整的设备驱动概念哦)。
控制台设备都有统一的设备数据结构来抽象。
无论是串口还是显示终端,这里都是说明硬件操作的部分,并不设计串口协议之类的东东。
显示终端的操作远要比串口来得复杂。
(1)数据结构
Tty-io中定义了TTY设备统一的数据结构:struct tty_struct tty_table[]
显示终端:tty_table[0]
串口1:tty_table[1]
串口2:tty_table[2]
(2)如果需要“涉及”终端,就从tty-io.c文件开始……
tty_read(unsigned channel, char * buf, int nr)
channel:通道0(显示终端)1(串口1)2(串口2)
buf :输入缓冲区(1Kbyte)
nr :实际字节长度
tty_write(unsigned channel, char * buf, int nr)
channel:通道0(显示终端)1(串口1)2(串口2)
buf :输出缓冲区(1Kbyte)
nr :输出字节长度
例如:printk(const char *fmt, ...) 这是内核使用的打印输出到显示终端的函数,调用了函数tty_write(0,buf,nr)来把信息输出到显示终端设备上去。
(纳闷这三个函数参数是怎么被传过来的?这要看汇编与C的接口,或者跟编译相关,我打算放在中断和系统调用中一起搞定)
猜测这些设备和操作经过再封装,应该就成了文件系统中所谓的设备0,1,2等等,呵呵!
(3)tty设备初始化
Rs-init():初始化串口1,2。
设置一些串口寄存器
设置中断处理服务程序(陷阱门)
开串口中断
Con-init():初始化显示终端,这个要复杂些。
首先,显示的相关硬件的信息是在setup阶段获得的,这里要先取出这些信息。
根据这些信息来初始化显示。
设置滚屏初始化信息
光标信息初始化
初始化中断??阱门
开启中断
看起来初始化过程跟使用好象不相关,实际也是,初始化完了之后,我们再使用这些终端时,都是通过struct tty_struct tty_table[]来的。而这个结构,及调用的函数实现CON-WRITE,等等都是独立的。struct tty_struct tty_table[]就是全局的变量,在定义这个变量的同时就初始化了有关的数据。所以,初始化完成后。就直接调用吧。
READ?
(4)在main.c中,现在终于明白:在tty_init()之后就可以使用printk(),由于我们在内核态,所以只能使用prink()来打印,并且正因为是在内核printk()函数的“底层”是call –tty-write(),而不是系统调用(这些话显然多余)。但是在move to user之后应该就不能使用printk()。而应该使用printf()。实际上,在添加一个printf()后我连编译都过不去,现在还不知道为什么?也许要等到write的系统调用搞明白后就清楚了。
这样就OK了,以后的事情以后再说吧!(看完以后也不是那么难)
其实这一个部分是在看main()函数的TTY-init()函数后的总结。接下来应该是中断和异常===直接转到那个文档目录下吧。
原创力文档


文档评论(0)