OSDev.org

The Place to Start for Operating System Developers
It is currently Fri Apr 19, 2024 2:00 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 13 posts ] 
Author Message
 Post subject: Device Driver Interface
PostPosted: Mon Jul 19, 2004 5:26 am 
Hi all

I was wondering are there any points to concider when developing device drives and how to interface them with the Kernel.

I want my device drivers to be ELF shared libraries, that are loaded and unloaded if the particular piece of hardware is present or not respectively.

Thanks
srg


Top
  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Jul 19, 2004 6:04 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
well, that means that you'll need some "super driver" (for instance a bus driver like in the Mobius ddk) that will probe the different busses (pci, usb, ata) and identify hardware that might need a driver.

Personnally, i decided to have a small software component that will check meta-data blundled with each available driver (e.g. the Features list) to see which one will best fit the available hardware (e.g. the one which maximizes the hardware's utility according to features).

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Jul 19, 2004 6:22 am 
Offline
Member
Member
User avatar

Joined: Thu Nov 16, 2006 12:01 pm
Posts: 7614
Location: Germany
You might want to check http://www.project-udi.org, which advocates a "Uniform Driver Interface" - basically, a portable driver architecture. The project was basically stopped dead when the .com-bubble burst and the Free Software Foundation voiced its dislike of UDI, but the mere concept is worth considering IMHO. (In the very least, that'd mean we two could interchange drivers once I get to the point. ;-) )

_________________
Every good solution is obvious once you've found it.


Top
 Profile  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Jul 19, 2004 8:12 am 
The other thing I was going to ask was how exactly do I create ELF shared libraries with my GCC cross compiler?

Also, how do I introduce my Kernel to the routines in the shared library file. The reason I say this is that normally, the main executable, at least with PE DLLs, is compiled to expect that library dynamically linked into it's address space, so it then just calls the libraries functions as if they were compiled into the program its stelf AFAIK. With the Kernel, it doesn't necessarily know what functions are in the library. Also, an executable AFAIK is compiled to expect certain librares (the ones with the routines it needs), with the kernel, completly new libraries (drivers), that is was never compiled to expect, can be loaded and unloaded at need. Not to mention that with a normal shared library, it's the OS enviroment that checks for dependant shared libaraies and then loads and links them in.

This is what's getting me
Thanks
srg

srg


Top
  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Jul 19, 2004 8:31 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
srg wrote:
The other thing I was going to ask was how exactly do I create ELF shared libraries with my GCC cross compiler?

I'm not sure at all making it a *shared* ELF file will be the best option (because of how shared ELF look like with IA-32: requiring ebx to be kept up-to-date with the current file's table in a kernel context ?), compared to a ELF file in which you'd keep the relocation informations ...

