lenny@icus.islp.ny.us (Lenny Tropiano) (07/10/89)
Well I've been dabbling a little in device drivers lately, and my current quest is to see if I could write a block device driver. Using my copy of the blocks _Writing_a_UNIX_Device_Driver_ by Janet I. Egan and Thomas J. Teixeira, and their block driver example, I decided a good place to start would be their *working* driver. Although the book is specific to MASSCOMP's implementation of UNIX, RTU, the device-driver kernel routines were almost all identical to the UNIX pc's kernel routines. With that book, and my trusty photocopy of the "UNIX PC Version 3.0 Device Driver Development Guide, Issue 0" I was on my way ... First I started by typing in the 12 pages of code (to implement sort of a mini-ram disk), minus the comments for now ... Then I did the dreaded "cc -c" on the file. It had a few errors, undefined this, undefined that, typos, etc... I played around with the header files in /usr/include/sys, and got the appropriate changes (not much), and off I went to compile land. This time it compiled up! Ok, now I had to go hunting for Mike Ditto's vidram stuff, needed the simple INSTALL scripts he had. Found 'em! Modified the INSTALL scripts to install the block/character(for raw access) device and typed "./INSTALL". Off it went, installing the device into the /etc/master file with the commands ... /etc/masterupd -a block char init release open close ioctl read \ write strategy ram MAJ=`/etc/masterupd -b ram` /etc/mknod /dev/ram b $MAJ 0 MAJ=`/etc/masterupd -c ram` /etc/mknod /dev/rram c $MAJ 0 Then ... it did the /etc/lddrv/lddrv command to allocate and bind the driver. cp ram.o /etc/lddrv /etc/lddrv/lddrv -av ram allocated: 0x4000 bytes starting at 0x5c000 for device ram, B:10 C:9 id:4 BIND failed: invalid argument ... Hmm, I thought. What did I do wrong? I wrote to Alex Crain (alex@umbc3.umbc.edu), who gave me some advice on where to look ... Basically the drvbind() kernel routine failed to bind the driver because of something... (he outlined 4 or so reasons why possibly). Nope, the driver looked OK. Then I spoke with Gil Kloepfer (gil@limbic.UUCP) one evening, and he was saying, "Can we do loadable block devices? Do they work?" All the devices we've used are character oriented. He suggested making a dummy driver with all function stubs. ram.c: raminit() { } ramrelease() { } ramopen() { } ramclose() { } ramioctl() { } ramstrategy() { } ramread() { } ramwrite() { } This compiled (of course) and then I tried the /etc/lddrv/lddrv -av ram command again... Sure enough it failed with the SAME ERROR! Hmm, I thought, the only block driver I know of is the disk driver, and that isn't loadable. (It's built into the kernel). Block Devices major device handler flags 0 disk gd ioctl write read close open pwr strategy fix char block required ... Hmmm, I thought to myself, I know I've seen somewhere you can do loadable block drivers (even though the UNIX PC Device Driver Development Guide is very vague when it comes to that... In the file /etc/master, it has this: ... * * Loadable drivers * nlbdrv number of slots for loadable block drivers * nlcdrv number of slots for loadable char drivers * nlbdrv NLBDRV 4 nlcdrv NLCDRV 10 Yes, 4 slots for loadable block drivers. Oh well, I'll forward this posting onto the person doing the work for the *next and last* FIXDISK for the UNIX PC. He's fixed everything so far, I'm sure he'll love to tackle this when he gets back from his trip :-) So to make a long story even longer, Mike Peterson who was trying the same thing and getting the same results ... now you know why. Those who tried to write SCSI device drivers (IDT) I wonder how they did it? Or if they did it at all, maybe that's why the SCSI board was abandoned ... Eventually when my driver is loaded I'll be able to do this ... # mkfs /dev/rram 200:10 # mount /dev/ram /ramdisk # df -t /ramdisk /ramdisk (/dev/ram ): 192 blocks 10 i-nodes total: 200 blocks 10 i-nodes Enough said ... -Lenny -- Lenny Tropiano ICUS Software Systems [w] +1 (516) 589-7930 lenny@icus.islp.ny.us Telex; 154232428 ICUS [h] +1 (516) 968-8576 {ames,talcott,decuac,hombre,pacbell,sbcs}!icus!lenny attmail!icus!lenny ICUS Software Systems -- PO Box 1; Islip Terrace, NY 11752
lenny@icus.islp.ny.us (Lenny Tropiano) (07/11/89)
In article <736@icus.islp.ny.us> lenny@icus.islp.ny.us (Lenny Tropiano) writes: |> ... |>cp ram.o /etc/lddrv |>/etc/lddrv/lddrv -av ram |>allocated: 0x4000 bytes starting at 0x5c000 for device ram, B:10 C:9 id:4 |>BIND failed: invalid argument |> |>... Problem has been solved. A very kind person from AT&T gave me a call today at my office, and told me that he had similar results when he tried block devices on the UNIX pc. What he said was that the drvbind() kernel routine requires the presence of *strategy() and *print() routine, even if they don't do a darn thing... In my case they would be called ramstrategy() and ramprint() respectively. Sure enough I tried this and the driver loaded and bound itself to the kernel space. Now it is time to remove the bugs from the driver ;-) BTW: According to the _UNIX PC Device Driver Development Guide_, print() routines (and I quote) ... * Print This entry point is for the error reporting routine of the driver. It is most often left unused, and is not used at all in the present UNIX PC kernel. It may be here for historic reasons. Obviously if this isn't used at all ... I still consider it a bug that drvbind() requires it. Oh well, if it can't be fixed at the present, this will do. ramprint() { panic("Ut oh! I'm in ramprint(), how did I manage this?"); } -Lenny -- Lenny Tropiano ICUS Software Systems [w] +1 (516) 589-7930 lenny@icus.islp.ny.us Telex; 154232428 ICUS [h] +1 (516) 968-8576 {ames,talcott,decuac,hombre,pacbell,sbcs}!icus!lenny attmail!icus!lenny ICUS Software Systems -- PO Box 1; Islip Terrace, NY 11752