xxxxx@lists.osr.com wrote on 09/06/2004 05:15:18 AM:
Hi,
is you guess i’m new in this driver development topic. As i see its (or
looks like) a difficult job to make a running driver.
Right know i’m on the way developing a nic driver running on the pcimcia
bus. If not wrong doing this using NDIS will simplify (hope so) the job.
Any
suggestions, warnings source etc. would be helpful.
Developing drivers is definitely one of the more difficult levels to
program at, for the simple reason that there are more levels of difficulty
than for a normal user-mode application. Amongst these are:
- Your code will run at driver level, which means that if your code
overwrites some data that it shouldn’t be touching, it’s not necessarily
your application that crashes.
- As if this isn’t enough, windows offerst (for good reasons) less
protection between parts of the kernel, which makes detecting these bugs
harder.
- Debugging drivers is made harder by the fact that the whole system
usually fails to operate correctly after a driver crash, whilst an
application crash is normally not a big deal.
- The behaviour of your driver (even when it doesn’t crash the system) will
have impacts on the whole system. A user application doesn’t have that
“power”.
There are some good tools that can be used to help prevent complete
disaster. Amongst those are:
- Driver verifier (DV for short). Do not do any driver development without
it. It’s a tool that helps identify when/if something illegal is being
done, usually at the source of the illegal operation rather than later on
when it’s no longer traceable to your driver. Typical example would be
writing outside of a buffer. When windows normally (no DV) allocates small
buffers (say 100 bytes), the OS will pick a small piece of memory from a
large chunk (say a 4 or 16KB chunk), and give a pointer to that address.
Immediately after this 100b area will be the next small memory block, most
likely to be given to some other process shortly. DV will modify this
behaviour by allocating a full 4KB block, surrounded by a 4KB guard page on
either side, and fill the remaining part of the 4KB with a pattern that can
be identified later if it’s been overwritten. If you hit any other “either
side” 4KB blocks, it will signal an error, as well as when the block is
freed, the pattern is checked to see that it’s “undisturbed”.
Other things it detects is: Potential deadlock situations, double-free of
memory, immediate detection of pageable access at levels where the OS
requires non-pageable memory, etc, etc.
Start by dv by running “Verifier” (start->run “Verifier”), select
everything except the “Low resource simulation”.
- WinDBG. A remote debugger that allows you set breakpoints (either in
code, or for instance when a address is being written to), single step the
code, view variables etc. It actually works for applications too, but it’s
mostly used by the driver/kernel developers.
Regarding NDIS: Can’t really comment on this one. I’m sure one of the
networking experts will chime in here (I’ve done Linux drivers for network
devices, but not Windows ones).
My special question is, do my miniport driver needs a flow control
mechanism? I mean, how do a say the nic I will transfer YYY (say 100)
bytes.
The card i’ m working on has I/O space with 16 bit Tx/Rx buffers. Does
this
mean the 100 bytes should be sent in 16 bit fragments?
If this is the case how does the card knows the whole data is 100 bytes
long, since it should reassemble the 16 bit data to make a single 100
byte
packet.
The PCMCIA interface is 16-bit wide, so in some form, all the data will be
transmitted as 16-bit units. This doesn’t necessarily mean that your driver
has to go through and send 16 bits at a time from the packet. As to your
device knowing the length of the data, there’s no generic answer to this.
Here’s how it generally works, but it may be different:
- Your driver (or some upper layer driver) puts the data to be transmitted
in a locked down buffer (i.e. a non-pageable buffer).
- You put the address and size of the buffer to the network device.
There’s three basic principles here:
a. (semi-)Circular buffers: A set of packet buffers are predefined.
The driver puts the relevant
information about the packet in the “next available space”, and
sets a flag to indicate to the
network hardware that it’s available to send.
If there’s no available buffer, you’ll have to wait for the device
to finish transmitting, usually
indicated by an interrupt, and then use the newly released buffer.
Some devices will automatically “poll” for the “new data to
transmit” and others require that the
information about “new data to transmit” be written to a register
(usually just one bit to be set
somewhere).
b. Single buffer: There’s only one buffer, and your driver specifies
the packet information directly to a
set of registers in the chip. Once the buffer has been filled in,
you’ll need to wait for the data to
be transmitted before the next packet can be readied.
c. No buffer: The device requires the hardware&softwate to supply the
data as it’s being transmitted.
Basicly just a single register that is written, and a second
register that needs to be polled for
“status” to indicate that the next few bits of data can be put in
the transmit register.
Generally, modern network devices are “DMA” (direct memory access) devices,
so they use the (a) or (b) versions above. PIO (programmed I/O) is probably
extinct by now for network devices (at the very least for 100Mb/s devices).
Exactly how this works on your NIC is obviously something that you can find
in the software developers guide for that NIC. They are not all the same,
but most are pretty similar.
Hope this helps.
–
Mats
I’ m not sure about having the question stated correctly. My good i’m so
confused. Thanks in advance.
Best Regards
Yagmur Konuslu
Questions? First check the Kernel Driver FAQ at http://www.
osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@3dlabs.com
To unsubscribe send a blank email to xxxxx@lists.osr.com
ForwardSourceID:NT00002BFA