If your 'kernel space' is large enough (e.g. 1GB), you could also decide to pin-point a location for each module (if you're really uncomfortable with relocation and as uncomfortable as i am with ELF shared stuff)

Quote:
Also, how do I introduce my Kernel to the routines in the shared library file.

like 'how will the shared module call kalloc and kprint' ? well you have several options, like
- having a well-known interrupt that will provide a interface to all the kernel functions (a Kernel Programming Interface)
- leave kernel-defined symbols pending in the ELF file (thus with a list of symbols) and resolve them while loading
- have a 'jump table' ready in each driver that will be filled with the kernel jump table's content when loading.

Hope i made myself clear enough. Don't hesitate to bug me back if i've been too fast on some point.
If you're interrested in how clicker solved the problem, you may check http://clicker.sourceforge.net/forums/i ... hreadid=17

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Jul 19, 2004 8:35 am 
Pype.Clicker wrote:
Quote:
Also, how do I introduce my Kernel to the routines in the shared library file.

like 'how will the shared module call kalloc and kprint' ?


I meant

'how will the Kernel call functions in the shared module'

Sorry
srg


Top
  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Jul 19, 2004 9:33 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
This is much easier. For instance, your driver's initialization function may return a structure that the kernel will use to invoke the module. Thinking "? la COM" here can help alot.

Your driver offers one (or possibly many) *interfaces* to the kernel. Some interfaces are known by the kernel itself, other may be known only by some other components. In the first case, a table with a collection of function pointer is just fine.

Code:
   struct Device { void (read*)(...); void (write*)(...); }
   typedef struct Device* (InitDriver)();

   
   MyDriver=((InitDriver)Elf.EntryPoint)();
   MyDriver.read(...);


In the latest, you'll probably have one such table of fctptr for each 'interface' and will offer a 'basic interface' (iUnknown :) ) to the kernel so that it can get any interface for the sake of another component through the 'basic' interface.

i'm still cooking my own devices/drivers model so i cannot come with a clear suggestion on what interfaces to offer ...

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Jul 19, 2004 10:45 am 
Pype.Clicker wrote:
This is much easier. For instance, your driver's initialization function may return a structure that the kernel will use to invoke the module. Thinking "? la COM" here can help alot.

Your driver offers one (or possibly many) *interfaces* to the kernel. Some interfaces are known by the kernel itself, other may be known only by some other components. In the first case, a table with a collection of function pointer is just fine.

Code:
   struct Device { void (read*)(...); void (write*)(...); }
   typedef struct Device* (InitDriver)();

   
   MyDriver=((InitDriver)Elf.EntryPoint)();
   MyDriver.read(...);


In the latest, you'll probably have one such table of fctptr for each 'interface' and will offer a 'basic interface' (iUnknown :) ) to the kernel so that it can get any interface for the sake of another component through the 'basic' interface.

i'm still cooking my own devices/drivers model so i cannot come with a clear suggestion on what interfaces to offer ...


Or I suppose the Kernel, when linking in the module could simply look out for a magic string (a la VBE) or magic number which tells it were the table of function pointers are. Then, once copied into its reference structure, it could add to the function pointers the base address of where the module has been loaded (is this a bit like what PIC is like?) so the calls jump the the right address, of course this would also need to happen to data as well, hmm. Anyway, in which case, surely the module wouldn't need be be ELF at all, just a simple custom object format?

Could this work (with a bit of filling out)?
srg

BTW Thanks, you've given me some ideas to go away with.


Top
  
 
 Post subject: Re:Device Driver Interface
PostPosted: Tue Jul 20, 2004 2:47 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
srg wrote:
Or I suppose the Kernel, when linking in the module could simply look out for a magic string (a la VBE) or magic number which tells it were the table of function pointers are.

Yes, it could, but why scanning for a magic number while just using the entry point (which could either be a function returning info or a table) would be enough ? The purpose of magic scan (imho) is to locate some information which location cannot be standardized and when you have nothing you can call ...

Quote:
Then, once copied into its reference structure, it could add to the function pointers the base address of where the module has been loaded (is this a bit like what PIC is like?) so the calls jump the the right address,


So you're suggesting something like
Code:
   kernel_something() {
        void *base=load_driver("myDriver");
        FctPtr **export_table=find_export_table(base);
        for (FctPtr **export=export_table;*export!=MAGIC_END_OF_TABLE;export++)
            *export+=base;
   }


that looks like a partial relocation to me. The problem with it is that data reference cannot be relative and that they won't be fixed by this code. If variables can be made relative to a "global object structure" which pointer would be passed at any driver invocation, there are some references (like those pointing to constant strings) that you cannot alter this way from your code.

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Device Driver Interface
PostPosted: Tue Jul 20, 2004 7:42 am 
So what driver model does clicker, or say mobius have at the moment. (I know mobius uses PE not ELF)

srg


Top
  
 
 Post subject: Re:Device Driver Interface
PostPosted: Tue Jul 20, 2004 9:04 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
i won't try to describe the mobius, as tim did it marvelously in its device book (yet the document seems to be offline atm, but it should be at http://mobius.sourceforge.net/index.php)

Concerning Clicker,
- i have modules in a personal format, which includes the relocation list
- each module has a list of symbols which it will import from the running system (among which kalloc, but also helper functions for I/O operations etc) and a list of locations to be patched with the symbol's value.
- the device driver manager initially reads the header of every kdrv file it can find and list them by io bus. For instance, the IDELBA driver belongs to bus "ATA".

- a special category of drivers ("bus" drivers) are used to scan hardware and detect devices and their properties. These drivers are loaded by the driver manager and will report things like "device for ATA bus, available properties are: LBA, UDMA"

- for each reported device, an entry is created. When a program will attempt to access that device (say device.disk.primary-master), the broker is invoked to find a driver that will match the device. As the broker knows the 'bus' on which the device is attached and the available drivers for that bus, it just needs to compare the offered features of the device with the required features of the driver and picks the one that will make the best use of the device.

- each driver has an "ioDriverControl" structure telling (for instance) how devices should be attached with the driver, which is returned as a result of kdrv's init() function


Hmm ... i didn't remember it had *that* many steps ...

_________________
Image May the source be with you.


Top
 Profile  
 
 Post subject: Re:Device Driver Interface
PostPosted: Tue Jul 20, 2004 11:00 am 
Pype.Clicker wrote:
i won't try to describe the mobius, as tim did it marvelously in its device book (yet the document seems to be offline atm, but it should be at http://mobius.sourceforge.net/index.php)

Concerning Clicker,
- i have modules in a personal format, which includes the relocation list
- each module has a list of symbols which it will import from the running system (among which kalloc, but also helper functions for I/O operations etc) and a list of locations to be patched with the symbol's value.


How do you do this BTW. What are you patching? Individual instructions that make memory references possibly?

srg


Top
  
 
 Post subject: Re:Device Driver Interface
PostPosted: Mon Aug 02, 2004 4:16 am 
Offline
Member
Member
User avatar

Joined: Wed Oct 18, 2006 2:31 am
Posts: 5964
Location: In a galaxy, far, far away
okay, let's say you have in some C code
Code:
    buffer=kalloc(KMEM_KERNEL, 512);

the object file will look like (pd, pb, cn are opcodes for PushDword, PushByte and CallNear respectively):
Code:
+0:    pd 00 02 00 00    push 512
+5:    pb 02                  push 2 ;; KMEM_KERNEL
+7:    cn 00 00 00 00    call 0x00000000
;; an entry in the relocation info of the object file tells that
;; when linking, the address of 'kalloc' symbol should be
;; added to value at offset +8 ...
+C:   ad 08                  add esp, 8


A helper tool inspect the .coff or .elf file and browse the relocation information so that it put it in a 'easier-to-use' form for me, but the information basically remains the same:
value of symbol "kalloc" should be added to dword at offset 8

So the relocation looks like
Code:
foreach $symbol (@module.import_table) {
    $value = resolve($symbol.name);
    foreach $where ($symbol.references) {
       ((dword*)(module.loaded+$where)) += $value;
    }
}


Hope this helps.

_________________
Image May the source be with you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot] and 95 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group