Xref: utzoo comp.unix.questions:26373 comp.unix.sysv386:1426 Path: utzoo!attcan!uunet!know!zaphod.mps.ohio-state.edu!usc!apple!portal!cup.portal.com!ts From: ts@cup.portal.com (Tim W Smith) Newsgroups: comp.unix.questions,comp.unix.sysv386 Subject: Re: Loadable device drivers...in V.4? Message-ID: <35110@cup.portal.com> Date: 21 Oct 90 14:37:22 GMT References: <6681@suns302.cel.co.uk> Organization: The Portal System (TM) Lines: 71 I wish vendors would do this. It's not even hard. I worked out how it could be done a long time ago (when I worked at Callan Data Systems), but didn't try it. When I worked at Interactive, I got to try it. It only requires a couple of relatively simple kernel changes. First, you need a system call that will allocate kernel memory for the driver. Second, you need a system call that will install an interrupt handler for the driver. The rest you do with a program. The basic things that must be done to load a driver are these: Assuming the driver object file is named Driver.o, get a list of undefined external references in Driver.o. Use nm or ld to do this for you. Look up each of these in the kernel symbol table. You must have a kernel symbol table, of course, for this to work. Make a file that defines these externals as absolute references to the values obtained from the kernel symbol table. I don't remember if I did this by making as assembly file that declared them this way, or some sort if input file for ld. It's been a while since I did this. The program (which must be running as root) now uses the system call for memory allocation to allocate memory in the kernel for the driver. This system call returns the base address in kernel space of the allocated memory. Use ld and the file created two steps ago and the return value from the memory allocation system call to create a .o file that has all external references resolved and is set up to be loaded at the address of the kernel memory allocated in the previous step. The driver loader program now opens /dev/kmem and copies the driver into the memory allocated a couple of steps ago. The driver loader then adds entries for the driver open, close, read, etc., routines into the appropriate kernel table (bdevsw, cdevsw, or whatever). The driver load program uses the second new system call to tell the kernel what interrupt the driver uses, and where the interrupt routine is at. The ISC version of this could load drivers and streams modules. Facilities were also included to unload drivers. The main reason it was never released by ISC was that they were interested in this as a way to make the kernel smaller on the boot floppy. At the time, there were limits in the boot program on the size of a kernel that could be loaded, and if all the drivers they wanted were in the kernel, it would exceed those limits. However, someone fixed the boot program, so they did not need the loadable driver stuff. I was in the process of leaving at the time, so I don't know what ever happened to it after that. I wish they had pursued it. I've developed a couple of drivers since then, and would have really appreciated being able to test minor changes without having to rebuild the kernel. In my experience, there is a long period at the end of a driver project where the thing works well enough that it is not crashing the kernel, but it needs various tweeks. This stage would go much faster with a way to load drivers without rebooting the system. Tim Smith