[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: drivers for l4 (2)
Re: drivers for l4 (2)
24 Mar 2003 14:24:48 +0100
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7
>>>>> "Daniel" == Daniel Wagner <address@hidden> writes:
I think all DDE could be well designed and implemented using OOP (also new
L4, pistachio should be implemented using c++). Also, because
it run in user space, could use shared objects as device driver. A design
like ACE (from smidth) could be a good example.
Daniel> The driver framework basically has to worry about IRQ
Daniel> Handling, bus management and access to hardware and
Daniel> hotplugging (driver loading,...).
Daniel> + IRQ handling is basically done by L4 for us. The only
Daniel> thing left is handling mapping bus IRQ to a system
Daniel> interrupt. This can be easily done by the bus managers.
Daniel> How to install a interrupt handler: Precondition(s):
Daniel> - All interrupt handler code should be relocable.
Daniel> + The code is mapped into the interrupt thread's
Daniel> address space.
Daniel> + The interrupt thread's address space loader thread copies and
Daniel> relocates the code and adds it to
Daniel> the chain of handlers (linked list) to be executed for the
Daniel> specific IRQ.
the above should be the basic IRQ handling on L4, right?
Daniel> + A bus manager has to offer the following API:
Daniel> + enumerate children: lists all children of this
Daniel> bus. Obviously children can be bus managers themselves.
Daniel> + alloc resource
Daniel> + free resource
Daniel> + map resource: provides access to a resource in the
Daniel> requesting AS
Daniel> + unmap resource
Daniel> + activate resource
Daniel> + desactivate resource
Daniel> + get interrupt
Daniel> resources can be:
Daniel> I/O space. prefetcheable memory
Daniel> address space: address space which is accessible using
Daniel> normal CPU load/store instructions and where the CPU may
Daniel> assume that reading a memory location will not have side
Daniel> non-prefetcheable memory address space: address
Daniel> space which is accessible using normal CPU load/store
Daniel> instructions. Reading a memory location from this space
Daniel> may have side effects.
Daniel> DMAable memory: Physical memory which can be accessed by
Daniel> the device. (More thoughts on DMA at the end of the email)
Daniel> for PCI this API can be extended with:
Daniel> + enable i/o
Daniel> + disable i/o
DAniel> + enable mem
Daniel> + disable mem
Daniel> + enable busmastering
Daniel> + disable busmastering
Daniel> + read configspace + write configspace
Daniel> (other busses probably need their own extensions)
As said above, a base class bus manager could have inherited classes which
implement extended interfaces for a particular type of bus.
Daniel> + The hotplug manager implements the following API:
Daniel> + add device: Announces a new device in the system.
Daniel> + remove device: Device has gone
Daniel> The hotplug manager will load the appropriate device
Daniel> driver into one of the device driver AS's. The hotplug
Daniel> manager create or deletes these AS's as necessary. Whithin
Daniel> each AS a device driver management thread runs which
Daniel> handles the loading and unloading of the drivers.
The above could be an inherited class from base bus manager.
Daniel> Device drivers themselves are modules which are
Daniel> relocateable so they can be loaded anywhere into the
Daniel> AS. This can be done by building them as Position
Daniel> Independent Code or having explicit relocation tables. The
Daniel> latter is probably the best choice, except if we would
Daniel> load a driver multiple times for multiple devices of the
Daniel> same type. They are loaded and started by the management
Daniel> thread. They also get a reference to a port of their
Daniel> parent bus manager so they can ask for resources, etc.
IMHO, device driver code could be builded as shared object and (if vm permit)
mapped in thread which request it (an interrupt handler for example). Like
bus manager, device drivers of the same type could be inherited from
a base common interface and implement only method useful for interaction
with device (read, write, and so on...). The interface between device driver
and other procs could be implemented by a generic thread which manipulate
the well known interface to driver
Daniel> + Bootup:
Daniel> + All drivers are loaded in their own address
Daniel> space for now
as shared object
Daniel> + Drivers which are necessary for system
Daniel> bootup (HD driver, console driver, ...) are loaded by
Daniel> + The hotplug manager and a config file is also
Daniel> loaded by grub. The config file has also a list of device
Daniel> names/identifier strings which tells wich driver can
Daniel> handle which device. This list will be discared after the
Daniel> system is able to load an editable list from the harddisk.
As said above, device driver shouldn't be started as device manipulator
directly but be used from another task as a dynamic shared object. So the
config file tell to root bus manager which how many device driver task should
be started up and which object (loaded previously as shared object by grub) them
instantiate and use. So all device driver task implement same code but use
different object implementation as specified in config file.
This kind of design is well explainated in Service definitions bye smidth's
Obviously the above describe particularly ACE framework but the generic idea
and design could be used in DDE context.
Daniel> + The hotplug manager gets a list of the driver loaded by
Daniel> grub with their thread ID's.
Daniel> + All drivers are loaded as
Daniel> separate process by the resource manager.
Daniel> + The root bus manager starts as first driver.
Daniel> The root driver reads possible BIOS data (or the needed
Daniel> information which driver should be loaded is compiled in).
Daniel> Then it asks the hotplug manager for the driver which should
Daniel> be inserted into the driver tree.
I think hotplug could be skipped out make reading directly config file to
root bus manager and making it starting out threads as needing.
Daniel> + All output to stdout and stderr
Daniel> will be buffered in memory untill the video driver is
Daniel> ready to dump it on the screen. It might be usefull to
Daniel> write it to a serial port.
Daniel> For actually bootstrapping the resource manager (rmgr)
Daniel> with some small additions could be used:
Daniel> + keeps a list of the modules started, their name, their grub
Daniel> commandline and their thread id.
Daniel> + no reallocation needed for modules
couldn't be rmgr the root bus manager?
Daniel> (Why is this done anyway? Is it to keep sigma0 simpler
Daniel> (one-to-one map?))
Daniel> And here now some question or thoughts we haven't solved
Daniel> + In which address space is the resource manager started?
user space I think. And get initial resources by sigma0
Daniel> + We can take control of the interrupt threads by migrating
Daniel> them to our own address space. How does
Daniel> thread migration work? Restrictions?
as said above if rmgr is the "root bus manager" there isn't need of
Daniel> TODO :
Daniel> think about API's for other busses (ISA, Nubus, Zorro,
Daniel> ...) think about API's for message busses such as USB,
Daniel> firewire, scsi, fibrechannel ADB,...
a well designed hierarchy of classes :)
Daniel> and all things we forgot.
Now I'm working on port UVM to L4 and I think this could be finished in next
3 months. Next I'll apply full time in DDE (in coworking with you all :) )
What do you think about this design? Are only few ideas, I've not try to
implement them before.
GPG key: 0xCC0FBF8F
fingerprint => E429 A37C 5259 763C 9DEE FC8B 5D61 C796 CC0F BF8F <= fingerprint