?? tty layer - the kernel structures.htm
字號(hào):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0059)http://www.geocities.com/marco_corvi/games/lkpe/tty/tty.htm -->
<HTML><HEAD><TITLE>The TTY layer</TITLE>
<META http-equiv=Content-Type content="text/html; charset=windows-1252"><LINK
href="tty layer - The kernel structures_file/style.css" rel=stylesheet>
<META content="MSHTML 6.00.2800.1170" name=GENERATOR></HEAD>
<BODY>
<H2>tty layer - The kernel structures</H2>
<DIV>References:<BR>G. Kroah-Hartman, "The tty layer", Linux Journal, Aug. 2002,
40-47<BR>G. Kroah-Hartman, "The tty layer - Part II", Linux Journal, Oct. 2002,
50-58<BR>G. Kroah-Hartman, "The USB serial driver layer", Linux Journal, Feb.
2003, 38-41<BR>G. Kroah-Hartman, "The USB serial driver layer - Part II" Linux
Journal, Apr. 2003, 32-35<BR></DIV><BR clear=all><BR clear=all><BR clear=all>
<DIV>The tty layer is split into two structures: the tty driver and the line
discipline. The driver handles the backend hardware; the line discipline is like
a filter on the input/output. These two structures are contained in the
<CODE>tty_struct</CODE>, which has also a structure, called flip buffer, for
buffering input characters, and pointers to the termios. These structures are
defined in four header files, in the include/linux subdirectory,
<UL>
<LI><CODE>tty.h</CODE>, with <CODE>screen_info</CODE>,
<CODE>tty_flip_buffer</CODE> and <CODE>tty_struct</CODE>;
<LI><CODE>tty_driver.h</CODE>, with <CODE>tty_driver</CODE>;
<LI><CODE>tty_ldisc.h</CODE>, with <CODE>tty_ldisc</CODE>;
<LI><CODE>tty_flip.h</CODE>, defines two inline routines
<UL>
<LI><CODE>tty_insert_flip_char</CODE>: insert a char and a flag into the
<CODE>flip</CODE> buffers;
<LI><CODE>tty_schedule_flip</CODE>: append the flip <CODE>tqueue</CODE> to
the timer task queue. The routine <CODE>tty_flip_buffer_push</CODE> either
calls <CODE>flush_to_ldisc()</CODE>, if the low-latency flag is set, or
submit the tty's flip buffer <CODE>tqueue</CODE> on the timer queue. This
tqueue is initialized with the <CODE>flush_to_ldisc()</CODE> routine and the
tty data: see the description of <CODE>initialize_tty_struct</CODE> below.
</LI></UL></LI></UL></DIV><BR clear=all><IMG height=320 alt="tty structures"
src="tty layer - The kernel structures_file/tty_struct.gif" width=480> <BR
clear=all>
<DIV>The <CODE>screen_info</CODE> contains video informations, and data for the
linear frame buffer of VESA graphic mode. </DIV>
<DIV>The <CODE>tty_flip_buffer</CODE> contains two input buffers of size twice
<CODE>TTY_FLIPBUF_SIZE</CODE> (512), one of characters the other of flags (for
parity errors). The flip buffers are logically made of two parts, and the code
fills alternatively one or the other. <CODE>buf_num</CODE> denotes the part in
use, and <CODE>count</CODE> the number of bytes that have been received. There
is a task_queue <CODE>tqueue</CODE> and a semaphore <CODE>pty_sem</CODE>.
</DIV><BR clear=all><B>TTY, tty_struct</B> <BR clear=all>
<DIV>
<UL>
<LI>It contains a tty_driver <CODE>driver</CODE>;
<LI>a line discipline <CODE>ldisc</CODE>;
<LI>pointers to the <CODE>termios</CODE> and <CODE>termios_locked</CODE>;
<LI>several flags and counters;
<LI>a <CODE>link</CODE> to another tty_struct's (for ptty). It is used in the
<CODE>stop</CODE>/<CODE>start</CODE> methods of the tty_driver: the link's
read_wait queue is waken up if its <CODE>packet</CODE> flag is set;
<LI>a tty_flip_buffer <CODE>flip</CODE>;
<LI>two wait_queue_head_t, <CODE>write_wait</CODE> and <CODE>read_wait</CODE>;
<LI>a tq_struct <CODE>tq_hangup</CODE>;
<LI>a list of <CODE>tty_files</CODE>;
<LI>other fields for the N_TTY line discipline. </LI></UL></DIV><BR
clear=all><B>Device driver, tty_driver</B> <BR clear=all>
<DIV>
<UL>
<LI>It contains accessory informations: <CODE>driver_name</CODE>,
<CODE>name</CODE>, <CODE>major</CODE>, <CODE>num</CODE> (number of devices),
<CODE>type</CODE> and <CODE>subtype</CODE> (type and subtype of the tty
driver), <CODE>flags</CODE>, and others
<LI>the pointer to the <CODE>table</TABLE> of tty_struct;
<LI><CODE>termios</CODE> and <CODE>termios_locked</CODE>;
<LI>two pointers for a doubly-linked list, <CODE>next</CODE> and
<CODE>prev</CODE>.
<LI>the tty_driver methods:
<UL>
<LI><CODE>open</CODE>, called after a user open.2;
<LI><CODE>close</CODE>, called after a user close.2
<LI><CODE>write</CODE>, called after a user write.2 or when the kernel needs
to write to the tty device
<LI><CODE>put_char</CODE>, called by the kernel to write a single character;
<LI><CODE>flush_chars</CODE>, called by the kernel after writing a number of
characters to the tty device using put_char.
<LI><CODE>write_room</CODE>, returns the number of characters the tty device
will accept for writing.
<LI><CODE>ioctl</CODE>, driver specific ioctl's
<LI><CODE>set_termios</CODE>, used to notify the tty driver of a change of
termios;
<LI><CODE>set_ldisc</CODE>, used to notify the tty driver of a change of
line discipline;
<LI><CODE>throttle</CODE>, tells the tty driver that the input buffers of
the line discipline are close to full;
<LI><CODE>unthrottle</CODE>, tells the tty driver that the input buffers of
the line discipline have enough space;
<LI><CODE>stop</CODE>, stops the tty driver from sending out characters to
the tty device;
<LI><CODE>start</CODE>, starts the tty driver to send out characters to the
device;
<LI><CODE>hangup</CODE>, tells the tty driver to hang up the tty device;
<LI><CODE>break_ctl</CODE>, toggle the BREAK status on the RS-232 port;
<LI><CODE>wait_until_sent</CODE>, the tty driver waits until the device has
written out all the characters in its FIFO queue;
<LI><CODE>send_xchar</CODE>, send a high-priority XON-XOFF character to the
device. </LI></UL></LI></UL></DIV><BR clear=all><B>Line discipline,
tty_ldisc</B> <BR clear=all>
<DIV>
<UL>
<LI>A line discipline consists of a <CODE>magic</CODE> number, a
<CODE>name</CODE>, <CODE>flags</CODE> (of the line discipline),
<CODE>num</CODE> (index of the line discipline in the global
<CODE>ldiscs</CODE> array);
<LI>It has methods called from above, ie, from the user perspective,
<UL>
<LI><CODE>open</CODE>, called when the line discipline is associated with
the tty. The line discipline can do any suitable initialization and return
negative on failure.
<LI><CODE>close</CODE>, called when the line discipline is shut down, either
because the tty is closed or it changes the line discipline.
<LI><CODE>read</CODE>, called after a user read.2.
<LI><CODE>write</CODE>, called after a user write.2. It must deliver the
characters to the low-level tty device.
<LI><CODE>ioctl</CODE>, called after a user ioctl.2 that is not handled by
the tty layer or the low-level tty driver.
<LI><CODE>poll</CODE>, called after a user select/poll.
<LI><CODE>set_termios</CODE>, called after a user set_termios.
<LI><CODE>flush_buffer</CODE>, called to tell the line discipline to send
any input character in the buffer to the user process.
<LI><CODE>chars_in_buffer</CODE>, returns the number of input characters
buffered by the line discipline. </LI></UL>
<LI>It defines methods called from below, ie from the low-level tty_driver
<UL>
<LI><CODE>receive_buf</CODE>, called to send characters to the line
discipline.
<LI><CODE>receive_room</CODE>, returns the number of characters that the
line discipline can accept.
<LI><CODE>write_wakeup</CODE>, called to tell the line discipline that it
can send down more characters. </LI></UL></LI></UL></DIV><BR
clear=all><B>tty_fops</B> <BR clear=all>
<DIV><CODE>tty_register_driver()</CODE> inserts the tty_driver into the list of
the <CODE>tty_drivers</CODE>, and if it does not provide its own routine
<CODE>put_char()</CODE> assignes the <CODE>tty_default_put_char()</CODE> to it.
It registers the tty_driver with the devfs (devfs_register_chrdev), and with the
proc filesystem (proc_tty_register_driver). The file operations are
<CODE>tty_fops</CODE>):
<UL>
<LI><CODE>tty_read</CODE>: after some checks it locks the kernel and calls the
line discipline read function. Then it unlocks the kernel;
<LI><CODE>tty_write</CODE>: it does some checks and then calls
<CODE>do_tty_write()</CODE> which down's the semaphore
<CODE>atomic_write</CODE>, locks the kernel, calls the write function (of the
line discipline), and unlocks and ups;
<LI><CODE>tty_poll</CODE> calls the poll routine of the line discipline;
<LI><CODE>tty_ioctl</CODE>;
<LI><CODE>tty_open</CODE>: essentially it calls <CODE>init_dev()</CODE> to
retrieve the tty_struct for the device number, and the <CODE>open</CODE>
routine of the tty's driver;
<LI><CODE>tty_release</CODE> calls <CODE>release_dev()</CODE>;
<LI><CODE>tty_fasync</CODE>; </LI></UL></DIV>
<DIV><B><CODE>init_dev()</CODE></B> allocates a new tty_struct, and initializes
it (by calling <CODE>initialize_tty_struct()</CODE>); sets up the tty's termios,
termios_locked, device, driver, count; sets up the driver's table entry for this
device; finally it calls the tty's line discipline <CODE>open()</CODE>. </DIV>
<DIV><B><CODE>initialize_tty_struct()</CODE></B> performs the initialization of
a tty_struct. It sets the magic number (TTY_MAGIC), the line discipline (with
the default ldiscs[N_TTY]), the fields in the tty flip_buffer (in particular the
<CODE>tqueue</CODE> with routine <CODE>flush_to_ldisc</CODE> and data the
<CODE>tty</CODE>), the write and read wait_queues, the task_queue
<CODE>tq_hangup</CODE> (routine <CODE>do_tty_hangup</CODE>, data
<CODE>tty</CODE>). Finally it initializes the semaphores
<CODE>atomic_read</CODE> and <CODE>atomic_write</CODE>, the list_head
<CODE>tty_files</CODE>, and the secure-attention-key task_queue
<CODE>SAK_tq</CODE>. </DIV>
<DIV><B><CODE>flush_to_ldisc()</CODE></B>: if the tty has the TTY_DONT_FLIP flag
set, the flip <CODE>tqueue</CODE> is queued on the timer queue. Otherwise the
buffer pairs are "flipped", the flip count is reset to zero, and the line
discipline <CODE>receive_buf</CODE> is called. </DIV><BR clear=all><B>The line
discipline tty_ldisc_N_TTY</B> <BR clear=all>
<DIV>The line discipline <CODE>tty_ldisc_N_TTY</CODE> is defined in n_tty.c with
the following methods,
<UL>
<LI><CODE>n_tty_open</CODE> allocates a <CODE>read_buf</CODE> for the
tty_struct;
<LI><CODE>n_tty_close</CODE> flushes the buffer and frees the
<CODE>read_buf</CODE>
<LI><CODE>n_tty_flush_buffer</CODE> clears everything and unthrottle the
driver;
<LI><CODE>n_tty_chars_in_buffer</CODE> returns the number of characters in the
buffer to be delivered to the user, ie, the difference between
<CODE>read_head</CODE> and <CODE>read_tail</CODE>
<LI><CODE>read_chan</CODE> is rather complicated, but essentially it amounts
to add the current process to the tty_struct <CODE>read_wait</CODE> queue;
copy characters from the buffer to the user buf. When done remove the current
process from the wait_queue.
<LI><CODE>write_chan</CODE> adds the current process to the tty_struct
<CODE>write_wait</CODE> queue; calls the tty driver write(tty, 1, buf, count)
routine; possibly schedule(). When done removes the current process from the
wait_queue.
<LI><CODE>n_tty_ioctl</CODE>
<LI><CODE>n_tty_settermios</CODE>
<LI><CODE>normal_poll</CODE>
<LI><CODE>n_tty_receive_buf</CODE> copies the received chars in the
<CODE>read_buf</CODE> with possible line discipline processing. If the
tty_struct is not ICANON and the <CODE>read_cnt</CODE> is more than the
<CODE>minimum_to_wake</CODE> calls the fasync method on the tty_struct.
Finally it checks whether to throttle or not the device.
<LI><CODE>n_tty_receive_room</CODE>
<LI><CODE>n_tty_write_wakeup</CODE> calls the fasync method on the tty_struct
</LI></UL></DIV><BR clear=all><FONT size=-1>Marco Corvi - 2003</FONT> <!-- text below generated by server. PLEASE REMOVE --></OBJECT></LAYER>
<DIV></DIV></SPAN></STYLE></NOSCRIPT></TABLE></SCRIPT></APPLET>
<SCRIPT
language=JavaScript>var PUpage="76001084"; var PUprop="geocities"; </SCRIPT>
<SCRIPT language=JavaScript
src="tty layer - The kernel structures_file/pu5geo.js"></SCRIPT>
<SCRIPT language=JavaScript
src="tty layer - The kernel structures_file/ygIELib9.js"></SCRIPT>
<SCRIPT language=JavaScript>var yviContents='http://us.toto.geo.yahoo.com/toto?s=76001084&l=NE&b=1&t=1057747199';yviR='us';yfiEA(0);</SCRIPT>
<SCRIPT language=JavaScript
src="tty layer - The kernel structures_file/mc.js"></SCRIPT>
<SCRIPT language=JavaScript
src="tty layer - The kernel structures_file/geov2.js"></SCRIPT>
<SCRIPT language=javascript>geovisit();</SCRIPT>
<NOSCRIPT><IMG height=1 alt=setstats
src="tty layer - The kernel structures_file/visit.gif" width=1
border=0></NOSCRIPT> <IMG height=1 alt=1
src="tty layer - The kernel structures_file/serv.gif" width=1> <!-- w26.geo.scd.yahoo.com compressed/chunked Wed Jul 9 03:39:59 PDT 2003 --></CODE></BODY></HTML>
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -