- Device Drivers and HAL
- Posted by one-trick-pony on August 16th, 2007
Greetings,
I am interested in understanding some of the terminology and concepts
in regards to device drivers. I have done some basic research and
some of the things are confusing me. For instance, when I think of a
driver, I think of software controlling a hardware. That is, it may
contain C and/or assembly language very particular to a piece of
hardware. In my understanding a driver was a software which has full
ability to access a device, knows about its internal structures,
buses, timings and registers etc.
I was told about an example that exists called toaster that can be
studied to help better understand device drivers and device driver
development process for Windows OS. I have not yet looked into
toaster. I wanted to read up on theory first and thats where I am
really puzzled. What device are we controlling with that toaster
driver? Suppose toaster controls CD-ROM device, I have no idea how
Samsung makes their CD-ROM drive and how Sony makes theirs. To me a
driver is fully aware of the hardware it must be controlling. That
is, a driver is hardware dependent. It seems to me that is not the
case. How can driver have a hypothetical device? My question is
based on the fact, that I am thinking a physical device with chips
with internal registers, timing issues, memory, buses etc.
What made me write this post is right now I am studying HAL layer of
Windows OS. It seems drivers don't access devices directly, they go
through HAL. That is another puzzle. HAL can not possibily concieve
a device that, say, I make. How would HAL know how to begin to
interact with the device? I am sure there are standards that exists
to adhere to making,say, PC device that uses PCI. Suppose my device,
a card that sits in a PCI slot, has 32MB of memory on it, and of
course myraid of chips on it. It is a brand new device that is custom
made and adheres to all the PC and PCI hardware standards. How would
HAL know how to control and utilize this device if a device driver can
not directly access it?
Thanks
- Posted by Don Burn on August 16th, 2007
Comments in-line:
"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message
news:1187270338.166621.102250@r29g2000hsg.googlegr oups.com...
That is the common thought, but there are a lot of drivers that do not talk
to hardware at all. They can either modify actions of other drivers, or be
independant services for the system.
Make that almost entirely C (some experts use C++). Most drivers do not
use assembler, and its use is highly discouraged for portability reasons.
Toaster is a set of drivers. They do not control a real device, but show
how to do many operations within the kernel. In particular, is has a bus
driver that shows how devices are recognized and presented to regular
drivers. Most developers do not need a bus driver, but it is useful if you
hardware presents more than one device in a non-standard way. It has a
function driver, this is the type of driver you imagined above, and
controls a device. It has a filter driver that sits above or below a
function driver, and can do things like monitoring or modifying actions of
the function driver.
As I said toaster if for a hypothetical device, it does not control real
hardware or in the end actually do anything useful. The drivers show you
how to put together one of more drivers for your own purposes.
layer, that abstracts things like device register access. So instead of
using a hardware instruction IN you use READ_REGISTER_XXX where XXX is the
type (size) of the read. The reason not to use IN is that some systems did
not have them. The same happens for memory accesses, but here the wrapper
functions handle flushing and other things that are needed to truly access
the device.
The HAL does not abstract devices, it abstracts the systems access to
devices.
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
- Posted by one-trick-pony on August 16th, 2007
Interesting...
First thing understood is a driver does not necessarily control a
hardware device.
Second, drivers are written in C for portability reasons.
Third, there are 3 types of drivers including bus, function and
filter. Can drivers fall under other categories?
Fourth, toaster is used as a good introduction into communications
with kernel.
If following can be explained more that will help:
How does HAL know about device registers? For instance, it uses, uc =
READ_REGISTER_UCHAR( register ); for reading and
WRITE_REGISTER_UCHAR( register, uc ); for writing. I guess my
question is where is this register? Is it on CPU, some chip on
motherboard, some chip on the device itself, etc?
I may have more questions. Appreciate the help.
Thanks
- Posted by Don Burn on August 16th, 2007
"one-trick-pony" <worldofpain.aamir@gmail.com> wrote in message
news:1187275972.416588.56040@k79g2000hse.googlegro ups.com...
driver). These typically include registers, memory and interrupts. Note:
in the device manager in Windows you can look at the resources a device
has. There are a number of ways that the resources are communicated to
the system, for things like PCI the bus configuration space is read to get
the information. For legacy devices, the user specifies the resources with
help from the driver writer to provide valid sets of resources in the INF
file.
What the HAL is doing, is taking care of all the little details of the
interaction to get out to the device.
--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply
- Posted by one-trick-pony on August 16th, 2007
I think I understand. Driver can access a resource represented by the
device and interact with it. Will continue to study. I can not claim
I understand fully but pieces are falling into the place. Still
interested in learning more so please contribute your
knowledge....Thanks
- Posted by Maxim S. Shatskih on August 16th, 2007
All CD/DVD drives obey (with the tolerance of 95%) to MMC-5/6 spec.
Some (Pioneer and Asus) do obey the Mount Fuji spec, which has IIRC only 1 main
difference with MMC - the use of TEST UNIT READY pinging during CLOSE
TRACK/SESSION is not supported in MtFuji and is supported in MMC.
Some do have some firmware bugs - requiring a larger output buffer for some
commands then prescribed by MMC, for instance - Panasonic with IIRC GET
CONFIGURATION command.
But most of this is related to CD/DVD burning, not to the CD/DVD reading which
is nearly the same for all drives on the market (and, if some drive's firmware
is buggy, then CdRom.sys has a workaround).
CdRom.sys only supports reading and audio control and not burning. Burning is
done by handicrafting the SCSI requests without CdRom.sys (sometimes with a
kernel mode helper, sometimes in user mode alone as Nero does) and then sending
them to the storage LUN stack.
Think of HAL as of platform-dependent part of the kernel.
The NTOSKRNL binary has only 4 flavours - SMP/UP and PAE/noPAE. NTOSKRNL thus
cannot contain any code working with any system-level chipset hardware except
the CPU itself. It cannot contain the code to work with interrupt controllers
or timers.
HAL is mainly the second part of the kernel which provides the following:
a) all work with interrupt controller hardware
b) all work with timer hardware - I think that Windows kernel architecturally
has 2 timers - main and performance - and their implementation is up to HAL.
c) SMP CPU enumeration and startup (HalStartNextProcessor)
d) SMP interprocessor interrupts
e) final reboot/powerdown/shutdown code (HalReturnToFirmware)
f) WRITE_xxx_UCHAR and similar functions.
g) non-standard partition table layout support
In open-source OSes, the analog of HAL is just a build subtree of the kernel
project, chosen at config time before building the kernel. Since Windows ships
ready binaries, they have choses to only have 4 kernel binaries and several
HALs - APIC/noAPIC, ACPI/noACPI and so on.
What is interesting for the drivers is item f) - WRITE_xxx_UCHAR functions.
They do the hardware register access _in a way safe with the
hardware-platform-specific memory barriers_. Yes, in this sense "drivers talk
to the hardware via HAL".
It only knows how to ensure that your driver's device accesses will be executed
properly by the platform with proper memory barriers - i.e. by CPU+bus bridges.
What are these accesses - is not the HAL's job.
It only knows how to execute your driver's register accesses properly. It is
the driver which calls WRITE_xxx_USHORT or so, the HAL is a passive player
here.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
- Posted by Paul Baker [MVP, Windows - SDK] on August 16th, 2007
You mention the TEST UNIT READY command and LUN. Aren't these SCSI concepts?
What happens if it's an IDE drive? Or whatever other types of drive there
are these days that I don't know about 
Paul
"Maxim S. Shatskih" <maxim@storagecraft.com> wrote in message
news:uPJoItC4HHA.3684@TK2MSFTNGP02.phx.gbl...
- Posted by Maxim S. Shatskih on August 16th, 2007
This classification is only about PnP. For instance, filesystem stacks has no
notion of bus/function.
The notion of "filter driver" is yes, universal, and means - the additional
driver which passes all request flow to the real ("functional") driver of FSD
thru itself and possibly makes some alterations to this flow.
The notion of the "bus driver" is PnP-only, and means - the driver which
creates the children (in PnP/Device Manager sense) of its device.
The notion of "functional driver" means - the driver which really contains the
device-specific piece of code which knows how to command the device to do
something.
With PnP, each position in the Device Manager tree is called "devnode". Devnode
is usually an attachment chain of the several device objects, which grows in
the "Z direction", if we are speaking about Device Manager tree to be X Y
directions - X is parent-child relation, Y is sibling-sibling relation.
Devnode is created by creating the bottom-most device object in it, and then
reporting it to PnP (PnP does the rest of the devnode mechanics). This
bottom-most device object is called PDO - Physical Device Object.
The driver which creates PDOs - and thus the child devnodes - is called "bus
driver" or "enumerator" (the old Win9x term).
Why these attachment chains? Let's consider USB. USB PDOs are created by the
bus driver USBHUB.SYS. Their functionality is to a) accept URBs from the top
and execute them over the bus with their target device b) accept some bus
management requests and status/information queries.
Note that the USB PDOs do not usually create URBs themselves. They are passive
executors of the URBs created by some upper code.
Think on USB PDO as of "hub's downstream connector hole device". :-)
So, to control the USB device, another driver is needed, which will form the
proper URBs and send them down to the PDO. This is the device-specific driver,
and is called "functional driver", and its device object - a FDO.
The PnP's architectural choice is to use the device attachment chain (Z-order)
to attach the FDOs to the PDOs.
PnP also support filters, upper and lower.
Upper filters are above the functional driver, and filter the class-specific
requests. For instance, upper filter driver for a scanner - be it USB or some
other scanner - filters the scanner requests, which are not dependent on the
scanner's physical means of attachment - it is the scanner's FD which converts
the class generic scanner requests to the requests particular for the proper
scanner and its ways of connection - USB or so.
Lower filters are below the FDO, and filter the bus-specific traffic - URBs for
USB devices (be it scanners or printers or HID or so), SCSI SRBs for storage
stacks and so on.
One more example: the storage stack. The storage stack in Windows is all-SCSI
in its middle-layers. So, the storage device is called "LUN".
Each LUN is a PnP devnode, with a PDO for it. The PDO is created by the bus
driver called "storage port driver", accepts the SCSI commands (SCSI-standard
CDB + additional info in a Windows structrure called SRB) from the upper layers
and transfers them to the real device.
Disk and CdRom storage LUN types have also the functional drivers in the
kernel - Disk and CdRom.sys (with ClassPnP.sys being a kernel-mode DLL holding
their common paths).
Their FDOs are attached on top of the storage port PDOs, and do the job of
converting the MJ_READ, MJ_WRITE and storage IOCTL IRPs to the SCSI SRBs/CDBs.
Disk and CdRom driver can even be agnostic of the fact how the disk is
connected to the computer - the storage port does this job.
Among the known storage ports: USBSTOR for USB storage (works for devices which
are compliant for USB Storage spec), SBP2PORT for 1394 storage (implements
SBP-2 - the SCSI over 1394 protocol), SCSIPORT for hardware - say, PCI-based -
SCSI controllers and non-standard (S)ATA controllers, and ATAPI - for ATA
controllers compatible with good old 0x1f0/int 0xe standard.
Some storage ports like SCSIPORT allows the controller-hardware-specific
portion to be developed by 3rd party (the controller vendor usually) and
plugged into SCSIPORT, forming a full storage port/bus driver. This portion is
called "miniport driver", it does exactly the job of driving the particular
hardware, while the MS-provided SCSIPORT does the generic tasks of being the
PnP bus driver for LUNs, power management, request queue management, naming and
so on.
Also, sometimes the PnP bus driver is also a PnP functional driver. Look at the
same USBHUB - it is the functional for the hub itself, and creates a PDO for
each downstream port on this hub. Both a functional and a bus driver.
So is SCSIPORT+miniport combo - a functional driver for the controller card and
a bus driver for LUNs attached to the card.
Sometimes, this is more complex, with the functional driver and the bus driver
being 2 separate binaries with proprietary means of connection, sometimes not
published by MS. For instance, OHCI1394.sys is the functional driver for TI's
1394 host controller chip. It connects to 1394BUS.sys via undocumented
interface of function pointer table exchange, and 1394BUS.sys is the bus driver
which creates PDOs for 1394-attached devices.
It does not. The driver passes their addresses to READ_REGISTER_UCHAR and
friends.
The value of "register" argument is passed by the driver, and not chosen by HAL
itself.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
- Posted by Maxim S. Shatskih on August 16th, 2007
All so-called "IDE CD-ROMs" use the SCSI command set.
This feature of IDE - running SCSI commands over IDE/SATA cable - is called
"ATA packet interface" and is defined by the ATA spec, with some aspects being
defined in the SCSI set of specs - MMC and so on.
I think that all ATA/IDE devices, except the usual hard disks, are "ATA packet
interface" devices, i.e. they run SCSI commands over IDE or SATA cable.
So, CD/DVD drive is always SCSI, and the MMC/MtFuji specs are SCSI-based - they
use TEST UNIT READY, START STOP UNIT, CDBs, unit attention condition, mode
pages, sense info data and so on.
USB enclosures and external disk drives (both flash and mechanical) work as
described is USB Storage spec, which is effectively "SCSI over USB" (a subset
of SCSI).
1394 enclosures and external disk drives work as described in SBP-2 spec, which
is "SCSI over 1394".
So, SCSI cabling and controllers are rare these days, but the SCSI notions and
the command set is ubiquitous - all storage devices except usual IDE/SATA hard
disks.
--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com
- Posted by one-trick-pony on August 17th, 2007
Hi,
Thanks for your time and explaining concepts.