michael@maui.cs.ucla.edu (10/26/88)
I need to know how a part of the unix kernel can call another part of the kernel (in particular, open(), read(), write(), close). Specifically, I am planning to write a device driver for a block device that would read the data from a tty device (Actually a psuedu tty who's other end is another device driver--yet another fun thing to worry about). The system is a system 5 release 2 (Unix Pc 3.51a) The open() call can be done at device initial open, the close() at device initial close, but the strategy routine will need to call read and write multiple times (I need to transfer 512 bytes of data, but the tty buffers have a limit of 255 chars. I was planning on 8 calls of 64 bytes each). Not to mention one more write to tell the other end what it is that I want them to do. Now, the obvious way of just calling "read()" will fail with a recursice TRAP inside the kernel. But there is no "open", or "read" routine defined in the kernel's name list. Between process accounting and core file creation, I know that it can be done, but I do not know how. Michael
ferencz@cwsys3..CWRU.Edu (Don Ferencz) (10/26/88)
In article <17200@shemp.CS.UCLA.EDU> michael@CS.UCLA.EDU () writes: >I need to know how a part of the unix kernel can call another part of the >kernel (in particular, open(), read(), write(), close). > [...] >The system is a system 5 release 2 (Unix Pc 3.51a) > [...] >TRAP inside the kernel. But there is no "open", or "read" routine defined >in the kernel's name list. > > Michael I don't want to go into a full desciption of how device driver routines work, but I have had some experience in their design, so I can give a brief note on where to look. You won't find routines named "read()" and "write()" in the kernel tables: these (and all other) system calls cause a trap that puts the processor into "kernel mode" where it looks up the routine name in the "sysent" table (not very important). All "read()"s, "write()"s and other I/O calls look up which device you are referring to, then based on whether the device is a "block" (like disks) or "character" device, (like serial ports) check the "bdevsw" or "cdevsw" tables, respectively. For the hard disk driver, the "bdevsw" table has an entry for the "major" number of the hard disk, which should have a field which then points to the actual routine called. To make things easy (???) for us, it is conventional to name the routine xxxread() and xxxwrite, where "xxx" is the name of the driver (for a hard disk driver, it should be "hdread()" and "hdwrite()", so these are the actual routines you are looking for. As far as calling one routine from another, that's no problem (unless you are using STREAMS, which is SYSV 3.0 or greater, so don't sweat it). Just make sure you give the correct arguments to "hdread()" and the like. The best source of information on this stuff is "The UNIX Device Drivers Guide" by AT&T. I think you'll definitely need a copy to do any serious device driver work. =========================================================================== | Don Ferencz | "And in the end/ | | ferencz@cwsys3.cwru.EDU | The love you take/ | | Department of Systems Engineering | Is equal to the love you make." | | Case Western Reserve University | -- The Beatles | ===========================================================================
andrew@frip.gwd.tek.com (Andrew Klossner) (11/03/88)
[] "Specifically, I am planning to write a device driver for a block device that would read the data from a tty device (Actually a pseudo tty who's other end is another device driver ...)" I've done something like this, as part of a mechanism by which kernel messages and /dev/console traffic are routed to an X window if-and-only-if X is up. You open the routine by calling ptsopen; you write by calling ptswrite; and you close by calling ptsclose. There are several pitfalls: 1) Under some varieties of Unix, the device driver expects the entire device number, not just the minor number. You have no easy way of finding out what the major number is. I hacked our pty driver not to care about the major number. 2) If you call ptsclose for a pseudo-terminal that's still open, the close routine will shut down the pty and the "legitimate" processes that have it open will have trouble. On the other hand, if you don't call ptsclose and nobody had it open, it won't get shut down. You either have to interact with the inode locking mechanism, or you need alternate "open" and "close" entry points into the pty driver. 3) After call call to ptswrite, you need to unschedule yourself so that the other end of the pseudo-terminal can digest what you've fed it. -=- Andrew Klossner (uunet!tektronix!tekecs!frip!andrew) [UUCP] (andrew%frip.gwd.tek.com@relay.cs.net) [ARPA]