Download Computer Networking over the IEEE

Document related concepts

Computer security compromised by hardware failure wikipedia , lookup

Cracking of wireless networks wikipedia , lookup

Motorola 68000 wikipedia , lookup

Transcript
Computer Networking over the IEEE-1394
Serial Bus
Kelvin Lawson
BEng Electronic & Computer Engineering
Supervisor: Dr W. Buchanan
Sponsor: British Telecom Research Labs
April 1999
2
ABSTRACT
This report documents the development of software to implement computer networking over the
IEEE-1394 Serial Bus. Other than IEEE-1394 it encompasses a number of technologies, most
notably the Windows networking model, NDIS, and hardware device drivers. The work was
performed on behalf of British Telecom Research Labs, as part of their ongoing research into new
communications technologies.
The document provides a complete and in depth analysis of this wide-ranging project, and has been
written such that it clearly explains the technologies involved. It investigates the practicalities of
designing device drivers for IEEE-1394, and presents a working design for a Plug and Play device
driver working under Windows. The information herein can also be applied to other device driver
projects, as documentation for developers in this field is sparse. Thus the benefits of the experience
gained on this project are made available to others.
The work carried out has broken new ground in using IEEE-1394 in an innovative fashion, and the
product of the work can be used to network Windows PCs over this new bus technology. This can
be done seamlessly, without the need to change any current network application software. The
project will be completed within budget, and without any support from, or recourse to, the customer,
BT Labs.
3
TABLE OF CONTENTS
1. INTRODUCTION ................................................................................................................................................. 6
1.1 PROJECT OBJECTIVES.............................................................................................................................................. 6
1.2 STRUCTURE OF REPORT........................................................................................................................................... 6
2. FORMAL REQUIREMENTS SPECIFICATION ............................................................................................... 7
2.1 PROJECT OVERVIEW ............................................................................................................................................... 7
2.2 OPERATING SYSTEM ............................................................................................................................................... 7
2.3 HARDWARE ............................................................................................................................................................ 7
2.4 TRANSPORT PROTOCOL........................................................................................................................................... 8
2.5 SOFTWARE FUNCTIONS ........................................................................................................................................... 8
2.5.1 System Administrator Requirements ............................................................................................................... 8
2.5.2 End User Requirements.................................................................................................................................. 8
2.5.3 System Resources........................................................................................................................................... 9
2.6 SPEEDS................................................................................................................................................................... 9
2.7 PROJECT SCHEDULE ................................................................................................................................................ 9
2.8 BUDGET ................................................................................................................................................................. 9
3. IEEE-1394............................................................................................................................................................ 10
3.1 TECHNICAL INFORMATION .................................................................................................................................... 10
3.1.1 Topology...................................................................................................................................................... 10
3.1.2 Asynchronous & Isochronous Transfer......................................................................................................... 11
3.1.3 1394 Packet Formats ................................................................................................................................... 13
3.1.4 Bus Management.......................................................................................................................................... 13
3.1.5 Cable ........................................................................................................................................................... 14
3.1.6 Transmission Rates ...................................................................................................................................... 14
3.2 THE PROSPECT OF NETWORKING ........................................................................................................................... 15
3.3 WHY IS 1394 NEEDED ?........................................................................................................................................ 17
3.4 PROJECT DEVELOPMENT EQUIPMENT..................................................................................................................... 18
4. NDIS – THE WINDOWS NETWORK DRIVER MODEL ............................................................................... 20
4.1 NDIS & THE OSI MODEL ................................................................................................................................. 22
4.2 WINDOWS DRIVER ARCHITECTURES ...................................................................................................................... 25
4.2.1 Universal Driver Architecture...................................................................................................................... 25
4.2.2 NDIS Architecture........................................................................................................................................ 26
4.3 DYNAMIC LIBRARIES ............................................................................................................................................ 27
4.4 NDIS INTERFACES................................................................................................................................................ 28
5. DRIVER DESIGN ............................................................................................................................................... 32
5.1 NETWORKING & IEEE-1394................................................................................................................................. 32
5.1.1 Asynchronous/Isochronous Traffic ............................................................................................................... 32
5.1.2 Broadcast Networks ..................................................................................................................................... 33
5.1.3 Bus Management.......................................................................................................................................... 34
5.2 IEEE-1394 & NDIS............................................................................................................................................. 35
5.2.1 Legacy VxD Driver ...................................................................................................................................... 35
5.2.2 Miniport NIC Driver .................................................................................................................................... 36
5.2.3 Intermediate Driver / TI API ........................................................................................................................ 36
5.2.4 Intermediate Driver / WDM 1394 Bus Class Driver ..................................................................................... 37
5.2.5 Driver-Type Design Choice.......................................................................................................................... 38
5.2.6 Ethernet Emulation ...................................................................................................................................... 38
5.2.7 1394 Transaction Type................................................................................................................................. 41
5.2.8 MAC Addresses............................................................................................................................................ 42
5.2.9 MAC/Node ID Translation ........................................................................................................................... 43
5.2.10 Broadcast and ARP.................................................................................................................................... 47
5.3 HARDWARE CONTROL........................................................................................................................................... 49
5.4 DEVELOPMENT ENVIRONMENT .............................................................................................................................. 51
5.5 DEBUGGING ......................................................................................................................................................... 54
5.5.1 Microsoft WDEB386 .................................................................................................................................... 54
4
5.5.2 SoftICE ........................................................................................................................................................ 56
5.5.3 Which Debugger to Use ............................................................................................................................... 56
5.6 PROJECT PLANNING .............................................................................................................................................. 57
6. FORMAL DESIGN SPECIFICATION .............................................................................................................. 59
6.1 DEVELOPMENT APPROACH .................................................................................................................................... 59
6.2 FILE MAP ............................................................................................................................................................. 60
6.3 MODULE SPECIFICATION ....................................................................................................................................... 61
6.3.1 tilynx.c ......................................................................................................................................................... 62
6.3.2 card.c........................................................................................................................................................... 71
6.3.3 send.c........................................................................................................................................................... 77
6.3.4 oid.c............................................................................................................................................................. 79
6.3.5 interrup.c ..................................................................................................................................................... 82
6.4 TEST PROCESS ...................................................................................................................................................... 86
7. TEST RESULTS.................................................................................................................................................. 87
7.1 MODULE TESTS .................................................................................................................................................... 87
7.2 FUNCTIONAL TESTS .............................................................................................................................................. 90
7.2.1 Resource Allocation/Deallocation................................................................................................................ 90
7.2.2 Hardware Communication ........................................................................................................................... 90
7.3 PLUG AND PLAY ................................................................................................................................................... 90
7.3.1 Integration into Windows Control Panel ...................................................................................................... 90
7.3.2 Self ID Configuration................................................................................................................................... 92
7.3.3 Transmission Between 1394 Nodes............................................................................................................... 92
7.3.4 Communication with Protocol Layer ............................................................................................................ 93
7.3.5 MAC/1394 Translation Table Mechanism .................................................................................................... 93
7.3.6 Broadcast Mechanism.................................................................................................................................. 94
7.4 DRIVER RESOURCE USAGE .................................................................................................................................... 94
7.5 WHQL TEST RESULTS .......................................................................................................................................... 94
8. DISCUSSION AND CONCLUSIONS................................................................................................................. 96
8.1 EVALUATION OF TEST RESULTS ............................................................................................................................. 96
8.1.1 Operating System......................................................................................................................................... 96
8.1.2 Hardware..................................................................................................................................................... 97
8.1.3 Transport Protocol....................................................................................................................................... 97
8.1.4 Software....................................................................................................................................................... 97
8.1.5 System Resources......................................................................................................................................... 97
8.1.6 Speeds.......................................................................................................................................................... 97
8.1.7 Schedule ...................................................................................................................................................... 97
8.1.8 Budget ......................................................................................................................................................... 97
8.2 EVALUATION OF 1394 AND NETWORKING .............................................................................................................. 97
8.3 COMMERCIAL IMPLICATIONS ................................................................................................................................. 99
8.4 THE NEXT STAGE ................................................................................................................................................. 99
8.5 CONCLUSIONS .................................................................................................................................................... 100
APPENDIX A - WINDOWS95 AND NDIS 4.0..................................................................................................... 101
APPENDIX B - MINIPORT INSTALLATION IN WINDOWS95...................................................................... 102
APPENDIX C - MAKEFILE FOR NDIS MINIPORT COMPILATION ........................................................... 104
APPENDIX D – COMPANION CD-ROM ........................................................................................................... 108
5
LIST OF FIGURES
FIGURE 3-1 - 1394 TOPOLOGY EXAMPLE ..................................................................................................................... 11
FIGURE 3-2 - BANDWIDTH ALLOCATION ON THE 1394 BUS .......................................................................................... 12
FIGURE 3-3 - ASYNCHRONOUS WRITE DATA BLOCK PAYLOAD ..................................................................................... 13
FIGURE 3-4 - 1394 CABLE AND CONNECTORS .............................................................................................................. 14
FIGURE 4-1 - TYPICAL OPERATING SYSTEM ................................................................................................................. 21
FIGURE 4-2 - LAYERS IN THE OSI MODEL.................................................................................................................... 22
FIGURE 4-3 - WINDOWS NETWORK ARCHITECTURE ..................................................................................................... 24
FIGURE 4-4 - UNIVERSAL/MINI DRIVER ARCHITECTURE ............................................................................................... 25
FIGURE 4-5 - ARCHITECTURE FOR NDIS 3.1 OR LATER ................................................................................................ 26
FIGURE 4-6 - NDIS WRAPPER .................................................................................................................................... 29
FIGURE 5-1 - 1394 AND THE OSI MODEL .................................................................................................................... 32
FIGURE 5-2 - INTERMEDIATE DRIVER STRUCTURE........................................................................................................ 36
FIGURE 5-3 - DRIVER POSITION WITHIN NDIS ............................................................................................................. 38
FIGURE 5-4 - ETHERNET/1394 SEND PROCESS ............................................................................................................. 40
FIGURE 5-5 - 1394 ENCAPSULATED ETHERNET FRAME................................................................................................. 40
FIGURE 5-6 - 1394 NODE ID FORMAT ......................................................................................................................... 42
FIGURE 5-7 - ASYNCHRONOUS WRITE QUADLET PAYLOAD .......................................................................................... 46
FIGURE 5-8 - PCI CONFIGURATION CONTROL AND STATUS REGISTERS ......................................................................... 49
FIGURE 5-9 - PCILYNX DATA TRANSFER..................................................................................................................... 50
FIGURE 5-10 - NDIS MINIPORT BUILD PROCESS ......................................................................................................... 52
FIGURE 5-11 - NULL-MODEM CABLE .......................................................................................................................... 54
FIGURE 7-1 - WINDOWS DEVICE MANAGER ................................................................................................................. 91
FIGURE 7-2 - NETWORK PROPERTIES APPLET............................................................................................................... 91
LIST OF TABLES
TABLE 3-1 - CABLE TRANSMISSION RATES .................................................................................................................. 14
TABLE 4-1 - NDIS SUPPORT IN WINDOWS ................................................................................................................... 27
TABLE 5-1 - MAXIMUM PAYLOAD SIZES ...................................................................................................................... 41
TABLE 5-2 - CABLE CONNECTORS ............................................................................................................................... 54
TABLE 6-1 - PROJECT FILE-MAP ................................................................................................................................. 60
TABLE 6-2 - MODULE SPECIFICATION FORMAT ............................................................................................................ 61
TABLE 7-1 - TEST SYSTEMS ........................................................................................................................................ 87
TABLE 7-2 - MODULE TEST RESULTS FORMAT ............................................................................................................. 87
TABLE 7-3 - RESOURCE USAGE ................................................................................................................................... 94
TABLE 7-4 - WHQL RESULTS ..................................................................................................................................... 94
TABLE 8-1 - STAGE COMPLETION STATUS ................................................................................................................... 96
ACCOMPANYING MATERIAL
CD-ROM containing the complete project source code and the required hardware specifications.
6
1. INTRODUCTION
This document relates to an investigation into the IEEE-1394 High Performance Serial Bus, more
commonly known as ‘FireWire’. IEEE-1394 is a new bus technology, and current applications have
centred on connecting peripheral devices to PCs. This project aims to bring IEEE-1394 into the
realms of computer networking.
The project has been set by the Local Area Networking team at British Telecommunications
Research Labs (BTL), who have also provided the necessary equipment for the work. This team
carries out evaluations on new networking technologies, with a view to selecting the best
technologies and providing this information to British Telecommunications at large. They also work
with the various communications standards bodies, and present their findings such that improvements
can be made, and eventual standards can be agreed.
Their evaluations generally involve setting up computer networks with these new network media,
and carrying out rigorous tests to establish the capabilities and characteristics of the technology. For
this work to be carried out on IEEE-1394, they require a Windows device driver that can implement
a network over the IEEE-1394 bus. With this in mind, the developer (Kelvin Lawson) has been
solely assigned the task of developing this software, and presenting the final result to BTL. The
software should be developed from the initial concept to the final implementation, using the IEEE1394 hardware provided by BTL. The work encompasses three key areas:
§
§
§
IEEE-1394 bus hardware and protocols
The Windows network driver model (NDIS)
Transport protocols, such as TCP/IP or IPX/SPX
1.1 Project Objectives
On initial consideration of the project, the following objectives were identified:
§
§
§
§
§
Development of a requirements specification
Research into IEEE-1394
Research into NDIS
Consideration of the implementation of IEEE-1394 within Windows and NDIS
Development of a Plug and Play device driver
At a functional level, the final device driver should achieve the objectives set in the requirements
specification.
1.2 Structure of Report
This document is laid out in chronological order, such that the initial requirements specification is
read first, to give the reader an idea of the scope of the project. Following this, two chapters present
the information required to understand the design considerations. These are the constraints and
opportunities of the technology in its proposed application, which must be taken into account in
order to justify the ultimate design approach that was used. Following these chapters, the reader is
taken through the design of the actual project up to the eventual results of the work and some
discussion on the results.
2. FORMAL REQUIREMENTS SPECIFICATION
This section serves as a formal agreement between the developer and the customer, British
Telecommunications Research Labs (BTL). It identifies the functions that must be performed by the
final product, including any hardware and software constraints. Details of the actual method of
implementation are left to the discretion of the developer. This student project is a new development
and does not benefit from any prior work by BTL.
2.1 Project Overview
To develop a Plug and Play device driver that implements Windows networking over the IEEE-1394
Serial Bus. The result should allow a number of PCs to be connected together and share resources in
a similar fashion to the facilities available with existing network media, such as Ethernet. These
facilities include file access to storage systems, such as hard drives, on networked PCs, and the use
of any Windows compatible network-oriented applications, such as e-mail. This should eventually
provide the platform for a full analysis of IEEE-1394, including how well the Serial Bus is suited to
networking PCs.
2.2 Operating System
The target operating system has been chosen to be Microsoft Windows95, due to the large number
of systems in the Research Laboratories which run on this system. However, compatibility with later
versions of Windows is seen as desirable, in order to allow for future upgrades to the computer
installations.
2.3 Hardware
The user computer systems are assumed to be based on the Intel architecture with a minimum
specification being a Pentium processor, and also to contain a local PCI bus. Further constraints are
not necessary except that there is sufficient RAM to run the Windows operating system, and one
spare PCI slot. The minimum requirement for RAM can vary, but as a general indication at least 8
Megabytes is desirable.
Two Texas Instruments PCILynx development cards have been supplied by BTL, which provide a
bridge between the PCI bus and the 1394 Bus. A full description of these cards can be found in the
PCILynx Specification1, however some key characteristics are identified as:
•
•
•
•
•
•
•
Compliant with IEEE 1394-1995
Compliant with PCI Specification revision 2.1
Supports IEEE 1394 transfer rates of 100 and 200 Mbps
Provides 5 scatter-gather DMA channels for the following 1394 operations:
Asynchronous Transmit & Receive
Isochronous Transmit & Receive
Supports Plug and Play Specification
8
2.4 Transport Protocol
No assumptions have been made about the required transport protocol to be implemented over the
1394 Bus, except that it is available within the Windows Operating System. At the time of writing,
available protocols include AppleTalk®, NetBEUI, NWLink, IPX/SPX and TCP/IP. However,
current networks within BTL are based on TCP/IP and to ease transition to the new media from
older technologies, it is seen as desirable but not required, that the same transport protocol be
supported.
Support for more than one transport protocol is also identified as useful for BTL, such that a more
full analysis of 1394 as a networking media can be performed.
2.5 Software Functions
No software requirements have been specified by BTL, other than that the product should fit into
Windows as with previously available network media, usually Ethernet. The result should be
seamless and invisible to the user, such that all functions normally associated with networking, are
available. There follows a summary of the relevant interactions which might be expected by both
administrators and the end user, and which should be no different whether using 1394 or Ethernet.
2.5.1 System Administrator Requirements
The duties of the system or network administrator, include setting up new PCs and connecting them
to the Lab network. The installation of networking devices requires a device driver which is relevant
to the hardware. Once the hardware is installed in a spare PCI slot, booting Windows will result in an
installation dialogue, which asks the administrator for a disk containing the correct device driver. No
other tasks must be performed pertaining to the hardware due to the fact that the device driver and
Texas Instruments device are to be Plug and Play compliant. Installation can then ensue by inserting
a disk containing the driver and any required installation details. Plug and Play will negate the need
for choosing IRQs and memory ranges, all of which is configured completely transparently.
Once the device driver has been installed, it should be present in the Windows Control Panel, where
it can be identified under the “Network” menu. The next stages involve the setting up of software
such as required protocols. This can be done by choosing Network properties in the Control Panel,
or from the Network Neighborhood menu. From here the administrator should be able to set the
transport protocol in use, currently TCP/IP on the Lab network. It must be possible to “bind” the
1394 device to the required protocol, where a binding describes a virtual connection between the
device and the protocol.
Further configuration is not related to the device driver, and will be the same regardless of the
underlying network card. This includes setting up the IP protocol with information relevant to BTL,
such as a unique IP address assigned by the network administration, and eventually setting up the
Client type in use. Thus the entire installation system should fit into BTL’s documented procedures.
2.5.2 End User Requirements
As with the network administrator, the requirement is that the end user experiences no change in the
way they interact with the network, in the transition from old technologies to 1394. Typical
interactions with the network include:
•
•
Drive-mapping – Server hard disks are mapped to local disk names. Thus users can maintain
private disk space on the server and are able to work from any PC on the network. Also project
resources can be pooled on the server.
E-Mail – BTL provides employees with e-mail, and this must be maintained.
9
•
•
•
•
Intranet/Internet – Each unit and team within BTL maintain web pages on the Intranet and also
access to the global Internet is provided through the network.
Printers – Printers connected to machines on the network can be pooled, until 1394-capable
printers become available.
Remote login to distant machines on the network.
Distributed processing.
These applications are merely provided as an example of important requirements to the end user, and
are not a specification of the entire scope of functionality to be provided by the end product. By
conforming to the Windows networking standard, all of these applications should be inherently
possible.
Note that if it is required that a 1394 Bus be internetworked with some other networking media, a
Bus Bridge will be required. Provision of such bridges is beyond the scope of this project.
2.5.3 System Resources
It is identified as important that the product does not consume a large amount of resources on the
host computers. It is noted that current Ethernet networked PCs do not experience degradation in
performance when connected to the network, or when the network device driver is loaded. Thus the
product should consume as little memory, processor time, or other resource as possible whilst not
degrading the performance of the driver. Actual projected memory and other consumption is,
however, outwith the confines of this section.
2.6 Speeds
The development cards provided by BTL support physical transfer rates up to 200Mbps. To this end,
it is a requirement that the product supports this transfer rate, however 400Mbps cards are available
now, and higher rates are expected in the future. Thus it is seen as desirable that the product should
be easily upgraded to support these prospective rates.
2.7 Project Schedule
The development of a network device driver has never previously been undertaken within the team at
BTL, or by the developer, thus a time-scale for completion was not specified. BTL have agreed that
the work involved may take the date past April 1999.
2.8 Budget
It is understood that, within reason, funding is available from BTL, however it is hoped that this will
not be necessary. BTL have loaned two Texas Instruments 1394 devices, and one IBM PC system.
References
1
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI
10
3. IEEE-1394
The IEEE-1394 High Performance Serial Bus, hereafter referred to as 1394, is an
emerging technology that aims to provide an advanced bus for connecting a wide range
of electronic devices. Its flexibility should ensure that it is adopted across many
applications in both the home and the office, and makes the prospect of this project
possible. This chapter introduces the technology, and goes on to discuss the current
and future possibilities for its usage.
3.1 Technical Information
1394 was first officially defined as a standard in 1995, which resulted in the IEEE
1394-1995 specification1. This provided for data rates of approximately 100, 200 and
400 megabits per second (Mbps), known as S100, S200 and S400 respectively. Future
standards promise higher data rates, and ultimately it is envisaged that rates of 3.2
gigabits per second will be achieved when optical fibre is introduced into the system.
1394 offers an attractive alternative to technologies such as SCSI and it is hoped that it
can eventually provide a universal connection to replace many of the older connectors
normally found at the back of a standard PC. This should subsequently reduce the
costs of production of computer interfaces and peripheral connectors, as well as
simplifying the requirements placed on users when setting up their devices. This is
made possible by the following features of the 1394 bus:
•
•
•
•
•
•
Hot Pluggable – Devices can be added or removed while the bus is still active.
Easy to use – There are no terminators, device addressing or elaborate
configuration often associated with technologies like SCSI.
Flexible topology – Devices can be connected together in many configurations,
thus the user need not consider logical locations on the network.
Fast – Suitable for high bandwidth applications.
Rate mixing – A single cable medium can carry a mix of different speed capabilities
at the same time
Inexpensive – Targeted at consumer devices.
3.1.1 Topology
There are two bus categories defined as cable and backplane. Cable refers to a bus
connecting external devices via a cable, whereas backplane refers to an internal bus.
The cable environment is described by Jennings (1997)2 as “a non-cyclic network with
finite branches consisting of bus bridges and nodes (cable devices)”.
A non-cyclic network is one in which there are no loops. The resultant topology is a
tree-formation, with devices daisy-chained and branched (where more than one device
branch is connected to a device). An example is shown in Figure 3-1, where for
example, the 1394 Splitter has three branches and the telephone is daisy-chained from
the Digital Camera.
11
Figure 3-1 - 1394 Topology Example
The finite branches restriction imposes a limit of 16 cable hops between nodes.
Therefore branching should be used to take advantage of the maximum number of
nodes on a bus. 6-bit node addressing allows up to 63 nodes on each bus, while 10-bit
bus addressing allows up to 1023 buses, interconnected using 1394 bridges. Devices
on the bus are identified by node IDs. Configuration of the node IDs is performed by
the self ID and tree ID processes after every bus reset. This happens every time a
device is added to or removed from the bus, and is invisible to the user.
A final restriction is that, using standard cables, the length between nodes is limited to
4.5 metres. This can be increased by adding repeaters between nodes, but lengths are
expected to improve as work on the standard ensues. Although a PC is shown in
Figure 3-1, a principal advantage of 1394 is that, unlike USB, no PC is actually
required to form a bus, and devices can talk to each other without intervention from a
computer.
The backplane bus is well described by Hoffman (1995)3:
“In addition to a cable specification, there is a backplane specification that extends
the serial bus internally to a device. The internal 1394 device may be used alone, or
incorporated into another backplane bus. For example, two pins are reserved for a
serial bus by various ANSI and IEEE bus standards. Implementation of the
backplane specification lags the development of the cable environment, but one
could image internal 1394 hard disks in one computer being directly accessed by
another 1394 connected computer.”
The backplane bus is not to be utilised within this project, and as such there shall be no
further comment throughout this document.
3.1.2 Asynchronous & Isochronous Transfer
One of the key capabilities of 1394 is isochronous data transfer. Both asynchronous
and isochronous are supported, and are useful for different applications. Mackenzie
(1998)4 describes isochronous transmission as a means to transmit “data like real-time
speech and video, both of which must be delivered uninterrupted, and at the rate
expected”. By contrast, asynchronous transmission is used to transfer data that is not
tied to a specific transfer time. In the context of 1394, asynchronous is the
12
conventional transfer method of sending data to an explicit address, and receiving
confirmation when it is received. Isochronous, however, is an unacknowledged
guaranteed-bandwidth transmission method, useful for just-in-time delivery of
multimedia-type data.
An isochronous ‘talker’, requests an amount of bandwidth and a channel number. Once
the bandwidth has been allocated, it can transmit data preceded by a channel ID. The
isochronous ‘listeners’ can then listen for the specified channel ID and accept the data
following. If the data is not intended for a node, it will not be set to listen on the
specific channel ID. Up to 64 isochronous channels are available, and these must be
allocated, along with their respective bandwidths, by an isochronous resource manager
on the bus.
Figure 3-2 - Bandwidth Allocation on the 1394 Bus
Figure 3-2, as designed by Hoffman3, shows an example situation where two
isochronous channels are allocated. These have a guaranteed bandwidth, and any
remaining bandwidth is used by pending asynchronous transfers. Thus isochronous
traffic takes some priority over asynchronous traffic.
By comparison, asynchronous transfers are sent to explicit addresses on the 1394 bus.
When data is to be sent, it is preceded by a destination address, which each node
checks to identify packets for itself. If a node finds a packet addressed to itself, it
copies it into its receive buffer. Each node is identified by a 16-bit ID, containing the
10-bit bus ID and 6-bit node or physical ID. The actual packet addressing however, is
64 bits wide, providing a further 48 bits for addressing a specific offset within a node’s
memory. This addressing conforms to the Control and Status Register (CSR) bus
architecture standard5. As stated by Jennings (1997)2, “Conformance to ISO/IEC
13213:1994 minimizes the amount of circuitry required by 1394 ICs to interconnect
with standard parallel buses”.
The 48 bit offset allows for the addressing of 256 terabytes of memory and registers on
each node. If the CSR specification is unavailable, some information is contained in the
1394-1995 specification6.
13
3.1.3 1394 Packet Formats
There are a number of different packet formats specified in 1394-1995, however only
the asynchronous block write will be presented here, as it is the main transaction type
used within this project.
Figure 3-3 - Asynchronous Write Data Block Payload
The asynchronous block write is described in the 1394-1995 specification7 as a packet
type that “requests a data block be written to the specified destination address”. It is
the packet type used on asynchronous transmits, for a variable length of data.
The “destination_ID” field should contain the 16-bit destination node ID, while the
“destination_offset” field contains the remaining 48 bits required for CSR-addressing.
The data is sent in the data field, which can be any quadlet-aligned length up to a
maximum given by the transmission speed. These maximums are shown in Table 5-1.
At 200Mbps, for example, the data field may hold anything from 0 to 1024 bytes, in
stages of 4 bytes. The header information is followed by a CRC (cyclic redundancy
check) for error-checking, as is the block of data.
For detailed information on the other fields shown, as well as the other packet types
available, consult Clause 6.2 of the 1394-1995 specification8.
3.1.4 Bus Management
Two bus management entities are available in the cable environment; the isochronous
resource manager and the bus manager. They provide services such as maintaining
topology maps, or acting as a central resource from which bandwidth and channel
allocations can be made. Further information on bus management can be found in the
1394-1995 specification9.
14
3.1.5 Cable
Figure 3-4 shows that the 1394 cable consists of three individually shielded cable pairs.
There are two power lines and two (screened) twisted pairs for data and strobe
transmission.
Figure 3-4 - 1394 Cable and Connectors
Lewis (1999)10 provides a very good description of the cable transmission methods, as
well as a good overview of 1394-1995 in general.
3.1.6 Transmission Rates
As already discussed, the cable rate definitions for 1394-1995 are termed S100, S200
and S400. These do not, however, describe the exact data rates for transmission and
these can be found in Table 3-1. As discussed by Lewis (1999)10, “The high data rates
are achieved by using differential non return to zero, or nrz, signalling on each shielded
twisted pair”.
1394 Definition
Actual Data Rate (megabits/sec)
S100 (Cable base rate) 98.304
S200
196.608
S400
393.216
Table 3-1 - Cable Transmission Rates
The information in this section serves as a brief introduction to the technology,
however if more detailed information is required, the 1394-1995 specification1 should
be consulted.
15
3.2 The Prospect of Networking
A Texas Instruments paper11, states the following regarding the reasons for the
development of 1394:
“The need for 1394 and other next-generation network topologies and protocols is
driven by the rapidly growing need for mass information transfer. Typical LANs and
WANs simply cannot provide cost-effective connection capabilities nor do they
easily support guaranteed bandwidth for “mission critical” applications. Additionally,
parallel high-speed communications such as SCSI are not suited to long distances
and do not support live connect/disconnect, making reconfiguration timeconsuming. Other factors driving next generation protocols such as 1394 include the
need for reliability, durability and universal interconnection.”
Although not stated in the citation, usage of 1394 has been primarily in the area of
‘interoperability’, the connectivity of peripherals. It may eventually displace
technologies such as Centronix, RS232 and SCSI, replacing their connectors with only
one type, the 1394 connector. However, the citation alludes to the possibility of it
being used in LAN and WAN situations, applications which have been largely
unexplored. The usage of 1394 in a LAN-type scenario is the subject of this project,
and it would be useful to proffer a clear and exact definition of a LAN or computer
network here. No clear definition was found, however, which could distinguish such
network technologies from those found in peripheral buses, but this discussion
proposes some possibilities.
Consideration of this question initially resulted in the decision that many computer
networking technologies could be used in an interoperability scenario, and reciprocally,
peripheral buses could conceivably be used as computer networks. Thus, the
distinction between a computer network and a peripheral bus, is less to do with the
technology itself, but only the application that it becomes used for. Examples might be
the prospect of using Ethernet to connect peripherals, and using SCSI to network
computers. Further consideration of these examples, however, presented some
speculation on the distinction, which is based on certain characteristics of the
technologies.
The medium access mechanism may be unsuitable for fair access in a peripheral bus.
For example Ethernet, through CSMA/CD, provides a fair access system for all nodes.
Equally token ring methods provide a fair system for accessing the medium. A
peripheral bus might have a master-slave mechanism, where one PC acts as the master
with total responsibility for control of the bus, and would therefore not be suitable for
networking PCs with equal priority. Secondly a peripheral bus may not have a
transmission protocol which is tailored to suit the medium. As a result, long distances
may not be possible between nodes.
By contrast, networking technologies could still be suitable for connecting peripherals.
In fact, this is already the case with networked printers, usually using Ethernet. Also
file servers are in some respects networked peripherals, although an interface bus is
used to reach the hard drives. A possible drawback, however, is that traditional
network media might be too slow for communication with some peripherals.
16
Given these points, the previous distinction between a computer network and a
peripheral bus should be revamped. Although the distinction generally depends on the
application, rather than the technology, certain characteristics of the technology will
shape what it eventually becomes used for. The above discussion may appear to
present the view that networks can be used for peripheral buses, and not the other way
round, but this is not necessarily always the case. However some characteristics of
peripheral buses are particularly detrimental to computer networking, such as short
transmission distances and master/slave bus control.
Therefore, in considering the use of 1394 as a computer networking medium, we must
consider its characteristics, and their suitability for the proposed application:
•
•
•
•
•
•
Fair arbitration – each node has equal access to the bus.
Bus management – a central bus controller is optional.
Explicit addressing – packets can be addressed to specific nodes.
Lengths up to 4.5m
High data rates
Bridging to form internetworks
Given the above points, it should be possible to see that 1394 offers the services
normally warranted of a computer network. Where SCSI, for instance, may be most
suitable for interoperability only, 1394 is a truly versatile medium, and it should be
possible to use it in both applications to good effect. In fact Lewis (1999) 10 describes
1394-1995 as “a cross between a network and a bus extension system”.
17
3.3 Why Is 1394 Needed ?
Although Section 3.2 proposed that it is technically possible to use 1394 to network
computers, it did not explain why the end user should want to choose it over legacy
network media. A primary driving force that should ensure the acceptance of 1394
computer networks in the marketplace is the increase in bandwidth it can offer over
currently available technologies. Where networks commonly employ Ethernet at data
rates of 10 or 100 Mbps, 1394 can offer rates of 400Mbps today and up to 3.2Gbps in
the future. Demand for high bandwidths is ever increasing in the home and office, with
the advent of applications such as video-conferencing, and companies can no longer
rely on their old Ethernet networks to provide the required bandwidth.
1394, however, offers more advantages than bandwidth, and these were identified as:
•
•
•
•
Manageability – Networks are easy to set up with little thought for the topology.
1394 offers plug and play, and automatic reconfiguration of device addressing,
invisibly to the user or network administrator. This also eases the path of upgrading
from older networks to 1394.
Inexpensive – 1394 chips are priced for the consumer market, and should
eventually be integrated on PC motherboards. Therefore companies need not
purchase adapter cards in order to be network-ready.
Universal connector – Can use the same port for peripherals and the network, also
allowing easy sharing of peripherals over a network.
Backwards compatibility – 1394 networking can be integrated into an operating
system, while allowing current network applications to work as before.
Simplicity may well be key to the adoption of 1394 in the home. While companies can
employ network administrators to take care of complex network setup, the average
home user may be put off by complicated hardware issues. With the same connector
for their printers, cameras, stereos and networks, they can feel at home setting up a
simple computer network, with no regard for the topology. Simplicity and price are not
offset by poor performance. 1394 networks will provide an advanced network that can
handle the coming increase in high-bandwidth applications.
It is with this in mind that this project was identified, the ultimate goal of which is to
implement such computer networking using 1394. The developer is responsible for
taking this from the initial concept into a working realisation. The result of the work is
important to British Telecom Research Labs, in order that they can be at the forefront
of emerging technologies, both for their own benefit and for the benefit of their many
customers.
18
3.4 Project Development Equipment
Two adapter cards were provided by British Telecom Research Labs (BTL) for use
with the project. These were Texas Instruments TSBKPCI Development Cards, with a
physical layer (PHY) capable of 200Mbps transmission. The heart of these cards is a
PCILynx ASIC, which provides the capability to transfer data between PCI and 1394
buses. A very complete specification is available12 and should be consulted for detailed
information on using the PCILynx, however a list of capabilities is provided herein, to
aid a quick understanding of the hardware.
Features of the BTL-supplied cards include:
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Compliant with 1394-1995 (and not later draft specifications such as p1394a)
Compliant with PCI specification revision 2.113
Generates 32-bit CRC for transmission of 1394 packets
Performs 32-bit CRC checking on reception of 1394 packets
Supports IEEE transfer rates of 100 and 200Mbps
Provides 3 size-programmable FIFOs (Async & Iso Transmit & General Receive)
Programmable 5 channel address comparator logic for receiving incoming 1394
packets and assigning them to a DMA channel
Supports DMA transfers between 1394 and local bus RAM
Provides PCI busmaster function for supporting DMA operations
Provides PCI slave function for read-write access to internal registers
Implements a 32-bit PCI address-data path
Provides PCI address-data parity checking
Provides software control of interrupt events
Supports Plug and Play specification14
References
1
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE
Jennings R. (1997), Fire on the Wire: The IEEE 1394 High Performance Serial Bus,
Adaptec Inc.
3
Hoffman G. and Moore D. (1995), IEEE 1394: A Ubiquitous Bus, presented at
Compcon’95 in San Francisco, 5 Mar 1995
4
Mackenzie L. (1998), Communications and Networks. McGraw-Hill, p140
5
ISO/IEC 13213:1994, ANSI/IEEE Std 1212, 1994 Edition, Control and Status
Register (CSR) Architecture for Microcomputer Buses, ISO/IEC
6
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause
3.3
7
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause
6.2.2.3.1
8
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause
6.2
9
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause
3.8
10
Lewis G. (1999), FireWire – A Bus for all Systems ?, Electronics World (Jan 99)
11
Texas Instruments (1998), 1394 Technical Overview, TI
2
19
12
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI
PCISIG (1995), PCI Local Bus Specification Revision 2.1, PCI Special Interest
Group
14
Microsoft (1999), Plug and Play Design Specification for IEEE 1394, Microsoft
Corporation
13
20
4. NDIS – THE WINDOWS NETWORK DRIVER MODEL
This chapter should serve as an aid to understanding the Windows network driver
environment. An understanding of this environment is vital to comprehending the
remainder of this document. Most important is the NDIS Miniport concept, which
became the basis for the project, and is therefore the main feature of this chapter. The
primary sources of information on developing such software, whilst being useful as a
reference or specification, tend not to provide an easy introduction to the subject. To
fully grasp the topic, experience in the development of network drivers is most useful,
and is the only way to learn the various undocumented nuances that come to light in
the process of development. With this in mind, the following chapter has been written
to provide the reader with an easy footing into the subject, given the experience gained
in the development of this project.
A device driver is a piece of software responsible for controlling a hardware device. It
knows the characteristics of the hardware it supports, and provides an interface
between the hardware, and the operating system or applications, which wish to
communicate with the device. Any physically unique device also requires a unique
device driver, in order to function within an operating system.
Due to the massive range of available devices for any one purpose, it is desirable that
the drivers provide a common interface to the software accessing it. If it were not for a
common interface, applications would need to be hardware-specific. For example,
there are many different network cards on the market at any time, and even more
which are no longer in production. Each of the device drivers for these cards needs to
be accessed in a specific fashion, which might be entirely different when compared with
another manufacturer’s driver and card. For an application, such as a file sharing
system, to send and receive network data using the many different hardware
configurations, it would need to know the characteristics of all of these device driver
interfaces. That means what functions need to be called upon and how. This of course
presents an unreasonable task to the software developer, and would result in unwieldy
software. In addition to this, and perhaps more importantly, any new hardware which
comes on the market would not be supported by the slightly older application.
Thankfully, in operating systems such as Windows, a common interface does exist,
which makes the job of developing applications and supporting hardware far easier.
Thus the hardware and device driver can be changed, and applications will still work.
Figure 4-1 represents a typical operating system, and how it interfaces with the
hardware it is running on. Only three device drivers have been included for simplicity,
however in practice there will tend to be many more. For example, the hardware
devices might be a graphics card, a sound card and a network card. Each of these
device types has a well-defined interface, particularly between the operating system
and the device driver. As long as the device driver conforms to the rules associated
with its device type in Windows for example, the operating system and any relevant
applications will be able to access it.
21
Figure 4-1 - Typical Operating System
This works by writing device drivers which export a particular set of functions, rather
like a dynamic library, and applications or the operating system can call on these
functions when they wish to program the hardware device underneath. Of course the
code within each device driver may vary widely, depending on the hardware it is
controlling, but the functions it exports on its upper-edge (towards the operating
system) must always conform to the rules governing the driver environment.
These interfaces may be common for the same class of device, such as all sound cards,
but may be entirely different when compared to other classes of device, and a
particularly unique system is NDIS. This is described by Dhawan1:
“The NDIS (Network Driver Interface Specification) was developed by 3COM and
Microsoft. This interface specification defines an interface between the protocol
stacks and network adapter card drivers. The network hardware and its associated
NDIS driver are independent of the protocol stack and can communicate with each
other and transmit and receive packets if the NDIS specification is used.”
NDIS is the specification used when developing device drivers for network cards in all
varieties of Windows. It standardises access to network cards, so that the same
software may be used to access any brand of network device. It is the aim of this
project to integrate 1394 into this environment, particularly with Texas Instruments
1394 cards. There are different versions of NDIS in use, depending on the particular
release of Windows. This chapter introduces NDIS, particularly NDIS v4.0, which is
primarily used in Windows98 and Windows NT v4.0, however Windows95 can be
adapted to also implement this version. For a more complete reference on this
specification, the NT v4.0 DDK2 should be consulted, which contains the actual
specification for NDIS v4.0.
22
4.1 NDIS & THE OSI MODEL
The Windows98 Resource Kit3 describes this relationship as:
“The modular networking architecture of Windows 98 is based on two industry
standard models for a layered networking architecture, namely the International
Standards Organization (ISO) model for computer networking, called the Open
Systems Interconnection (OSI) Reference Model, and the Institute of Electrical and
Electronics Engineers (IEEE) 802 model. Windows NT and Windows for
Workgroups are also designed according to these standard models. The ISO OSI
and IEEE 802 models define a modular approach to networking, with each layer
responsible for some discrete aspect of the networking process. They are only
models; they do not correspond exactly to any existing network. However, they can
help you understand how networks function in general.”
Although not specified in this citation, the same also applies to Windows95 implicitly,
given that this describes Windows for Workgroups and Windows98.
The OSI model describes the flow of communication between well-defined layers in a
network configuration. These layers are shown in Figure 4-2. Data to be transmitted by
an application travels from the Application Layer, down through the other layers to the
lowest layer, the Physical Layer, and across the network media, to be transported back
up the layers at the destination node. Each layer performs its own functionality, and is
only able to communicate with the layer immediately above and below itself, with no
knowledge of the other layers. In this way each layer can be implemented as a single
component, which does not rely on the conformance of distant layers. This concept has
already been introduced above, with regard to NDIS, where applications are able to
function properly with no regard to the intricacies of the network card in use. This is
because the device driver sits at the Data Link layer of the OSI model, and only talks
to the Network layer (the protocol) and the Physical layer (the 1394 network card in
this instance). Thus the Application layer is far removed from any of these layers, and
must only be able to communicate with the Presentation layer.
Figure 4-2 - Layers in the OSI Model
23
To take this notion further, each layer of the OSI model assumes it is communicating
directly with the same layer at the node with which it is communicating. Thus as far as
any layer is concerned, the data being transferred has not travelled down through the
other layers and eventually across the physical medium, but has travelled straight
across to its respective layer at the distant node.
NDIS device drivers relate to the OSI model at the Data Link layer, and this layer is
described by Dhawan4:
“The purpose of the Data Link layer is to provide the functional and procedural
means to transfer data between network entities and to detect, and possibly correct,
errors which may occur in the Physical layer. Data Link layer protocols and services
are very sensitive to the physical layer technology. While in the upper layers there is
one protocol specified per layer, in the lower layers this is not the case. In order to
ensure efficient and effective use of the variety of cabling technologies, protocols
designed to their specific characteristics are required.”
Within the context of this project, the device driver developer is not only concerned
with the characteristics of the 1394 protocol to be used for physical transfer, but also
has to consider the Texas Instruments hardware, and how it fits into the local computer
hardware. This means knowledge of the PCI internal bus system must be gained. Most
importantly, the developer must know exactly how to program the 1394 card itself for
data transfer, and provide functionality to convert data (formatted as a frame) into a
raw physical bit-stream for the card and 1394 bus, and similarly convert back to frames
at the receiver.
The IEEE802 project committee further sub-divides the Data Link layer into the LLC
and MAC layers, and is concerned only with the bottom two layers of the OSI model.
The standards within IEEE802 refer specifically to Local Area Networks (LANs) and
Metropolitan Area Networks (MANs). These two layers are described in the NT4
DDK5:
“The LLC sublayer provides error-free transfer of data frames from one node to
another. This sublayer is responsible for the establishing and terminating logical
links, controlling frame flow, sequencing frames, acknowledging frames, and
retransmitting unacknowledged frames. The LLC sublayer uses frame
acknowledgement and retransmission to provide virtually error-free transmission
over the link to the layers above. The MAC sublayer manages access to the network
media, checks frame errors, and address recognition of received frames.”
Within Windows, the LLC (Logical Link Control) functions are provided by the
transport driver, whereas the MAC functionality is assigned to the network interface
card, and thus its (NDIS) device driver. The actual Windows network architecture is
shown in Figure 4-3, where the Network Adapter, in this instance, can be thought of as
a Texas Instruments 1394 card.
24
Figure 4-3 - Windows Network Architecture
These layers roughly correspond to the following layers of the OSI model:
• The Redirectors, the IFS (Installable File System) Manager and the Network
Providers, provide the Application, Presentation and Session layer functionality.
• The Transport Protocols, such as TCP/IP or IPX/SPX, correspond to the
Transport and Network layers.
• NDIS and the network card drivers, reflect the Data Link layer. The network card
driver sits specifically at the MAC layer, and receives information from the
Transport layer, which is fully packaged in a framed format, ready for transmission
on the Physical layer.
Detailed description of the upper three layers of the OSI model is deemed not relevant
to this document, due to the fact that the project is related to the development of a
component at the Data Link layer. If necessary, more information can be found in the
OSI Model documentation6, and is also well described by Halsall7.
25
4.2 Windows Driver Architectures
The relationship between NDIS and the OSI model has been introduced, which is
interesting from a learning perspective, however it does not fully describe the actual
implementation of the driver structure in Windows. These device drivers are also
layered, most noticeably in the Universal driver/Mini driver architecture. This section
introduces this general architecture, and goes on to present the architecture used
within NDIS.
4.2.1 Universal Driver Architecture
The structure of device drivers has changed since Windows 3.1, where the drivers
were complex to develop, and were required to contain many services, which in reality
were common across many such drivers. The introduction of the Universal/Mini driver
architecture in Windows95, and further in Windows98, has since, simplified driver
development. This concept basically defers the common processing tasks to the
operating system, leaving the driver to take care of only device-specific code. See
Figure 4-4 for a representation.
Figure 4-4 - Universal/Mini Driver Architecture
The Universal driver contains most of the code necessary for a particular class of
device, such as a printer, to communicate with the operating system. The Mini-driver
contains only the device-specific code, which would otherwise be unknown to the
Universal driver. Note from Figure 4-4, that a Mini-Driver is not always necessary, if
the device is simple enough and abides by a common standard. This is illustrated by the
Unimodem driver, which is a Universal driver for modems, and can directly work with
any modem which supports the standard AT commands8.
The only Mini-drivers that were implemented in Windows95, were the Small Computer
System Interface (SCSI) and networking drivers. With the advent of Windows98, this
architecture has been extended to include many of the newer technologies, such as
USB, the 1394 bus, digital audio, DVD players, still imaging, and video capture.
Unfortunately this Windows98 1394 support does not make provisions for its use
within NDIS, it can only be used by higher level applications to control devices on the
bus. In order to use 1394 within NDIS and allow networking protocols to travel over
the bus, a new device driver had to be developed by this project, as it has to work at a
low-level that is abstracted by the Windows98 support. This is unfortunate, and is
because NDIS is far removed from the rest of the operating system, and drivers are not
allowed to coexist to in both environments. NDIS is effectively an autonomous entity
with no direct operating system calls, the reasons for which are outlined in Section 4.4.
26
For information on driver architectures which predate the Universal driver, the
Windows95 DDK9 should be consulted.
4.2.2 NDIS Architecture
Like the Mini-driver concept, NDIS versions later than 3.1 implement an architecture
that separates device-specific functionality, from the rest of the network system. These
device drivers are called Miniports, and they are supported by the NDIS subsystem,
known as the “wrapper”. This structure is represented in a simple form in Figure 4-5,
where the wrapper is shown as ‘NDIS’ and ‘Ndis.vxd’. This provides a neat interface
between the device drivers, and the protocol drivers. Thus the protocol drivers, such as
TCP/IP can use a well-defined function set in order to carry out functions such as
sending a packet over the network media. Thanks to this interface, the protocol drivers
are unaware of the intricacies of the network interface card (NIC) driver, and can
function normally regardless of which device driver is lying beneath the interface.
Figure 4-5 - Architecture for NDIS 3.1 or later
Note that there are two device driver possibilities shown in Figure 4-5;
•
•
Miniport – Simple, small device-specific driver, where common functionality is
provided by the wrapper
VxD Driver – Does not benefit from the extra services provided by the wrapper.
These drivers are larger and more complex as the extra code must be provided
within the device driver. More commonly referred to as a Legacy Full driver.
NDIS VxD drivers are described by the NT 4.0 DDK10:
“Legacy full NIC drivers required driver developers to write a large amount of code
to deal with issues that are common across all NDIS drivers. About fifty percent of
the code written for a full NIC driver is common to all NDIS drivers, while the other
half is specific to the hardware. Writing a full NIC driver places the full burden of
coding multiprocessor support and other more difficult operating system
programming issues on the NIC driver developer.”
A VxD is a Windows95/98 Virtual Device Driver, where ‘x’ represents the device
being controlled. For example a VDD is a Virtual Display Adapter. VxDs are more
complex to develop than Miniports, and usually require some coding in assembly
27
language. They are OS-dependent, hence they are only supported by Windows 95 and
98, but not in Windows NT. The VxD driver is a massive topic, and if required, a
complete description can be found in the Windows95 DDK9.
Legacy NDIS drivers are no longer supported by Microsoft, and became defunct after
NDIS 3.1. Coupled with this, the entire VxD model has been removed from Windows
releases following Windows98. Miniports are now the recommended implementation
to use for NIC drivers, and these have a number of benefits:
•
•
•
They support newer versions of NDIS, and can thus take advantage of any new
features after NDIS 3.1.
Only hardware-specific code must be written, and they are therefore smaller and
less complex to write.
They are OS-independent, hence it should be possible to compile the same source
on any version of Windows, without requiring any changes.
This issue of working on many operating systems is key to the Miniport concept, and
would appear to be where the ‘port’ suffix derives from. The main hindrance to
portability, is which version of NDIS the Miniport was designed for. For example,
Windows95 and NT 3.51 only support up to NDIS 3.1, and thus Miniports from later
versions may not work if the newer extensions are used. Table 4-1 shows the highest
version of NDIS supported by different versions of Windows:
NDIS 2.0.1
WFW3.1
WFW3.11 NDIS 3.0
NDIS 3.1
Win95
NDIS 3.1
NT 3.51
NDIS 4.0
Win95b
NDIS 4.0
NT 4.0
NDIS 5.0
Win98
NDIS 5.0
NT 5.0
Table 4-1 - NDIS Support in Windows
Each version of NDIS is backwards-compatible, thus Windows98 provides support for
NDIS 2.x up to NDIS 5.0. Note that at the time of writing, NT 5.0 is only in the Beta
testing stage, and the actual NDIS implementation may be updated. Win95b refers to
Windows95 OSR2, which was never released as an “off-the-shelf” product, and was
only available with OEM machines. The original Windows95 release, however, can be
upgraded to support NDIS 4.0, and this process is described in APPENDIX A. It was
decided that NDIS 4.0 be used within the project, and thus this update has to be
performed.
It is also conceivable that operating systems other than Windows could implement the
NDIS environment. Miniports should be relatively easy to port to the new system, as
long as both the operating system and the miniport conform to the NDIS specification.
4.3 Dynamic Libraries
28
One of the major difficulties in designing and developing an NDIS Miniport is
understanding the file-type. The primary source of information on NDIS is the
Windows NT 4.0 Device Driver Kit (DDK) 2, which is a very good reference once
development is under way, but is not suitable for use as a tutorial for the novice device
driver developer. Thus it makes no attempt to explain the file type which should be
produced by the linker. This situation is compounded where the target system is
Windows95, due to the fact that the NT DDK does not provide information on
developing Windows95 NDIS drivers. Reciprocally, the NDIS section of the
Windows95 DDK9 merely directs you to the NT DDK for further information.
Although this general lack of information was found to prove difficult in the
development of this project, the material in this document should remedy the situation
for those undertaking similar projects in the future. The compilation process of a
Windows95 NDIS Miniport is undocumented in either operating system’s DDK, but
Section 5.3 describes the method that must be used to perform this.
The Miniport driver is basically a 32-bit protected mode DLL (Windows Dynamic Link
Library). DLLs can be called dynamically to provide functionality to other processes.
The term ‘dynamic’ is used to distinguish such libraries from those that provide
functions which are included in an application’s binary file when the driver is compiled
and linked. Thus with dynamic libraries, the actual code in the library is not included in
the distributed binary file, and instead is provided whenever the application requires it.
For further information on DLLs, consult the Windows98 Resource Kit3.
The major difference between normal DLLs and Miniports (as well as VxDs), is that
DLLs run at a less privileged processor level, ring-3, the same level which applications
run at. Device drivers, however, must run at privilege level 0, or ring-0, which allows
them access to low-level system resources, memory etc.
Miniports run in a single 32-bit flat model address space, and of course have ready
access to virtual memory. They also have somewhat indirect access to physical
memory addresses, which can be accomplished by page-locking. This ensures that a
virtual memory range is always mapped to a given physical address range, and virtual
addresses can then be used to access physical memory on a hardware device.
Although not specified by the DDK, the file extension assigned to Miniports is .SYS,
not to be confused with 16-bit MS-DOS drivers. The actual file format is the Portable
Executable (PE) format, which is common across all Windows platforms since
Windows 3.1. This format is not only used for Miniports, but all Windows executables,
such as applications or DLLs. The linker in any Windows development platform should
create them, and thus the intricacies of the format need not be learned. To give an idea
of the format, however, they are basically laid out in a very similar fashion to how the
process will actually look once loaded into virtual memory. Thanks to this structure,
the Windows loader need not perform a great deal of processing to run the file. If more
information is required, Peering Inside the PE11 provides a very good tutorial.
4.4 NDIS Interfaces
29
The interfaces involved in NDIS have now been introduced, and this section shall now
provide some more depth in the subject. Although in Figure 4-5, it appears that the
NDIS subsystem sits only between the Miniport and the Protocol drivers, in actual fact
NDIS provides functionality on both “sides” of the Miniport. The functions on the
Protocol side are termed ‘upper-edge’ functions, and those towards the hardware
‘lower-edge’. As the Miniport is a type of DLL, it ‘exports’ functions on its upperedge, and it ‘calls’ functions on its lower-edge. That is, it provides functions to the
Protocols, which can be called dynamically, and it utilises lower-edge (NDIS library)
functions to talk to the card. NDIS is the intermediary between both sides, and thus no
direct communication occurs. This is illustrated in Figure 4-6, where the “NetCard”
can be thought of as a 1394 card. From this diagram it is easier to see where the term
‘wrapper’ comes from.
Figure 4-6 - NDIS Wrapper
Note that the Native Media Aware Protocol, and Intermediate driver are only present
in special situations, but have been included for completeness. An NDIS Intermediate
driver can be used to process packets before they reach the Miniport, for example to
perform a security check, or frame conversion. A Native Media Aware Protocol allows
you to develop your own protocol, which talks directly to the Miniport, and may be
useful for unsupported network-media types where normal protocols, such as TCP/IP
are not wanted.
To explain the NDIS system, an example process might be TCP/IP sending a packet to
a distant machine on the 1394 bus. The process should occur as follows:
1. The protocol driver constructs a packet (IP datagram), and packages it into a
media-specific frame (1394 packet).
2. The protocol driver calls NDIS to pass the frame down to the Miniport. It does this
using the NDIS library function NdisSend, and NDIS passes the packet on to the
Miniport’s Send function (for sake of argument MiniportSend).
3. MiniportSend is called in the Miniport, which takes the packet and places it onto
the 1394 physical medium. Talking to the hardware is accomplished using the
NDIS library functions, for example NdisWritePortUchar for port i/o.
4. Any status, such as a failure, is indicated back up to the Protocol via the NDIS
wrapper.
30
It can be seen then, that both the Protocol driver and the Miniport are isolated not only
from each other, but from the hardware and the rest of the operating system. Any
functions that are called by an NDIS driver are provided by the NDIS wrapper. In this
respect, the developer is limited to a particular function set, and cannot link in the
usual code libraries. However, the NDIS library provides a great deal of functionality,
which should be sufficient for the needs of a driver. This abstraction from the operating
system is key to cross-platform portability. No operating system specific function calls
should be made, which means that any operating system can implement NDIS by
passing the NDIS calls to its own proprietary calls.
An important point to understand is that the protocol packages the frames for the
Miniport, and thus must be aware of the media type in use. The example process above
showed that the protocol should package the information into a 1394 packet, however
in practice, the Windows protocols do not support 1394 packet formats. The common
types are supported, such as Ethernet and Token Ring, and therefore an Ethernet
Miniport, for example, need not process the frame, as header information such as the
destination and source addresses are already present in the frame. The fact that only
certain media types are supported by the protocols causes problems when new network
types are to be used, a situation very apparent in the development of this project. The
simple way round this is to accept a supported frame-type from the protocols, and
convert this to a 1394 packet before sending. Section 5.2.6 discusses the possible ways
to implement such a system.
Miniports have to provide certain mandatory functions on their upper-edge, those used
for sending packets, querying the network status, and so on. These functions, as well
as the NDIS library functions are fully specified in the NT DDK2 and this should be
consulted if more research is required. This chapter is intended only as an introduction
to the structure of NDIS, and although subsequent chapters introduce more in-depth
topics, the NT DDK should be consulted for a full understanding.
References
1
Dhawan S. (1995), Networking Device Drivers, Van Nostrand Reinhold, p94
Microsoft (1996), Windows NT Version 4.0 Device Driver Kit, Microsoft
Corporation
3
Microsoft (1998), Windows 98 Resource Kit, Microsoft Corporation
4
Dhawan S. (1995), Networking Device Drivers, Van Nostrand Reinhold, p13
5
Microsoft (1996), NT4 DDK: Network Drivers Design Guide Part 1, Microsoft
Corporation
6
ISO (1984), Basic Reference Model for Open Systems Interconnection, ISO:7498
7
Halsall F. (1996), Data Communications, Computer Networks and Open Systems, 4th
Ed, Addison-Wesley
8
Buchanan W. (1999), PC Interfacing, Communications and Windows Programming,
Addison-Wesley, p648
9
Microsoft (1996), Windows 95 Device Driver Kit, Microsoft Corporation
10
Microsoft (1996), NT4 DDK: Network Drivers Design Guide Part 2, Microsoft
Corporation, Section 1.3
2
31
11
Pietrek M. (1994), Peering Inside the PE: A Tour of the Win32 Portable Executable
File Format, Microsoft Systems Journal (March 1994)
32
5. DRIVER DESIGN
5.1 Networking & IEEE-1394
IEEE-1394 has already been introduced as a bus standard in Chapter 3, which
discussed the various capabilities of this new technology. It detailed how the current
usage of 1394 has been focussed on interoperability. This project presents a unique
opportunity to use the 1394 Bus in an entirely new way. The following section outlines
the many decisions which had to be made on how the 1394 Bus could best be utilised
as a computer networking medium, followed by a description of how the final driver
design concept was determined.
1394 can operate as its own protocol, without carrying any higher-level protocols,
such as TCP/IP, over it. Thus it can be used as a complete bus for interoperability, and
would tend not to be compared with the OSI model. However, it may be useful to
draw comparisons with the OSI model when using 1394 for carrying networking
protocols over the medium. To take the example of carrying TCP/IP traffic, this could
fit into the OSI model as shown in Figure 5-1. There are some bus management
functions that, if present, may sit higher up in the model, but to keep the model simple
they shall be omitted.
Figure 5-1 - 1394 and the OSI Model
5.1.1 Asynchronous/Isochronous Traffic
To use the1394 Bus as a computer networking medium, some design decisions needed
to be made on which characteristics of the 1394 Bus are useful and which can be
discarded. Perhaps the decision with the greatest impact, was the choice of purely
asynchronous traffic. Isochronous traffic was a major goal in the development of 1394,
and stands out as one of its main features. However, that does not mean that it should
be used in every 1394 platform, and by using only the asynchronous capabilities we can
still take advantage of high-speed communications, and all of the other features of
1394. As we have seen, asynchronous is the conventional transmit/acknowledge
transfer to an explicit address, and isochronous is a broadcast, unacknowledged service
for guaranteed bandwidth applications.
Isochronous traffic was chosen to be left unimplemented for the following reasons:
•
•
It cannot be used for sending data to an explicit node on the Bus. Instead it
broadcasts to all nodes listening to a certain channel.
It is for guaranteed bandwidth applications, and the current Windows networking
implementation, for example the TCP/IP protocols, make no provision for
33
•
attaching a bandwidth requirement, or quality of service (QoS), to a packet that
must be sent.
The project must be implemented in a reasonable time-scale.
5.1.2 Broadcast Networks
As discussed later in this chapter, it was decided that the eventual product should work
in a similar fashion to Ethernet, which provides only asynchronous capabilities. Explicit
addressing is very important, because packets to be sent are normally sent to an
explicit node on the bus, except for such broadcast events as ARP (Address Resolution
Protocol within TCP/IP), and for multicast sends. Such networks are termed broadcast
networks, described by Mackenzie (1998)1:
“In a broadcast communication network, the subnet has no switching nodes, and all
hosts share a single physical medium, which may be a cable, a fibre or free-space. A
transmission from one host is broadcast to all others, in the sense that it is placed in
the medium, where it becomes visible to the receiving apparatus at each possible
destination. Each message must carry some form of destination identifier or address
as part of its protocol control information. A possible destination only recognises
that it is the intended target by examining the address in the message and identifying
it as its own.”
Asynchronous transfers on the 1394 Bus conform to the above definition, as each node
acts as a repeater, but with the added complexity of addressing within each node. Not
only does the asynchronous packet identify the destination node, it also identifies an
offset within the node’s memory space. This is useful for controlling external, dumb
devices and can also be used to set various 1394 operational registers at each node.
This concept is entirely described in the Control and Status Register (CSR)
Architecture for Microcomputer Buses specification2. The result of conformance to
this architecture is each device on the 1394 Bus can be effectively locally mapped or
memory-mapped to the other devices on the Bus.
The implications of CSR in a computer networking environment were considered and
it was decided that the memory offset be ignored, in order to work in a similar fashion
to Ethernet. Only the 16-bit node ID would be used to identify the destination
machine, and the other 48 bits of the CSR address can be ignored as they are not
required for network addressing. To standardise this, it was decided that all 48 bits
would be set to zeroes in each packet. Alternatively, future implementations may find
some other use for these redundant bits.
1394 does not inherently make any provision for multicast asynchronous sends, and as
such it was decided that multicast be unsupported in the implementation. The
implications of this are not greatly important, but are also difficult to measure. How
much of an adverse effect this would have will vary widely between different networks.
It is envisaged that the majority of traffic on the eventual networks will be unicast,
however. If multicast transfers were deemed to be a solid requirement, it would be
possible to implement them using isochronous channels. Each multicast group would
be identified by a unique 1394 isochronous channel number. To do this, some work
must be carried out in developing a new protocol to communicate the channel
34
identifications to each member of the multicast group. Alternatively it may be possible
to set aside a group of 1394 Bus IDs, each to be used for one multicast group,
however the Texas Instruments development cards provided for use with this project
only make provisions for listening for one Bus ID. There are workarounds then, but
generally they would cause problems on unicast sends, or would require some extra
management, all of which begin to stray from the 1394 specification.
Broadcast asynchronous transactions are specified in 1394-19953, which states that for
destination addresses containing entirely binary 1’s “All nodes on the local bus shall
recognize the packet”. However, during discussions with David Wooten of the 1394
Trade Alliance, it became apparent that there are problems with broadcast sends. This
is due to poor early implementations of 1394 link silicon. Both broadcast and multicast
are to be properly supported in future 1394 standards using “asynchronous streams”.
The p1394a draft specification4 discusses these:
“An advantage of an asynchronous stream is that broadcast and multicast applications that do not
have guaranteed latency requirements may be supported on Serial Bus without the allocation of a
valuable resource, bandwidth. An additional advantage is that asynchronous streams may be easily
filtered by contemporary hardware.”
It is unfortunate then, that the development cards for use with the project conform to the earlier
standard 1394-1995, and as such, some other methods of achieving broadcast and multicast must be
found. The implications of the lack of broadcast far outweigh those for the lack of multicast. As
mentioned above, TCP/IP uses broadcast for ARP, which enables the protocol suite to identify the
MAC address related to a specific IP address. With 1394-1995, some methods had to be developed to
enable broadcast to occur, in order to properly implement TCP/IP. The design decision and some
alternatives for implementing this are identified in Section 5.2.10. For a discussion of ARP, see
Tanenbaum (1996)5.
5.1.3 Bus Management
There are two bus management entities that can be implemented on the 1394 Bus.
They can reside on any node, and do not have to be on the same node. The
isochronous resource manager provides services such as guaranteeing adequate
bandwidth and allocating channel numbers, whereas the bus manager provides services
such as maintaining topology maps. Clause 3.8 of the 1394-1995 specification6 states
that “a valid combination is the absence of any bus manager entity in which case no
isochronous traffic is allowed.”
Given that no isochronous traffic is required by the design, it is deemed acceptable to
omit both entities, and function as an unmanaged bus. The 1394-1995 specification
also details the fact that cycle masters are only required for isochronous traffic, and
thus a cycle master and slaves are not required by this design. Further information on
cycle masters and bus management can be found in Clause 8 of the 1394-1995
specification7.
35
5.2 IEEE-1394 & NDIS
NDIS and 1394 have, until now, been two entirely separate technologies, and nothing
was found to suggest that a relationship between the two had been implemented in the
past. This presented a particularly fulfilling project objective, where there was scope to
entirely shape the product, and no need to conform to previous methods of
implementation. To this end, it was possible to investigate a number of different routes,
before arriving at the final design choice.
Perhaps the decision with the greatest impact, was the type of device driver to
implement. There are four possibilities:
•
•
•
•
VxD – Full legacy NIC driver
Miniport NIC driver
Intermediate Driver / TI API
Intermediate Driver / WDM Driver
5.2.1 Legacy VxD Driver
Legacy drivers were introduced in Section 4.2.2. They are “full” in that they must deal
with a number of complex operating system issues, as well as the normal hardware
issues related to the network interface card (NIC). They are described in the NT
DDK8:
“Introduced with the initial release of Windows NT, full NIC drivers require the
device driver writer to program at a more basic level, dealing with kernel-mode
issues of multiprocessor support and processor and thread synchronization. Full NIC
drivers require driver developers to write a large amount of code to deal with issues
that are common across all NDIS drivers.”
It is, of course, desirable to the developer that more issues are taken care of by the
operating system. It may, however, be that control over this extra functionality is
required in the driver, but this scenario seems unlikely given that Microsoft have
officially stopped supporting legacy drivers. Certainly in this case, control of these
features is not a design requirement, and would serve to add unnecessary overhead to
the workload.
Another very important consideration with legacy NIC drivers is that they are written
specifically for a particular operating system. That is a Windows95 legacy NIC driver
could not simply be recompiled on NT. The amount of work involved in porting to a
different operating system would differ between drivers, but complete crosscompatibility is a useful feature.
Finally, legacy NIC drivers are not supported in NDIS 4.0 or above, thus the
extensions provided by later versions are unavailable.
36
5.2.2 Miniport NIC Driver
Miniport drivers overcome the problems faced by legacy NIC drivers that were
outlined above. The NT DDK8 says the following of Miniports:
“Windows NT supports miniport NIC drivers to allow developers to write only the
code that is specific to the network hardware, merging the common functions into
additional services provided by the NDIS library. Miniport NIC drivers are smaller
and faster, requiring much less work to write. Miniport drivers are able to defer
handling of many issues to the NDIS library.”
Thus Miniports immediately appear to be an attractive target type. Less functionality
has to be provided by the developer, and they are smaller, thus will make a reduced
footprint in system memory. Also during fault-finding, if there is less code, faults are
easier to find. Most important of all, however, the project can enjoy a shorter
development time; other than the features that are now taken care of by the NDIS
library, the code is essentially very similar in a Miniport.
5.2.3 Intermediate Driver / TI API
Miniports and legacy NIC drivers must contain hardware-specific code, in order that
the hardware be controlled. This means that this code has to be written by the
developer, and the intricacies of the hardware must be learned in order to do this.
However, in actual fact, an API (Application Programmer Interface) is provided with
the Texas Instruments 1394 cards. This API exports a library function-set which can be
used to control the 1394 cards. Functions are provided to program all operations on
the devices. The API is a VxD device driver, called pcilynx.vxd. It is only supported in
Windows95/98, no equivalent is provided for NT.
Figure 5-2 - Intermediate Driver Structure
It is possible within NDIS to implement a structure similar to Figure 5-2. Here the
intermediate driver would be the output from this project, and it sits between the
protocol drivers and the TI-supplied API driver. Just as with a Miniport/legacy driver,
the intermediate driver accepts commands on its upper-edge, however, instead of
directly controlling the hardware, it communicates with the API to perform the
hardware functionality. In effect, it is masquerading as a Miniport to the protocol
drivers.
37
The attractiveness of this implementation lies in being able to omit the hardwarespecific code, leaving it up to the API. One or two fairly simple function calls could be
used to perform otherwise complex operations on the hardware. This structure was
afforded a great deal of consideration, and a number of problems were identified.
The intermediate driver, by specification, is intended for protocol-level functionality.
Perhaps to perform tests on packets before they are passed to the Miniport below, or
to change the frame format before frames are sent and so on. This structure deviates
from the NDIS specification, where the hardware functionality is always performed by
an NDIS driver. This is effectively making a call to a driver outside NDIS, which
perverts the wrapper concept. The NT DDK does not even recognise that calls outside
NDIS are possible, but experimentation has proved that this is possible. For example,
the Windows95 DbgPrint technique, documented in Section 5.5.1, makes a call to
VxD wrapper services that are supposedly unavailable to NDIS drivers. Although it is
wrong to make such calls, it may be the only way to perform a certain action. In the
case of DbgPrint, however, and possibly universally, such a call makes a driver OSdependent. This is not particularly important for a debug technique that will not be
present in release-level code, however OS-independence is important in core
functionality in release versions. OS-independence is in fact impossible while the TI
API is only available for Windows95/98, however it is conceivable that an NT API will
be released eventually.
Apart from not conforming to NDIS, there are other issues to consider in developing
an intermediate driver. No control can be gained, internally to the API, unless the
source code is available. Texas Instruments were contacted regarding the possibility of
obtaining this source code, but it was only available at a price, and a decision was
made that the benefits of obtaining this would not justify the cost. Thus one cannot be
sure of the methods used within the API, and the efficiency of those functions required
by the project design. Considering the fact that the project was rather unique, it was
deemed as appropriate that full control be available over the hardware and 1394 Bus.
At a higher level, this method introduces some cross-communication between drivers,
and this might produce inefficiencies, which are undesirable when working with highspeed communications. Coupled with this, the synchronisation and multi-processor
issues mentioned with regard to legacy NIC drivers, may not be implemented as
required by NDIS, and interrupt-handling, usually taken care of by NDIS, becomes
confused.
Finally, the API is provided as a universal access method to the hardware. A lot of this
functionality may not be required by the design, for example isochronous transfer, in
which case there is redundant code consuming resources.
5.2.4 Intermediate Driver / WDM 1394 Bus Class Driver
Windows98 and the forthcoming Windows NT5 also provide driver support for 1394
buses. This support is entirely removed from NDIS, and the intended use is to control
remote devices, such as video cameras, on the 1394 Bus. The support is via a WDM
(Windows Driver Model) driver, which works in a similar fashion to the Texas
Instruments API. It is conceivable that an intermediate driver could be written to sit in
38
the NDIS structure, and the pcilynx.vxd API would be replaced with this bus class
driver.
This method would suffer from the same problems as the TI API method, as it is
basically doing the same thing. Furthermore, WDM drivers are not supported by
Windows95 or Windows NT4/3.51, thus the time spent on developing such a driver
would have to be supplemented with work on support in older Windows versions.
Although it is good to support the new models such as WDM, it presents problems
when older versions of Windows need to be supported. Given that this project
primarily requires a Windows95 driver, this was deemed an unsuitable development
route. This issue introduces an interesting dilemma faced by device driver developers in
general, when there are a number of driver models to follow. They must make tradeoffs depending on which operating systems are to be supported, and often would
dismiss new and possibly superior models, to ensure compatibility across platforms.
The fact that these new drivers are available with WDM may be useful for the normal
(interoperability) operation of the 1394 bus, however it must be stressed that they do
not provide networking support. The result of this project would still be used in the
new operating systems when networking is required.
5.2.5 Driver-Type Design Choice
Although both intermediate driver methods reduce the amount of code that needs to be
developed, the problems described above were deemed to outweigh this advantage.
Thus the choice lay between a Miniport and a legacy NIC driver, and given that no
disadvantages of Miniports over legacy drivers were identified above, the final design
choice lay with Miniports. Miniports are a progression from legacy drivers, and are the
Microsoft-advised method. This decision was also agreed with the project supervisor.
The intended NDIS structure is shown in Figure 5-3.
Figure 5-3 - Driver Position within NDIS
5.2.6 Ethernet Emulation
The fact that NDIS supports a restricted set of media types presents an interesting
problem when developing for a new media type such as IEEE-1394. Any NIC driver
must tell the NDIS library which medium it supports. With NDIS 4.0, the following
media types are supported:
•
•
•
•
Ethernet (802.3)
Token Ring (802.5)
FDDI
LocalTalk
39
•
•
•
ARCNET
WAN (point-to-point and WAN cards)
Wireless
Given that 1394 is not currently recognised by Microsoft as a network type, and the
fact that it is such a new technology, it is not supported by any available version of
NDIS. This is not an ideal situation, but it is not insurmountable. The 1394 Miniport
can “pretend” to the upper layers that it is one of the supported types. The medium to
masquerade as is not extremely important, and Ethernet was chosen for the following
reasons:
•
•
•
•
•
The developer has previous knowledge of Ethernet, and understands the basics of
transmission and frame formatting.
It is a fairly basic medium, with simple concepts for addressing destination nodes
etc. It should be easy to translate 1394 to encompass these concepts.
It should be supported by most of the protocol drivers, which for example,
ARCNET is not.
Frames can contain a fairly large amount of data (up to 1500 bytes), thus there
should be no need to send more 1394 packets than necessary. If the data length in
each frame was limited to a smaller value than 1394 could support, the abilities of
1394 would not be utilised to the maximum. See Table 5-1 for an indication of
1394 packet sizes.
The NT DDK9 suggests that “ATM media should implement LAN-emulation
functions within themselves, and report their medium type as Ethernet 802.3 or
802.5”. Although this is referring to ATM, it may be general advice to support one
of these two types for any non-native media.
NDIS protocol drivers output frames correctly formatted for the chosen medium. Thus
if a 1394 Miniport chose to emulate Ethernet, it would receive packets to be sent onto
the 1394 Bus, with some Ethernet framing data already present. The actual fields
present are the Destination Address, Source Address and Data Length fields. It is
normal that an Ethernet NIC would add the rest of the fields on transmission
(Preamble, Start Delimiter, FCS and Delay). Thus the Miniport does not have to take
care of any framing issues, it merely passes the frame onto the NIC for a send, or
passes it straight up to the protocol drivers on a receive. For further information on the
Ethernet frame format, consult Buchanan (1997)10.
The actual operation of the 1394 Miniport then, would be to accept an Ethernet frame
to be sent, and encapsulate it in a 1394 packet, before placing it on the 1394 Bus. This
process is depicted in Figure 5-4.
40
Figure 5-4 - Ethernet/1394 Send Process
The resultant 1394 packet would contain the whole Ethernet frame, surrounded by the
1394 framing information. Figure 5-5 shows a very basic view of the resultant 1394
packet. The 1394 fields are representative of the packet formatting information. In
1394 language, the Ethernet frame would constitute the data payload. The format of
these 1394 packets is described in the 1394-1995 specification11.
Figure 5-5 - 1394 Encapsulated Ethernet Frame
Including the Ethernet framing fields is effectively including redundant information.
The addressing and data length fields take up exactly 14 bytes, and ideally these would
be stripped. The problem is that they would have to be reconstructed at the far end
before being passed back up to the protocol drivers. This may be fairly simple using the
information in the 1394 packet header, but this would take up valuable processor time,
and may slow down packet reception. Given that 14 bytes is not a massive overhead,
the information has been deemed small enough as to not pose a problem.
Other implementation possibilities are:
•
•
Intermediate Driver
Rewrite protocol drivers
An intermediate driver could be written to sit between the protocol drivers and the
Miniport. For sends it would convert Ethernet frames from the protocols into 1394
packets, and perform the reverse on receives. Unfortunately, there will be processing
and resource overheads in introducing an extra driver layer, which would slow the
system down. Also this intermediate driver would perform such a small amount of
processing on the packet, that the need for separating it from the Miniport is
questionable.
Rewriting the protocol drivers is a very drastic option, and would be a rare choice for
supporting new media types. All of these drivers, such as for TCP/IP or IPX/SPX,
would have to be changed if they were required over the 1394 Bus. They would then
41
output correctly formatted 1394 packets, which could be placed immediately onto the
bus by the Miniport. Target customers may not want to replace their protocol drivers
when they upgrade to 1394 hardware, and if they were using proprietary protocols,
these would no longer work. Ideally, 1394 should become an NDIS-supported media,
at which time Microsoft would release 1394-ready versions of the protocol drivers. An
Internet Engineering Task Force (IETF) Working Group, is in fact working on an IP
over 1394 standard12, which will hopefully be adopted by Microsoft within its IP
driver, such that 1394-formatted packets will be passed down to the Miniport.
IPover1394, however is to support only p1394a hardware, and to support the other
protocols, such as IPX/SPX, the Miniport would still have to report itself as a
Windows-native media type.
Both the Intermediate and protocol driver options still require a Miniport to be
developed, and provide little help to the Miniport. Therefore, the time and costs
involved in developing these new drivers are deemed to far outweigh the advantages.
5.2.7 1394 Transaction Type
There are two types of transaction on a 1394 Bus that perform an asynchronous send.
These are:
•
•
Write request, data quadlet
Write request, data block
Both of these actions allow data to be sent to an explicit address on an explicit
destination node. Both consist of a header and a payload in which the data to be sent is
placed. A quadlet write can transfer a 32-bit data payload, whereas a block write can
transfer one or more quadlets of data. Block writes are limited to a maximum payload
size, depending on the data rate. The maximums in a cable environment are given by
Table 5-1.
Data rate
Maximum payload size (bytes)
S100 (Cable base rate) 512
S200
1024
S400
2048
Table 5-1 - Maximum Payload Sizes
The minimum size of an Ethernet frame that might be passed down from the protocol
drivers is equal to the minimum length of data added to the header size. As discussed
in Section 5.2.6, the header information takes up 14 bytes for Destination Address,
Source Address and Data Length. The minimum number of data bytes is 46, up to a
maximum of 1500 bytes. Thus the minimum frame size that would need to be
contained in a 1394 packet, is:
14 + 46 = 60 bytes.
Thus a quadlet write (4 bytes) would not be sufficient to transmit the smallest possible
Ethernet frame. Therefore it was decided that block writes be used for all frame
transmission. The largest possible Ethernet frame would contain 1514 bytes. This
42
could not be transmitted at S200, at which the maximum payload is 1024 bytes. Given
that the project development cards are only capable of up to S200, there are three
possibilities:
•
•
•
Notify NDIS/protocols that the maximum frame size is 1024 bytes.
Split larger frames up into two smaller frames.
Upgrade to S400-capable cards.
The first option would be the simplest to implement, and should not have an adverse
effect on the network. Thus the final design choice here lay with asynchronous block
writes for all frame transmission, up to a minimum Ethernet frame size of 1024 bytes.
Note that the actual 1394 block write packet also contains a header, which is not
involved in the limitations shown in Table 5-1. The header size is 4 quadlets, thus the
actual maximum packet size at S200 would be:
1024 + 16 = 1040 bytes.
There are also 2 quadlets which provide a CRC for the header and the payload,
bringing the transmitted packet up to 1048 bytes. The block write packet format is
shown in Figure 3-3 however for detailed information on the 1394 packet structures,
consult the 1394-1995 specification11.
5.2.8 MAC Addresses
One problem with acting like an Ethernet NIC, is that NDIS expects each NIC to have
a unique 6-byte MAC address. This is used by the protocol drivers to construct a
correctly addressed Ethernet frame on a send. Thus the destination and source address
fields will contain the MAC address of the destination and source nodes. Thanks to
this, a real Ethernet adapter can pick up frames addressed for itself, and the Miniport
need not know anything about which node the frame is destined for.
1394 Buses use a different addressing scheme, which is only 2 bytes long, shown in
Figure 5-6. The first 10 bits identify the bus number, and the final 6 bits identify a
particular device on that bus. These IDs are dynamic, and can change after any bus
reset. Thus it would be unsuitable to notify protocols of this information, as it can
change whenever a new device is connected to or removed from the bus, or any other
action that causes a bus reset.
Figure 5-6 - 1394 Node ID Format
Given that the Windows protocol drivers assume that an address is static, some means
of providing each 1394 NIC with a unique static ID is required. Also that ID should be
6 bytes long, in order to comply with Ethernet MAC addresses. When each 1394
Miniport registers itself with NDIS, it is queried for the NIC’s MAC address, and it
should pass back some unique address. How that address should be calculated or
assigned, is a point of consideration. It could be assigned by the network administrator,
43
in much the same way as they must assign unique IP addresses. Alternatively, it could
be calculated internally on installation, or on loading the Miniport.
There are a few possibilities for obtaining a unique MAC address, some of which are
listed below:
•
•
•
Based on the time at installation, or on first loading the Miniport.
Based on some unique information from the Windows registry, possibly the
Windows serial number.
Based on the 1394 card serial number
The immediately appealing option is to use the 1394 serial number. It is the most likely
route to provide a unique 6-byte number. The serial number is stored in a serial
EEPROM on the PCI development cards, and is 2 bytes long. The remaining 4 bytes
can be made up of almost anything, although resultant MAC addresses to avoid are:
•
•
All one’s (FF:FF:FF:FF:FF:FF in hexadecimal) - reserved for broadcast sends.
Those with a 1 in the most significant bit - reserved for multicast.
Further information on MAC addresses and reserved values can be found in
Fundamentals of Ethernet Technology13.
Reading the serial number is not as simple as reading from the PCILynx register space,
which is the normal method for programming the development cards. Sample code14
for doing so is provided with the cards and the format of the EEPROM is described in
the Lynxsoft guide15.
Note that if other manufacturer’s 1394 cards are eventually supported by such
Miniports, and are to co-exist with this Miniport, then a suitable algorithm must be
chosen to create MAC addresses such that it cannot result in conflicting addresses.
It is envisaged that initially MAC addresses will be chosen by an administrator, until
such a time as the above EEPROM method is implemented.
5.2.9 MAC/Node ID Translation
The previous section discussed the allocation of a unique MAC address for each 1394
NIC. This may take care of the upper edge of the Miniport, in that it will have
information for NDIS regarding its MAC address, but it does not provide a method for
translating these MAC addresses to a 1394 node ID, like that shown in Figure 5-6. As
it stands, the protocol drivers would be passing down frames addressed to certain
MAC addresses, and the Miniport would not know which 1394 node this MAC
address referred to. Thus it could not place the frame on the 1394 bus.
In simple terms, the Miniport has to do the following when it is passed an Ethernet
frame:
1. Check the destination MAC address of the frame passed to it.
2. Translate this to a 1394 node ID.
44
3. Build a 1394 packet addressed to the correct 1394 node ID, with the Ethernet
frame as the data payload.
The simple answer would be to somehow derive the 1394 node ID from the MAC
address, however this is not possible in a real implementation, as the node IDs are not
constant; they can change after a bus reset. MAC addresses must remain static in order
to not confuse the upper layer protocols, therefore they can not also change after a bus
reset.
This is a complex problem, and one that was given a great deal of consideration. Each
Miniport must, in some way, maintain knowledge of the translations of 1394 Node IDs
to MAC addresses. To gain this knowledge, some mechanism had to be developed to
enable the Miniports to build up a database of MAC to 1394 address translations.
It was decided that, on loading or after a bus reset, each Miniport would notify all
other nodes of its MAC address and its 1394 ID. Thus each Miniport would receive
the details from other nodes, and end up with a complete table. It could then use this
table to cross-reference MAC addresses whenever a packet needs to be sent. This is an
unusual action for a Miniport to perform, due to the fact that Miniports are usually
“dumb” layers, which merely pass frames onto the medium, or pick them off and send
them up to the protocols. The functionality described herein brings the Miniport into
the realms of addressing, usually taken care of by the network layer, as described by
the OSI Model16.
For each node to notify the other nodes on the 1394 Bus of its MAC address, a
protocol had to be developed to carry this information. Ideally a simple broadcast
mechanism would be used, where one broadcast packet is received by all nodes, and
the MAC/1394 address information is stored within the Miniports. Unfortunately, due
to the problems with 1394-1995 broadcasts, another method had to be developed.
Thus three possible options were identified that could be used for communicating with
every node:
•
•
•
Isochronous delivery.
Reiteratively send one packet to each child and parent.
Send one asynchronous packet to each node.
Isochronous delivery could be utilised by programming every node to listen on a
certain isochronous channel, over which they would send their MAC/1394 address
details in small packets. In theory this appears a simple mechanism, however on
consideration, it was decided that implementing isochronous capabilities on the bus
would bring with it many new configuration problems. Also, the allocation of
bandwidth, which could otherwise be used for normal asynchronous transfer, would
mean a reduction in data rates. There are many issues to take care of if isochronous
delivery is required, including setting up an isochronous resource manager entity.
Given the project time-scale, it was decided that the project should remain an
asynchronous only bus.
The second option would make quite efficient use of bus bandwidth. A node wishing
to broadcast to all other nodes could send one packet to each of its “children” and its
45
parent. In turn, these nodes would repeat the packet on all of their ports, and so on.
This way the packet would be efficiently propagated through the network to all nodes.
This would be quite difficult to implement, and in doing so would consume a fair
amount of project time, however it is noted as a possible future update.
Using the third option, of sending many asynchronous packets, is not immediately
attractive, however it was decided that it is an effective method, and is easy to
implement. In doing this, there would be a sudden influx of these packets after every
bus reset, however the impact of this can be reduced by using the smallest packets
possible. The following discussion will prove that the effect on bus bandwidth is
minimal. The Miniports will do the following in order to implement this:
1. Detect Bus resets.
2. On detection, build a small packet that contains at least the local MAC address and
the local 1394 ID.
3. Send this packet repeatedly to each of the other nodes (It knows what other nodes
are on the bus due to the self ID process).
In order for each Miniport to build up the table it must:
1. Check incoming packets to establish whether they are these special packets, or if
they should be passed up to the protocols.
2. If it detects one of these packets, it should not pass it up to the protocols, and
instead read the MAC/1394 addresses within, and store it in local memory.
3. Once it has intercepted a packet from all nodes, it will have a complete table of
translations.
After this process, when a normal frame is passed down to be sent on the bus, the
Miniport must first:
1. Read the first 6 bytes of the frame to determine the destination MAC address.
2. Look up the table to find out which 1394 ID this refers to.
3. Construct a 1394 packet addressed to the correct destination 1394 Node ID.
On receipt of a 1394 packet, a Miniport need not, of course, perform any address
translation. It must only check that it is not one of the small configuration packets
outlined above, as it is important that these packets are processed within the Miniport
and not passed up to the protocols. If a received packet is not a special packet, it does
pass it up, unprocessed.
The format of these packets was considered, in order to find a method of minimising
their size. It was decided that 1394 asynchronous quadlet writes be used, as these are
the smallest asynchronous packets. Also, if all other normal traffic were to be block
writes, then these special packets could be easily identified by type, without even
reading the information within the packet.
46
Figure 5-7 - Asynchronous Write Quadlet Payload
It was already decided that the destination offset in 1394 packets be ignored, and could
be set to all zeroes. Fortunately the “destination_offset” field is exactly 6 bytes, and
thus would be perfect for storing the 6-byte MAC address. The 1394 address is always
contained in the source ID field, therefore the packet already contains the necessary
information for other Miniports to build their translation tables. The format of these
quadlet write packets is shown in Figure 5-7, where both pieces of information
required of these packets can be seen to be totally contained in the packet.
The “tl” field, Transaction Label, can be used to further identify these packets, by a
given number, such as all one’s. This would only be required if there are other
occasions when quadlet writes will be used, otherwise they can be identified by the
“tcode”, Transaction Code, field, which will contain the code for quadlet writes.
The “quadlet_data” field is not required by this implementation, but is reserved for
future usage. It may be that later versions require extra information regarding the
capabilities of nodes, to be stored in the table. Information on the other fields in
quadlet write packets can be found in Clause 6 of the 1394-1995 specification17.
To investigate the effect that these packets will have on the bus traffic, we can
calculate a worst-case scenario. The maximum number of nodes per bus is 63.
Assuming there are 63 nodes present, each wishing to send a quadlet write to the other
62 nodes, the number of packets which would be placed on the bus is:
63 * 62 = 3906 packets.
The number of bytes this would consume, given that each quadlet write packet takes
up 5 quadlets (20 bytes):
3096 * 20 = 61,920 bytes.
This is not a massive amount of information, and at rates of 200Mbps (25 megabytes
per second), could be transferred in:
61,920 / 25,000,000 = 0.0024768 Seconds.
Given that bus resets should occur very rarely, normally only when a new device is
connected to the bus, this should not produce any noticeable effect on network
performance. This may cause a few problems on a network such as Ethernet, given the
collision detection mechanism it employs, however 1394 uses a fair arbitration system,
which would guarantee fair access to the bus. Should this still be regarded as adverse,
47
it is possible to reduce the overhead from packet headers by assigning one “master” to
accumulate 62 packets from the other nodes, and transfer the whole table in one block
write to each node, or to use the parent/children method.
The storage of the table will have some effect on the footprint of the Miniport within
memory. Each node will take up 8 bytes in the table (6 bytes for MAC address and 2
for 1394 ID). Therefore, to contain a table of 62 cross-references would require:
62 * 8 = 496 bytes.
Given the memory available on machines today, this is deemed to not make a
noticeable impact on Windows operation.
Other than these methods, the only other viable option is to upgrade all devices on the
bus to p1394a compliant, which can deal with asynchronous streams. Unfortunately
this is not only costly, but rather unforgiving in that a network will then not provide
support for any 1394-1995 cards whatsoever. Later implementations may provide
support for isochronous traffic or the parent/children method, but to keep the project
fairly simple in its initial stages, the asynchronous copy-to-all method will be used.
5.2.10 Broadcast and ARP
The previous section detailed how to implement unicast sends based on Ethernet MAC
addresses. Such transactions are generally the most common, and certainly the most
important send types on an Ethernet-type network. There are cases when broadcast
sends are required, however, such as with ARP, and the Miniport must be able to deal
with this in some way. This section outlines how broadcast will be implemented.
As outlined in Section 5.2.8, broadcast Ethernet sends are identified by a MAC address
where all 32 bits are binary 1’s. Thus, when the Miniport queries the frame’s
destination address, as it always should do for a unicast send (see previous section), it
must also recognise a broadcast address, and take some extra action.
Rather than using the lookup table to find the 1394 address, it must instead implement
some form of broadcast. The possibilities have already been discussed in some detail,
and it is assumed that the method will be as below:
1. Miniport detects a broadcast destination address.
2. Miniport just repeats the packets to all nodes on the 1394 Bus. Rather than analyse
self ID information, it will be quicker to use the table to determine which nodes are
on the bus.
Using this method, the Miniport does not have to hard-code any support for particular
types of broadcast transmission, such as ARP requests. An alternative method was also
considered and subsequently discarded which involved hard-coding ARP support:
1. Intercept ARP requests.
48
2. Use the table to respond automatically within the Miniport. This would involve
constructing a fake ARP response packet and passing it straight back up to IP,
without using the 1394 Bus at all.
Although this method does not involve the 1394 bus, and is therefore a very quick
mechanism, a number of problems were identified:
•
•
•
Support for only one protocol (IP) is hard-coded.
The table must also contain the IP addresses in order to be able to respond to ARP
requests. This would require the Miniport gaining knowledge of its IP address
which normally it does not know.
The table would increase in size by 4 bytes for each node in the table.
Due to these problems, it was decided that the original implementation be used, that is
repeating broadcast packets to each node. This concludes the main project decisions
made on how to best integrate 1394 with the NDIS system, and is the basis from which
the development was specified.
49
5.3 Hardware Control
The PCILynx contains a register-space, which is used to program the card. This space
is subdivided into quadlets (32 bits), each of which pertains to different information
and operations. Some of these quadlets are read-only, and some also provide write
access. As with all PCI devices, the PCI configuration space can also be read to obtain
information regarding the addresses of these registers and other PCI-related
information, such as the IRQ in use. This configuration area is depicted in Figure 5-8.
Figure 5-8 - PCI Configuration Control and Status Registers
The Base Address quadlets are used to determine the physical addresses of registers on
the card. Base Address 0 is the most important for programming the PCILynx chip,
whereas the others pertain to RAM and ports that are local to the card, and are not
implemented in this project. Communication with these registers in NDIS is achieved
by mapping them onto a local (Windows) virtual address space. In effect the physical
card register space is then also accessible using Windows-accessible virtual addressing.
Thus the address stored at Base Address 0 gains also a virtual address through an
NDIS library call, NdisMMapIoSpace, and each register is then programmed by
writing to or reading from an offset added to this virtual address.
Transmission on the 1394 bus is achieved by constructing correctly formatted 1394
packets in PCI-accessible memory. Each packet is supplemented with a Packet Control
List (PCL) which is a proprietary mechanism for programming the DMA busmaster.
These PCLs inform the busmaster of which operation must be performed, such as an
asynchronous transmit, and point to the memory containing the 1394 packet. For a
receive operation, this pointer will be to an empty buffer in PCI memory.
Therefore when a packet is to be sent, it must be correctly constructed in contiguous
PCI memory, and the address of this packet is then passed to the card, using the PCL
structure. As Windows implements virtual memory, the physical addresses of these
packets must be obtained as the PCILynx does not support virtual addresses. In NDIS
this means that a page-locked, shared memory range must be allocated, using the
50
NDIS library call. NdisMAllocateSharedMemory, which returns both a physical and
virtual address for the same memory range. Windows and NDIS operations are then
performed using the virtual addresses, whereas the card itself is passed the respective
physical addresses, and this memory is never paged out.
Figure 5-9 - PCILynx Data Transfer
Figure 5-9 illustrates the process of transferring data between the bus and PCI
memory. The busmaster copies 1394 packets between PCI memory and on-board
FIFO memory. On transmits, the busmaster copies packets into one of the transmit
FIFOs (isochronous or asynchronous), after which the LLC calculates and appends the
CRCs and copies the packets onto the bus. On receives, the packet CRCs are checked
and, if correct, the packets are copied into the General Receive FIFO (GRF). If a
receive PCL has been set up, then the busmaster copies the data from the GRF into
PCI memory.
Busmaster DMA is considered the fastest mechanism for PCI devices to use, because it
works on its own, while freeing up the computer’s processor to perform other tasks. It
is well described by Goldman (1998)18.
“Only the bus-mastering DMA data transfer technique leaves the system CPU alone
to process other applications. In bus-mastering DMA, the CPU on the network
adapter card manages the movement of data directly into the PC’s RAM without
interruption of the system CPU by taking control of the PC’s expansion bus. PCI
bus-based (devices) also exhibit low utilization of the main CPU thanks to the
intelligence of the PCI bus itself.”
A full description of design decisions, such as memory range requirements, is not
included here, as all hardware control has been described in the Module Specifications,
of Section 6.3. This section serves only as an introduction to a very complex hardware
system, and if a complete understanding is required, the PCILynx specification19 should
be consulted.
51
5.4 Development Environment
The actual tools and methods used when developing Miniports were found to be some
of the most confusing aspects of NDIS development. The intricacies of the functions
within the NDIS library are well documented; the format of parameters passed to it,
the return values and so on. There are, however, only sparse details of what is needed
to get started. For this reason, a great deal of time was spent learning the development
method, before actual coding began. The fruits of this labour are now presented here in
an accessible format, and this document can in future be used in conjunction with the
usual information, in the development of future NDIS projects, and even as a general
guide to Windows device driver projects.
Three products were required before NDIS Miniport development could start:
•
•
•
Microsoft Visual C++ v5.0
Microsoft Windows NT 4.0 Device Driver Kit (DDK)
Microsoft Windows Software Development Kit (SDK) September 1998
These are available in various release versions, and it may be possible to use older or
newer versions than were used in the development of this project. The language used
for developing NDIS Miniports is ‘C’, and it may even be possible to use a ‘C’
compiler other than Visual C++, for example the Borland/Inprise software, but there
may be slight implementation differences. Also the linker must be capable of producing
ring-0 level applications (see Section 4.3 for details). Therefore it is advisable to use
Microsoft products, as these are presumably the intended tools.
All three products are provided with subscriptions to the Microsoft Developer
Network (MSDN), although Visual C++ is also available as a retail product. The
Windows NT DDK should always be used for NDIS development, since the NDIS
details have been removed from both the Windows95 and Windows98 DDKs. As this
section details, it is possible to use the NT DDK for developing for these two
environments. A new version of the NT DDK is released with every new version of
NT. To find which version of the DDK you need, look up the version of NDIS in
Table 4-1, in section 4.2.2. Given that this project conforms to NDIS 4.0, the NT 4.0
DDK was used. Finally, the SDK version is not so important; it provides some tools
and libraries that may prove useful, as well as further information on the Windows
environment (although it does not contain any device driver level material).
Sample NDIS Miniport source code is provided as part of the DDK, and these drivers
are ready for immediate compilation for use in NT. However, as touched upon in
section 4.3, there are no references whatsoever to compilation in Windows95. This
situation would be acceptable if the Windows95 DDK provided these details, but the
only NDIS information is a suggestion to consult the NT DDK for the development of
Miniports. Given that the primary target system was specified as Windows95, a
method for development in Windows95 was an important objective.
The NT compilation process is taken care of by a utility known as BUILD, which
works in conjunction with the development environment (generally assumed to be
52
Visual C++). It takes an input configuration file, called a SOURCES file, which details
the filenames of the source-code, and the target type, in this case an NDIS Miniport.
BUILD is given the rest of the configuration information by the DDK. Thus it should
be easy to compile and test one of the example drivers.
Windows95, however, does not support BUILD, and an alternative method had to be
used to compile Miniport source from this environment. In both cases Visual C++ is
used to build the target driver file, but in Windows95 a ‘Makefile’ is normally used,
which is very similar to a Unix Makefile. This is rather like a batch file, which is used
to program the build process, and provide the correct parameters to the compiler and
linker. The Visual C++ integrated development environment (IDE) can be used, but it
is biased towards application development, and it is more difficult to exert absolute
control over the target file. Although compiling and linking may seem a simple
concept, the developer must provide a large amount of parameters to these tools, in
order to ensure that the target driver file is of the correct type, is formatted correctly
and so on.
The Makefile used in developing this project is included in APPENDIX C. It can be
used on a Windows95 or NT system to build Miniports for both environments. This is
done by providing a command-line parameter. It is also possible to use either
parameter to create a Windows98 Miniport. There are many parameters to be passed
to the compiler and linker, and these are all configured within the Makefile. For details
of the format of such files, the Visual C++ online help documentation should be
consulted.
The actual compilation is done from the MS-DOS command prompt, and the DOS
environment must be set with a number of variables, providing details of the location of
the Visual C++, DDK and SDK binary files and libraries. The utility NMAKE is part of
Visual C++, and uses the Makefile to build the target. The build process is depicted in
Figure 5-10.
Figure 5-10 - NDIS Miniport Build Process
The fact that the sample Miniports could not initially be compiled for use in
Windows95 proved to be a major obstacle to the project work, but once the Makefile
53
technique was completed, the development could properly ensue. The DDK sample
Miniports could be compiled, producing an output .SYS driver file. Due to the fact
that these samples were for particular network cards (both Ethernet and Token Ring),
they could not be tested since the cards were not available. However, the ability to
build the target file was deemed a breakthrough, and development of a new Miniport
for the IEEE-1394 cards was able to start.
54
5.5 Debugging
Device drivers, and thus NDIS miniports, require a very particular debug environment
due to the fact that they run at processor privilege level 0, or ring 0, within Windows.
Common debuggers, such as that which is integrated within Microsoft Visual C++,
whilst useful for debugging user applications, can not be used for debugging such
device drivers. Instead, a kernel-mode debugger is required, such as WDEB386 which
is included with the Windows95 DDK20 or the commercially available NuMega
SoftICE. This section describes the usage of these two packages, and provides an
appraisal that can be used where a choice has to be made. Proprietary techniques,
designed by the developer for use with the project, are also described.
5.5.1 Microsoft WDEB386
The Microsoft Windows System Debugger (WDEB386), can be used for debugging
any software running within the Windows operating system. That is, it can be used for
device drivers, dynamic link libraries (DLLs) and also applications. It is a very lowlevel debugger in that its command set is used to directly access hardware such as
memory, i/o ports and processor registers. It closely resembles the debug program
which was historically included with the MS-Dos operating system, and similarly,
tracing through programs is done at assembly language level rather than source code.
This complicates things somewhat, as it is very difficult to relate the assembly language
to the source code.
To debug a device driver, two computers are required; one acts as the test machine,
which is running WDEB386, Windows and the driver under development, whilst the
other is used for viewing the debugger output, and sending debug commands. The
connection between the two machines is via a null-modem cable, and both computers
will require a spare serial port. The machine which displays the debug output simply
requires a terminal package to be loaded, not necessarily within Windows, however
Windows contains the hypertrm package which is perfectly good for this use. The nullmodem cable does not require handshaking lines, and must simply be connected as in
Figure 5-11. The cable’s pin assignments are described in Table 5-2.
Figure 5-11 - Null-Modem Cable
Pin
Name
Receive
2
Transmit
3
Ground
5
Table 5-2 - Cable Connectors
55
The installation of WDEB386 also installs a number of VxDs, which replace some of
the standard Windows files with a debug version of the same file. These provide
support for debug functions which can be coded in driver source code, and also initiate
extended output of information at the terminal. Once this environment is installed,
debugging can proceed by executing WDEB386 instead of loading Windows as
normal. The booting of Windows should be interrupted, and WDEB386 should be
started in its place, which in turn will load Windows for you. In this way, the debugger
surrounds the operating system rather than loading the debugger from within
Windows. This is especially important considering device drivers are normally loaded
before Windows has finished the full boot process.
Since drivers can generally be coded in a high-level language, such as ‘C’, the
information provided by WDEB386 may not mean a great deal to most developers.
The developer usually will not know what the contents of certain processor registers
should be, and so on. To this end, making the best use of this environment requires
placing the following commands within the code:
•
•
Breakpoints
Debugger output strings
Breakpoints provide a point at which the debugger will regain control of the operating
system, and commands can be entered from the terminal. This is useful in getting
information on the flow of a driver, as strategically placed breakpoints can show you
exactly where your code is stumbling in the case of software that isn’t working.
Typical application debuggers allow you to step through your source code line by line
until a problem area is highlighted, however this is not possible without using one of
these two commands.
Debug output strings are usually far more useful than breakpoints, as contents of
variables, program flow and so on, can be output to the debug terminal. In this way the
terminal can be viewed for vital information while the driver is processing. An example
of terminal output using these strings might be:
MYDRIVER: Memory allocated successfully [2048 Bytes]
MYDRIVER: Reading serial number from device registers [12-34-56-78]
The two debug commands are provided by the debug-version NDIS wrapper driver,
and can be called using DbgBreakPoint() and DbgPrint() respectively. When
developing NDIS 4.0 Miniports for Windows95, however, due to the lack of an NDIS
4.0 driver debug version, alternative methods must be used, and simple workarounds
were written by the developer to aid in the debugging of this project. Breakpoints can
be implemented using assembly calls to int 3 or int 1, and VxD services can be used to
implement the debug output strings (see myDbgPrintf in Section 6.3.1). Both of these
alternatives are not allowable on the NT operating system, and thus the source code
should provide for different compilations depending on the target operating system.
This can be done using compiler commands such as:
#ifdef WIN95 /* W95 Specific Code */
#else /* WinNT Specific Code*/
56
5.5.2 SoftICE
This package is a very powerful alternative to WDEB386, and most notably, provides
source-level debugging. It loads in much the same way as WDEB386, as it must be
loaded before Windows and sits in the background. It can be loaded and used on one
machine, where a hot-key is used to switch between Windows and the debugger
window. Once in the debugger, the driver source code is displayed, and can be stepped
through as with most debuggers, and where the source code files are unavailable it
steps through at assembly level. The aforementioned breakpoint and output string
functions are available, and it is also possible to view the values stored in variables.
Since the source code and symbol files are loaded, it is easy to jump to a certain
function using
g functionName
where functionName is the name of your ‘C’ (or other) function. To do this in
WDEB386 would require that you know the actual address of the function.
5.5.3 Which Debugger to Use
Both debuggers are useful for different forms of testing. So called ‘white-box’ testing
where the code within functions is known and tested, is best implemented using
SoftICE as the code is available for display, and can be stepped through. ‘Black-box’
testing, however, may be easier using WDEB386, where the code is not known, but it
is simple to watch which functions are performing their job, without complicated stepthroughs. For more information regarding black and white box testing, see
Sommerville (1992)21.
Where the operating system used for debugging is Windows NT, there is a further tool
which replaces WDEB386, called WinDbg. It requires a serial link between two
machines, both of which must be running Windows NT. However, since the primary
target system for the miniport driver is Windows95 further discussion is outwith this
document, and can be found in the Windows NT DDK22. Note that for full driver
compatibility between operating systems, these tests must also be performed.
57
5.6 Project Planning
A time plan was prepared early on in the project23, which outlined the anticipated
stages of the project, and the dates by which they should be achieved. This had to be
revamped eventually, when the complexity of the project became more apparent. The
problem outlined in Section 5.3, regarding the undocumented compilation of an NDIS
driver for Windows95, required the postponement of the starting date of the coding,
however research was ongoing during this time, and it was used to design the low level
hardware control method. A new set of development stages were identified, as shown
below:
•
•
•
•
•
•
•
•
•
Development & successful compilation of a skeleton NDIS Miniport
Achievement of basic communication with and control of the TI hardware
Implementation of Plug and Play
Integration into Windows Control Panel & Network applet
Achievement of Self ID configuration
Transmission between 1394 nodes
Communication with protocol layer
MAC/1394 Translation table mechanism
Broadcast mechanism
During development and testing of the source code a version-numbering system was
used. Starting with v0.001, the version was incremented by 0.001 after every major
change. In addition, a ‘changes’ file was maintained to document the changes as well
as any bugs that were found during testing. The entire source code for each version
was archived, which proved very useful when changes introduced in earlier versions
began causing adverse affects. Changes, bugs and bug-fixes were also documented in
the project log book, accompanied by the relevant version number. Logging details in
this manner increased productivity, and the speed of source code development.
References
1
Mackenzie L. (1998), Communications and Networks, McGraw-Hill, p112
ISO/IEC 13213:1994, ANSI/IEEE Std 1212, 1994 Edition, Control and Status
Register (CSR) Architecture for Microcomputer Buses, ISO/IEC
3
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause
6.2.4.2.1
4
IEEE Project p1394a, Draft Specification for a High Performance Serial Bus
(Supplement), IEEE
5
Tanenbaum A. (1996), Computer Networks, 3rd Ed, Prentice-Hall London, pp420-3
6
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause
3.8
7
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause 8
8
Microsoft (1996), NT4 DDK: Network Drivers Design Guide 1.2.1, Microsoft
Corporation
2
58
9
Microsoft (1996), NT4 DDK: Network Drivers Design Guide Part 2: 1.5, Microsoft
Corporation
10
Buchanan W. (1997), Advanced Data Communications and Networks, Chapman &
Hall, pp447-8
11
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause
6.2
12
Johansson, P. (1999), Internet Draft: Ipv4 over IEEE 1394, IETF
13
Intel, Fundamentals of Ethernet Technology, Intel Certification Course FN2
14
Texas Instruments, 1394 Solutions CD-ROM, TI, filepath ‘hwsample\ic.c’
15
Texas Instruments (1998), Lynxsoft 1394 Software Application Programmer User’s
Guide- SLLU003 v2.2, TI, Chapter 6
16
ISO (1984), Basic Reference Model for Open Systems Interconnection, ISO:7498
17
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE, Clause 6
18
Goldman J. (1998), Applied Data Communications: A Business-Oriented Approach,
John Wiley & Sons, pp203-5
19
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI
20
Microsoft (1996), Windows 95 Device Driver Kit, Microsoft Corporation
21
Sommerville I. (1992), Software Engineering, Addison-Wesley
22
Microsoft (1996), Windows NT Version 4.0 Device Driver Kit, Microsoft
Corporation
23
1394 Project Logbook 1, p1
59
6. FORMAL DESIGN SPECIFICATION
This chapter describes the project source code in full. Due to the complexity of the
driver operations, all design requirements have been placed in the module
specifications, rather than supplement them with notes on the design process. It was
decided that notes on how memory allocations were decided and other low level design
decisions, would be best placed inside these specifications. Fundamental design issues
have been introduced already, however, in Chapter 5. A detailed specification of device
driver characteristics, such as data types and function calling conventions, has not been
included as there are so many considerations and these are common across all driver
projects. This chapter has to be supplemented with a study of the NT 4.0 DDK1 for a
full understanding.
6.1 Development Approach
Development of a new device driver does not proceed as normal application
development. A large amount of code has to be written before a driver will even load.
Thus initial development can be thought of as a rather blind process. In this instance
the developer had to thoroughly research the NDIS specification, and study the code
samples, before starting out with the new source code. After this, before any testing
could occur, a “complete” driver had to be developed. That is, one in which all of the
required exported functions were available, and a number of other issues were taken
care of. It is not possible to write one function, and go ahead and test it.
First, the source code, and driver, must contain every required NDIS export function.
These are listed in the module specification for this particular driver, however required
functions depend on the implementation. Consult the NT DDK1 for further details on
such functions. Although the function needs to be present, it does not necessarily have
to contain any code thankfully. As long as a basic driver structure is there, NDIS will
be willing to load the driver. Thus, source was developed which contained all of the
required functions, however, initially most of these contained no real code. Instead,
they merely displayed some output to the debugger, to notify the developer that they
had been called/entered.
The first function to be called on driver loading, and thus the function which was
attended to first, is the DriverEntry function. Secondly, the MiniportInitialize function
is called to allocate resources such as memory and interrupts, and to set up the 1394
hardware. Once these two functions contained code, and some information was written
for the ‘C’ include files, the driver was ready for initial testing. Testing, however,
cannot start until the driver is installed in Windows, a process which is described in
APPENDIX B.
Once the driver is installed in Windows, it can be tested by resetting the machine, and
loading Windows through one of the kernel debuggers described in Section 5.5. This is
a laborious process, as Windows must be reloaded after every change to the source.
Coupled with this, working at ring-0 gives privileged access to memory and resources,
and page faults or Windows protection errors are quite common-place, as well as
difficult to debug.
60
6.2 File Map
The source code is spread across a number of files. This is for tidiness, to prevent
unwieldy files, and to keep similar functionality within one source/object file. Table 6-1
describes the location of each function.
Filename
tilynx.c
Functions
DriverEntry
tilynxInitialize
tilnynxSetupAdapter
tilynxFreeResources
tilynxHalt
tilynxReset
tilynxCheckForHang
myDbgPrintf
cardInitialize
card.c
setupReceivePcls
linkPcls
tilynxSend
send.c
setupTransmitPcls
tilynxQueryInformation
oid.c
tilynxSetInformation
tilynxEnableInterrupt
interrup.c
tilynxDisableInterrupt
tilynxHandleInterrupt
tilynxIsr
tilynxTransferData
Table 6-1 - Project File-Map
61
6.3 Module Specification
This section contains the specification for each module contained in the project source
code. These have been designed and implemented by the developer, and the test results
can be found in Section 7.1. Each module has been implemented as a ‘C’ function. The
section is ordered as in the file-map shown in Table 6-1. All references to ‘tilynx’ or
‘Miniport’ in the specifications refer to the device driver, while the terms ‘adapter’,
‘device’ or ‘NIC’ refer to the Texas Instruments 1394 PCILynx hardware. NDIS
export functions that are named ‘MiniportXxxx’ in the NT DDK, are named
‘tilynxXxxx’ here.
Due to the amount of source code (170 Kbytes), it has not been included in the
Appendices, and has instead been placed on the companion CD-ROM, as has an
archive of previous versions. The hardware specifications are also on this CD-ROM,
and it will be necessary to reference these to fully understand the source code. Full
details of the CD-ROM are in APPENDIX D. All source files and functions have
header files to explain the functionality they perform in simple terms. Also the source is
commented throughout to help the reader gain an understanding.
The format of the module specifications is shown in Table 6-2.
Name
Source
Parameters
Title of function
Source file location
Passed parameters. Preceded by ‘IN’ or ‘OUT’, which are not part of
the parameter names.
‘IN’ refers to variables that are passed but not changed.
‘OUT’ refers to parameters that are passed as pointers, and can be
changed. (For returning data to the calling function).
Return Value
Call Type
Variable types are not included, in order to reduce the complexity
herein. They can easily be found in the source code, or in the NT
DDK for NDIS exports.
Value passed back by ‘return’ statement.
None refers to a void return declaration.
NDIS Export: Required by and called by NDIS. These are never
called by another function within the Miniport – they exist entirely
autonomously, and communicate only with the NDIS wrapper.
Internal Function: Specified by developer, called internally to driver.
Detailed description of the functionality that must be performed by
Description
this function. It should be possible to read this and go on to write the
function. This can also be used to supplement the source code, to aid
understanding.
Table 6-2 - Module Specification Format
62
6.3.1 tilynx.c
Name
Source
Parameters
Return Value
Call Type
Description
DriverEntry
tilynx.c
IN: DriverObject – Created by the system
IN: RegistryPath – Path to parameters for this driver
Returns the status of the operation (successful/unsuccessful)
NDIS Export
This is the primary initialisation routine for the TILynx driver. It is
simply responsible for initialising the wrapper and registering the
Miniport driver. All device drivers require this function, in order that
they can be loaded in Windows. It is run only once, during initialisation.
The wrapper is initialised by passing the two input variables
(DriverObject & RegistryPath) in a call to NdisMInitializeWrapper.
This returns a handle, which is used to refer to this driver when
communicating with the wrapper (NDIS). Once the wrapper has been
notified in this manner, it will look out for the miniport driver to
register itself using NdisMRegisterMiniport.
Before calling NdisMRegisterMiniport, the DriverEntry function must
fill in an NDIS_MINIPORT_CHARACTERISTICS structure. This
structure is used to notify the NDIS library/wrapper of the miniport’s
characteristics, such as the version of NDIS which it supports (v4.0),
and the names of its NDIS-exported functions. In this way, the
miniport’s functions may have any name, for example its Send function
can be named tilynxSend, mySend or any unused name, as long as it is
registered with NDIS. The names of all TILynx functions are entirely
described by this design specification.
This characteristics structure can be declared on the stack, because
NDIS copies the information in the call to NdisMRegisterMiniport, and
stores it in its own storage area.
Where either of these two calls fail, DriverEntry returns
STATUS_UNSUCCESSFUL, otherwise STATUS_SUCCESS is
returned.
63
Name
Source
Parameters
Return Value
Call Type
Description
tilynxInitialize
tilynx.c
OUT: OpenErrorStatus - Extra status bytes for token ring adapters.
OUT: SelectedMediumIndex - Index of the media type chosen.
IN: MediumArray - Array of media types for the driver to choose from.
IN: MediumArraySize - Number of entries in the array.
IN: MiniportAdapterHandle - Handle for passing to the wrapper when
referring to this adapter.
IN: ConfigurationHandle - A handle to pass to NdisOpenConfiguration.
Status of the operation
NDIS Export
This is the MiniportInitialize function of the driver. It is a required
function that sets up the NIC hardware (Texas Instruments PCI card)
for operation, claims hardware resources in the registry, and allocates
resources such as memory, and an interrupt line.
First select the network medium which this driver supports. An array of
possible choices is passed in the MediumArray parameter. This array
should be searched to find the index for Ethernet (NdisMedium802_3),
and SelectedMediumIndex is set to point to the index value in
MediumArray. If Ethernet is not passed as a valid choice (i.e. not
contained within MediumArray), then tilynxInitialize should return
NDIS_STATUS_UNSUPPORTED_MEDIA.
Memory for the adapter descriptor block should be allocated in nonshared, virtual memory. This descriptor block is defined in tilynxsw.h as
a structure of type TILYNX_ADAPTER, and stores information
required by the driver. Allocation of memory is done using the
NdisAllocateMemory library call. The amount of memory to allocate is
equal to the size of a TILYNX_ADAPTER structure. This memory
should be zeroed, using NdisZeroMemory. (Allocated memory initially
contains indeterminate bit-values).
NdisOpenConfiguration is used to obtain a handle to the NIC’s
parameters in the Windows registry. This handle can then be used by
NdisReadConfiguration and NdisReadNetworkAddress to read values
from the registry.
The Ethernet MAC address should be read from the registry using
NdisReadNetworkAddress. This searches the stored parameters for the
keyword “NetworkAddress”. The actual value is stored as a string. For
example, the MAC address 1A-1A-1A-1A-1A-1A. would be stored as
string value “1A1A1A1A1A1A”, not as a numerical value. Once the
address has been read, it is stored in the adapter block, for later use.
The registry reference where this information is stored is
HKLM\System\CurrentControlSet\Services\Class\Net\xxxx\NetworkAdd
ress, where xxxx is a 4-digit number used to reference a particular NIC.
64
Next, NdisMSetAttributes must be called to inform the NDIS
library/wrapper about significant features of the NIC. Specifically NDIS
must know that the NIC is a Busmaster DMA device, and that it is a
PCI device. NdisMSetAttributes must be called before a number of
other library functions, otherwise they will fail, including:
•
•
•
•
•
•
NdisMPciAssignResources
NdisMAllocateMapRegisters
NdisMAllocateSharedMemory
NdisMMapIoSpace
Ndis…RegisterXxx (e.g. NdisReadRegisterUlong)
NdisMRegisterInterrupt
Following NdisMSetAttributes, if the miniport is running on Windows
NT4.0, the PCI slot in which the NIC is placed must be determined. If
the system is Windows 95/98, then the operating system’s Plug and
Play capabilities take care of this for you. Therefore where the miniport
is used in NT, the slot number must be stored in the registry (on
installation), and this can be read using NdisReadConfiguration.
The slot number information is then passed as a parameter in a call to
NdisMPciAssignResources. This library function returns the adapter’s
bus relative resources, in a structure of type NDIS_RESOURCE_LIST,
which is a typedef of the CM_PARTIAL_RESOURCE_LIST structure
type. Information on this structure type can be found in the DDK
include file, NTDDK.H.
The actual information which is needed for allocating resources is the
interrupt number (IRQ) and the base addresses of the device memory.
These are identified in the structure by type values of:
•
•
cmResourceTypeInterrupt
cmResourceTypeMemory
Three memory base addresses should be returned, with their lengths.
These refer to the three register areas on the device as described in the
PCILynx specification2. The memory and interrupt information should
then be stored in the adapter descriptor block (TILYNX_ADAPTER
structure), to be used later in allocating local resources.
Note that where the environment is Windows 95/98, the slot number
parameter is ignored in the call to NdisMPciAssignResources. If the
driver is run in these environments, the parameter is set to –1, a
nonsense value. Instead, each PCI slot is probed until the NIC is found.
The information used to identify the correct card and slot is taken from
the registry value “AdapterCFID”. This is a vendor-assigned device
identification, concatenated with a PCISIG-assigned vendor ID.
65
This should be stored in the registry during installation, as string value
“8000104C” for the project PCILynx devices. This probing feature is
undocumented in the NT4.0 DDK, which does not list the slot number
parameter as optional.
All of the required registry information has now been read, and the
registry should be closed using NdisCloseConfiguration. This library
function has only one parameter, the handle returned by
NdisOpenConfiguration.
Lastly, the internal function, tilynxSetupAdapter must be called, to
complete the initialisation process. This function allocates the necessary
memory, registers the interrupt and performs hardware writes to set up
the NIC for operation. The initialise process has thus been split up into
tilynxInitialize and tilynxSetupAdapter in order that tilynxInitialize is
not unwieldy. Refer to the tilynxSetupAdapter module specification for
a full description of this function.
If any errors were reported during tilynxInitialize, tilynxFreeResources
is called to free up any allocations (such as the memory for the adapter
descriptor block), and tilynxInitialize returns
NDIS_STATUS_FAILURE. This is also the case if tilynxSetupAdapter
does not return NDIS_STATUS_SUCCESS. This provides a mechanism
for cleanly unloading the driver when it is having problems loading.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxSetupAdapter
tilynx.c
IN: Adapter – Pointer to the TILYNX_ADAPTER descriptor block.
Status of the operation
Internal Function
Called during driver loading/initialisation to allocate shared memory for
transfers, register the interrupt, and start the card. Also maps the NIC’s
register memory space into local virtual addresses.
Specifically:
• Maps the NIC's registers to a mem-space so that it can be
programmed & read.
• Allocates map registers so that send-buffers can be mapped to
shared memory, which the card is able to access.
• Allocates shared memory for received data from card.
• Allocates shared memory for the transmit staging buffer.
• Allocates memory for the transmit & receive PCLs.
• Allocates memory for the dummy transmit & receive PCLs.
• Registers the interrupt with the wrapper (NDIS library)
• Initializes the card by writing to its registers.
• Sets up the receive PCLs and buffer space, and links these to a
DMA channel so that receives may begin.
66
NdisMMapIoSpace is used to map the NIC’s registers to a virtual
memory range. Only Base Address 0 of the NIC needs to be mapped,
because this refers to the internal registers. This is the first address
range that will be returned by NdisMPciAssignResources and is thus
stored as index 0 in the mem range array in the adapter block.
(Adapter->MemBaseAddress[0]). The other two ranges returned refer
to registers for programming local bus resources (local RAM, AUX and
ZOOM Video), and these are currently not used by the miniport, so do
not need to be mapped. NdisMMapIoSpace returns a pointer to a base
virtual address, which can be used when this memory space needs to be
accessed. To access an offset within this mapped range, the offset is
simply added to the base virtual address.
Next some map registers are allocated. These are used to map buffers
passed to the miniport’s send function into physical addresses. Send
buffers are passed down from the protocol drivers, but only exist in
virtual memory. Thus, map registers are used to store the virtual to
physical mappings. To actually start a mapping, NDIS function
NdisMStartBufferPhysicalMapping is used. If each buffer is to
constitute one packet, then we need enough registers to map the
maximum number of packets. This is equal to the maximum number of
transmit PCLs. NdisMAllocateMapRegisters is used to allocate these
registers. The parameters to be passed to it are:
1. Handle of the adapter (in adapter block)
2. ‘0’ for Non-ISA bus.
3. TRUE for 32-bit DMA operations
4. Number of map registers needed (MAX_XMIT_PCLS)
5. Max size of a mapping (TILYNX_MAX_PACKET_SIZE)
Next shared memory is allocated for the receive & transmit buffers.
These must be in shared memory so that they have physical addresses,
which are downloadable to the card. The NIC cannot understand/access
virtual addresses. For receives, the DMA copies the received data
straight into the receive buffer, and for transmits the data to be sent is
placed into the transmit buffer.
Each packet is stored in this memory in stages of
MAX_TILYNX_PACKET_SIZE, thus a packet will never overflow into
the next packet’s buffer space. Thus to reference the beginning of each
packet or PCL, we add an offset to the base physical address:
Adapter->ReceiveMemPhysical + (PCLNum *
TILYNX_MAX_PACKET_SIZE)
For example to access PCL 0:
Adapter->ReceiveMemPhysical+ (0*TILYNX_MAX_PACKET_SIZE)
Shared memory is allocated using NdisMAllocateSharedMemory,
passing the variable names where you wish the virtual & physical
addresses to be stored. The size of the buffer should be
67
TILYNX_MAX_PACKET_SIZE * MAX_XMIT_PCLS for the transmit
buffer, and TILYNX_MAX_PACKET_SIZE * MAX_RECV_PCLS for
the receive buffer. Memory should be allocated in cached memory since
non-cached memory is a scarce system resource, and is less likely to be
available.
Next shared memory is allocated for the transmit & receive PCL
structures. These must also be stored in shared memory, because they
are accessed by the NIC. The same library function,
NdisMAllocateSharedMemory, is used, and this is called once for each
PCL. Thus it is called MAX_XMIT_PCLS times for the transmit PCLs,
and MAX_RECV_PCLS times for the receive PCLs. The size of each
allocation is always the size of a PCL structure, which is obtained using
sizeof(PCL_S).
The virtual, physical and buffer addresses for each PCL are stored in an
array of PCL_LIST_S structures, defined in tilynxsw.h. There is one
array for the receive PCLs, and one for the transmit PCLs.
As well as allocating memory for these PCL structures, shared memory
must be allocated for the dummy PCLs used to start a PCL queue. Thus
two more memory ranges are allocated, for the transmit and receive
dummy PCLs, each of size (sizeof(PCL_S)).
Next the interrupt is registered with Windows. The previous call to
NdisMPciAssignResources during tilynxInitialize returns the
information on the IRQ number, and this can be used in a call to NDIS
library function NdisMRegisterInterrupt. The parameters passed are:
1. Pointer to an NDIS_MINIPORT structure for returned information.
2. Interrupt vector (IRQ number).
3. Interrupt level (should be the same as 2.
4. Shared interrupt with another device = FALSE
5. RequestISR = FALSE
6. InterruptMode = NdisInterruptLatched
RequestISR is set to false, to notify the wrapper (NDIS) that the
miniport’s HandleInterrupt function should be called on an interrupt,
not the Isr function. An Isr function must still be exported by the driver,
as this is called if an interrupt occurs during Initialize.
InterruptMode is set such that interrupts are triggered by a transition
from low to high on the interrupt line.
Lastly, the miniport’s cardInitialize is called. This performs some writes
to the hardware to control its operation, and set it up ready to receive
and send data. It sets up the receive PCLs to receive data, via a call to
another internal function. For a complete description of cardInitialize,
see Section 6.3.2.
All memory allocated within tilynxSetupAdapter is zeroed using
68
NdisZeroMemory, since on allocation the memory will contain
indeterminate data.
If there was a problem at any point during tilynxSetupAdapter,
NDIS_STATUS_FAILURE is returned to the calling function, which
should free up any resources allocated by this function. Otherwise
NDIS_STATUS_SUCCESS is returned.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxFreeResources
tilynx.c
IN: Adapter – Pointer to the TILYNX_ADAPTER descriptor block.
None.
Internal Function
Frees all resources that have been allocated for use by the adapter.
This is called internally by other driver functions, when there has been
an error in loading the miniport, and all resources must be deallocated
for use by other system applications or drivers.
It is also called when the miniport is to be unloaded, for example on
system shutdown.
First all normal allocations are checked, in case they have not been
allocated yet. It they have not been allocated, then they need not be
deallocated, and a call to free the resource will have uncertain
consequences. This is a safety mechanism, in case this function is called
early in the initialisation sequence, in which case not all resources will
have been allocated yet.
Note that the order of deallocation is designed such that later
allocations are freed first. This is because later allocations may depend
on earlier allocations.
There follows a list of all resources which are allocated during normal
driver operation (latest first):
•
•
•
•
•
•
•
•
•
•
Receive memory buffer: Adapter->ReceiveMemVirtual
Transmit memory buffer: Adapter->TransmitMemVirtual
Dummy Receive PCL mem: Adapter->DummyReceivePclVirtual
Dummy Transmit PCL mem: Adapter->DummyTransmitPclVirtual
Transmit PCLs mem: Adapter->TransmitPclList[]
Receive PCLs mem: Adapter->ReceivePclList[]
Interrupt (IRQ): Adapter->Interrupt
Map registers
Mapped IO Space for NIC registers: Adapter->tilynxRegisters
Adapter descriptor block mem: Adapter (Not shared)
NDIS library functions which are available for freeing resources are:
69
•
•
•
•
•
Name
Source
Parameters
Return Value
Call Type
Description
NdisMFreeSharedMemory – for freeing the memory shared by the
miniport and the hardware.
NdisMDeregisterInterrupt – for deregistering the interrupt
associated with the device.
NdisMFreeMapRegisters – for freeing the map registers used to
map virtual to physical memory.
NdisMUnmapIoSpace – for unmapping the IO space used to map
device memory to system virtual memory.
NdisFreeMemory – for freeing any memory which was allocated,
but not shared with the device.
tilynxHalt
tilynx.c
IN: MiniportAdapterContext – Handle of Adapter descriptor block
None.
NDIS Export
This function is called by NDIS when the driver is being removed,
usually on system shutdown. It should stop the card and free all
resources allocated during initialisation.
The card can be stopped by blocking any interrupts, and stopping any
received data:
•
•
Call the compiler macro cardBlockInterrupts.
Stop receives by writing an invalid address to the receive DMA
(Channel 0) current PCL register. This can be accomplished using
the compiler macro TILYNX_WRITE_REG. An invalid address is
any number with a 1 in the LSB (Least Significant Bit).
The freeing of resources is done using a call to the tilynxFreeResources
function. The use of one function for all freeing of resources makes the
code more readable, and more adaptable to changes in the allocated
resources.
No status is returned by this function.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxReset
tilynx.c
OUT: AddressingReset – If SetInformation should be redone
IN: MiniportAdapterContext – Handle of Adapter descriptor block
Status of operation
NDIS Export
Is called by NDIS if it thinks the hardware has hung.
Simply performs a software reset by writing to the
MPCI_MISCTRL_REG register.
70
AddressingReset can be ignored, as the reset does not upset the card’s
configuration.
Always returns NDIS_STATUS_SUCCESS.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxCheckForHang
tilynx.c
IN: MiniportAdapterContext – Handle of Adapter descriptor block
Boolean.
NDIS Export
Is called by NDIS to check that the device has not stopped/hung.
In this implementation, the device should not hang. Therefore, always
returns FALSE (Device hasn’t hung).
Name
Source
Parameters
Return Value
Call Type
Description
myDbgPrintf
tilynx.c
Same format as printf (IN: *pszfmt)
None.
Internal Function
Outputs information to the debug terminal.
There is no debug NDIS 4.0 subsystem (NDIS.VXD), therefore the
usual DbgPrint function is not supported when developing NDIS 4.0
Miniports for Windows95. If the target system is Windows NT,
DbgPrint is supported as usual. This function should use a normal
DbgPrint call for NT Miniports, and for Windows95, should use VxD
wrapper services for the debug output. There must be a distinction
because NT will crash if a call to VxD wrapper services is made.
For NT, the following code can be used:
__asm jmp DbgPrint
For Windows95:
__asm jmp LCODE__Debug_Printf_Service
LCODE__Debug_Printf_service is the Windows95 native DbgPrint
function, and is provided in library VXDWRAPS.CLB, of the
Windows95 DDK. Thus this file must be linked during the build
process.
71
6.3.2 card.c
Name
Source
Parameters
Return Value
Call Type
Description
cardInitialize
card.c
IN: Adapter - Pointer to the TILYNX_ADAPTER block
Status – Status of operation
Internal Function
This is called during tilynxInitialize, to perform configuration of the
hardware. Configuration is achieved by writing to the register-space of
the PCILynx chip.
The register-space should already have been mapped to a virtual
address space, using NdisMMapIoSpace. The NDIS library provides
the following functions for reading and writing this mapped space:
•
•
NdisReadRegisterXxxxx
NdisWriteRegisterXxxxx
Where ‘Xxxx’ can be ‘Ushort’, ‘Uchar’ or ‘Ulong’, depending on the
amount of memory to access. The PCILynx chip registers are stored in
contiguous 4-byte (quadlet) stages, which on the target system equate
to a Ulong. The compiler macros TILYNX_READ_REG and
TILYNX_WRITE_REG were written to simplify the call to these
register functions, and these can be found in the source include file
tilynxhw.h.
The offsets of each register from the base address, are defined with
compiler ‘#define’ statements in tilynxhw.h, and these names are used
here in italics to identify each register. The values that must be written
to these registers are also defined in tilynxhw.h, to simplify the code.
Precise definitions of each register, and its function, can be found in the
PCILynx specification. This should be used in conjunction with this
module specification to determine the actual bits to be set in each
register.
The following hardware configuration must be performed during
cardInitialize:
Perform a PCI software reset, by writing to the PCI Miscellaneous
Control register (MPCI_MISCTRL_REG).
Set the FIFO sizes by writing to the FIFO_SIZES register. This divides
the 256-quadlet buffer into ATF/ITF/GRF. No isochronous
functionality is required, thus we should split the FIFO equally between
ATF and GRF.
• ATF = 128 quadlets
• GRF = 128 quadlets
• ITF = 0 quadlets
72
Set the transmit FIFO thresholds by writing to the
FIFO_XMT_THRESHOLD register. The DMA will not start
processing until this amount of data has been written to one of the
transmit FIFOs.
• ATF = 32 quadlets (this can be tweaked as required)
• ITF = 256 quadlets (this threshold will never be reached)
Reset the overrun/underrun counters for ATF/ITF/GRF by writing all
zeroes to the LLC_FIFO_OVRFL register. These will be incremented
when overruns or underruns occur.
Check the PCILynx revision ID by reading from MPCI_REV_ID_REG
in the PCI configuration space. If the revision is below revision A
(<0x02), some extra bits must be set in MPCI_MISCTRL_REG. This is
documented in the PCILynx specification3 which states that PCI slave
posted writes and PCI slave burst should be enabled to ensure PCI Spec
2.1 compliance.
Set up PCLs, DMA and memory to receive data from the 1394 bus.
Due to the complexity of this function, and so that it may be reused
outside of initialisation, this code has been placed in a separate function,
setupReceivePcls. It should be passed the receive type as a parameter
(PKT_RCV or PKT_RCV_AND_UPDATE). Extra flags can also be
passed, for example to implement a circular PCL queue, however this is
not required, and has been provided for future implementations.
The card interrupts should be enabled, and this is accomplished using
the compiler macro cardUnblockInterrupts. This has been implemented
as a macro because this will happen in many places of the code during
driver operation. Therefore, if a different interrupt mask is required, it
would only need to be changed in one place.
Set retry count to 5 and retry delay to 0 Iso Intervals. This is achieved
by writing 0x0005 to the DMA_BUSY_RETRY register. Note, to have a
retry delay other than zero, a cycle timer must be present on the bus,
which is not the case for this implementation, as it is used for
isochronous functionality.
Next the 1394 Bus/Physical IDs must be determined and written to the
card. These are discovered by forcing a bus reset (Compiler macro
BusReset), and reading the physical ID from PHY register 0, written
during the self ID process. Must wait 400 micro-seconds between the
bus reset and the reading of PHY0, which can be achieved using
NdisMSleep(400). To read the physical registers, write to
LLC_PHY_REGS with the address wished to read (0) and the READ
bit, then read LLC_PHY_REGS. Store the physical ID in the adapter
descriptor block, and force bus ID = 0. Finally, the 16-bit ID must be
written to LLC_NODE_ADDR.
73
Set the LLC_CONTROL register to enable asynchronous transmits and
receives. The RCV_COMP_VALID bit should also be set, which
enables the reception of packets. This bit ensures that the 1394
Bus/Physical node ID matches the destination of the incoming packet,
and also uses the receive comparators to establish whether a received
packet should be accepted. By not setting the isochronous
transmit/receive bits, isochronous transfer is disallowed. It is also
important to note that the asynchronous transmit/receive bits are reset
to 0 on a bus- reset, thus the interrupt handlers should set these bits
again.
This completes the hardware configuration, and the card should now be
ready to receive data. It is also ready for a queue of transmit PCLs to
be linked to a DMA channel and sent.
At present NDIS_STATUS_SUCCESS is always returned, however a
status return has been implemented to provide for future code where
fails may be possible. This is specifically provided for the
setupReceivePcls call, since writing to register space never returns a
fail.
Name
Source
Parameters
Return Value
Call Type
Description
setupReceivePcls
card.c
IN: Adapter – Pointer to the TILYNX_ADAPTER block
IN: Command – PKT_RCV or PKT_RCV_AND_UPDATE
IN: flags – For example to create a circular PCL queue
None.
Internal Function
Sets up the DMA Asynchronous receive buffers:
Constructs PCLs to receive asynchronous packets into a ring of
memory buffers, each of size TILYNX_MAX_PACKET_SIZE. After
each packet is received into a buffer, the PCL generates an interrupt so
that tilynxHandleInterrupt can be called to process the received packet.
The DMA channel to be used for receives is fixed as channel 0. No
other channels can be used for asynchronous transfer due to
complications with 1394 bus retries4.
The number of PCLS in the queue should equal MAX_RECV_PCLS (a
global define in tilynxsw.h). Thus each PCL in this queue must be set up
to contain the correct bits set in its structure. PCLs are defined by the
structure type PCL_S, also defined in tilynxsw.h. The queue should
start with a dummy PCL, which only contains information in its
nextPCL and errorPCL fields. All other fields are ignored, and the
DMA moves straight onto the PCL at address stored in nextPCL. The
last PCL in the queue should have an invalid address stored in its
74
nextPCL/errorPCL fields, unless a circular queue is required. An invalid
address is an address containing a 1 in the LSB.
Precise definitions of each bit in the PCL structure can be found in the
PCILynx specification4.
The following field values must be set in the PCLs. All other bits should
be set to zero.
Data Buffer0 Control & Byte Count Quadlet:
transferCount = TILYNX_MAX_PACKET_SIZE – This sets the size
of the available receive buffer for each PCL.
isochronousMode = 0 – Asynchronous on this channel
multipleIsochronous = 0 – Not required (isochronous only)
transmitSpeed = 0 – Not required (transmits only)
bigEndian = 1 – Send buffer in Big Endian (for 1394 Bus compatibility)
waitForStatus = 0 – Pipeline transmits to improve throughput
lastBuffer = 1 – This is the last buffer of the PCL (no Buffer1+)
doneInterrupt = 1 – Generate an interrupt when DMA completes PCL
waitSelect = 0 – No wait: continue execution
command = Command – Passed as a parameter (PKT_RCV/UPDATE)
Data Buffer0 Address:
Set to the physical address into which packets should be received
If the flags passed contains CHAN_CIRCULAR, point
nextPCL/errorPCL of the last one in the queue, back to the first PCL.
Once the dummy PCL has been set to point to the first PCL in the
queue, the physical address of the dummy can be passed to the linkPcls
function, in order to link the queue to the DMA channel.
After linkPcls has been called, the function exits (with no return status).
Name
Source
Parameters
Return Value
Call Type
Description
linkPcls
card.c
IN: Adapter – Pointer to TILYNX_ADAPTER block
IN: Command – PKT_XMT/PKT_RCV/PKT_RCV_AND_UPDATE
IN: dummyPhysicalAddress – First PCL in queue (dummy)
IN: dmaChannel – DMA Channel to link the PCL queue to
None.
Internal Function
Will take a completed PCL chain and link it to a DMA channel.
Provision has been made for choosing the channel, however by design,
all asynchronous transfers are to be linked to channel 0, due to
limitations of the card. This fourth parameter should allow for future
implementations of isochronous traffic.
75
The PCL chain must have been allocated in physical memory. The chain
must have a dummy PCL packet that is used to point to the actual PCL
chain that will be used to transfer the packets to memory.
DMA waits for a valid PCL pointer to be written to the Current Packet
Control List Address register, and for the CHA_ENA and LINK bits to
be set in DMA control reg. Note: A valid address means a 0 in bit 0.
The address written is the dummyPhysicalAddress parameter, which
should already be a valid value. All PCLs in the queue must have valid
netPCL addresses except for the last PCL if that is to halt DMA
processing.
Given a valid PCL address, the DMA looks at it and fetches the nextPcl
address from this PCL. That is because this first PCL is just a dummy
PCL, as described in the PCILynx specification5. The DMA makes this
nextPcl address the current PCL address, and begins execution.
If the address is invalid, the DMA is halted and the LINK & BUSY bits
are cleared in DMA status register. A DMA Halted Interrupt is then
generated and the channel becomes inactive.
This function tests the Command parameter, to check if this PCL queue
is for PKT_XMT, PKT_RCV or PKT_RCV_AND_UPDATE. Both
receive types are the same code, they are differentiated by the command
values in the PCL queue.
If PKT_XMT:
Write the physical address of the first PCL in the queue (Dummy) into
the DMA 0 current PCL register, DMA_CHAN_0_CURR_PCL.
Set the CHA_ENA and LINK bits in the DMA Channel 0 Control
register, DMA_CHAN_0_CTRL. The rest of this register is read-only
and will be updated to contain the commands etc in the PCL.
Flush the ATF (Asynchronous Transmit FIFO), in case the data has not
reached the ATF threshold. This can be removed if the packets are
known to be frequent or large enough. This is achieved by writing to
the FIFO_TEST register.
After the queue has been transmitted, if the last PCL is to halt
processing, the channel will be hung and CHA_ENA and LINK must be
re-set in the DMA Control register, if the channel is to be used again.
This completes the transmit code.
PKT_RCV or PKT_RCV_AND_UPDATE:
For receives the dummy physical address must be set as for PKT_XMT,
76
and the channel must also be enabled. However, the receive
comparators should also be set before the channel is enabled. This sets
up a system to accept or decline received packets, based on certain
fields in the header. Each DMA channel has two comparators, each of
which has a value register and a mask. The mask is used to determine
how many bits of the value register are to be checked.
Write the 1394 Bus/Physical Ids to the DMA channel 0 Word 0 Value
register, DMA_CHAN_0_WORD0_VALU. The Bus & Physical IDs are
stored in the adapter descriptor block after the self ID process.
Write to the DMA0 Word0 Mask register,
DMA_CHAN_0_WORD0_MASK. This should be set to check all bits of
the Bus and Physical ID. It should also be set to check that received
packets have an asynchronous transaction code. This mask can be
achieved by setting bits 0xFFFF00A0.
Set DMA0 Word1 Value register, DMA_CHAN_0_WORD1_VALU, to
not compare the source ID on incoming packets. This is achieved by
writing all zeroes.
Write to the DMA0 Word1 Mask register,
DMA_CHAN_0_WORD1_MASK, to enable the channel, send
acknowledgements, match broadcast etc and accept self-ID packets.
These bits are defined in tilynxhw.h and can be OR’ed together to
achieve the value to be written to the register:
CMP_W1_ENA_CH_COMPARE – Enable the channel for receives.
WRITE_REQ_ACK_SEL – Send acknowledgements on a receive.
MATCH_BUS_AND_NODE – Accept packets with correct 1394 ID.
MATCH_3FF_AND_NODE – Accept Local Bus, correct physical ID.
MATCH_BUS_AND_3F – Accept correct bus, Broadcast physical ID.
MATCH_BROADCAST – Accept Local Bus, Broadcast physical ID.
Don’t set SELF_ID_ENA, as this enables the catching of self ID
packets, and reception into PCLs. Instead, the self ID information
should be read from the PHY registers after a bus reset.
This completes the receive code.
77
6.3.3 send.c
Name
Source
Parameters
Return Value
Call Type
Description
tilynxSend
send.c
IN: MiniportAdapterContext – Handle of Adapter descriptor block
IN: Packet – Packet descriptor for frame to be sent
IN: Flags – Optional
Status of operation.
NDIS Export
This is called by NDIS to send a packet on the 1394 bus.
As required by design, it must (basically):
•
•
•
•
•
Check destination MAC address of frame passed to it.
Translate MAC to 1394 ID (using lookup table)
Build a 1394 block payload packet header.
Copy the passed frame/buffer after the header.
Pass to setupTransmitPcls.
NdisQueryPacket is used to find the first buffer descriptor contained by
the packet. NdisQueryBuffer is then used to find the (virtual) address
and length of this buffer.
A 1394 async write block payload packet header is created at the
beginning of the transmit memory. This should be set with the source
ID, correct transaction code for block writes (1), no destination offset.
The data length field should be set to the buffer length returned by
NdisQueryBuffer (length of the frame to be sent).
The buffer to be sent should then be copied into the transmit memory,
directly after the 1394 packet header. The starting address of the buffer
has been returned by NdisQueryBuffer.
The destination 1394 ID must now be set in the packet header. This
must be obtained by translating the buffer’s destination MAC address to
a 1394 ID. The destination MAC is found in the first 6 bytes of the
buffer. tilynxSend then uses this to lookup the translation table, stored
in its Adapter descriptor block, as required by the design.
Next, the shared memory should be updated with
NdisUpdateSharedMemory, to make sure it is current when copied by
the hardware.
Finally, setupTransmitPcls is called, passing the address of the transmit
staging buffer, as well as the length of the buffer (equal to the 1394
header length + the frame length).
Note that if the destination MAC contains a binary 1 in all 32 bits (hex
78
FF:FF:FF:FF:FF:FF), this is a broadcast transmission, and thus
tilynxSend should copy the same packet to all nodes in its lookup table.
If the lookup table has not been built (unlikely as this happens very
quickly), it should use the self ID information it has received.
Only returns NDIS_STATUS_SUCCESS.
Name
Source
Parameters
Return Value
Call Type
Description
setupTransmitPcls
send.c
IN: Adapter – Pointer to the TILYNX_ADAPTER block
IN: BufferLength – Length of buffer to be sent
IN: BufferPhysicalAddress – Physical address of transmit buffer
None.
Internal Function
Take a passed buffer to be transmitted, and construct a PCL queue to
link to a DMA channel. The buffer should be correctly formatted as a
1394/FIFO packet with header and payload.
For now only single-packet sends are implemented, thus only one PCL
is necessary in the queue (as well as a dummy). If multiple-packet sends
are required, the code can easily be changed to reflect the way
setupReceivePcls works.
Precise definitions of each bit in the PCL structure can be found in the
PCILynx specification4. The following field values should be set in the
PCLs. All other bits should be zero.
Dummy PCL layout:
nextPCL = errorPCL = (Physical address of first PCL in queue)
All other bits are ignored.
PCL0 layout:
nextPCL = errorPCL = (Invalid address e.g. 0x1)
Data Buffer0 Control & Byte Count Quadlet:
transferCount = BufferLength – Passed as a parameter
isochronousMode = 0 – Asynchronous for this channel/PCL
multipleIsochronous = 0 - Can be anything, isochronous only
transmitSpeed = 1 - Transmit speed, 1=200Mbps/S200
bigEndian = 1 – Big Endian for 1394 Bus compatibility
waitForStatus = 0 - Don't wait: pipeline asynchronous transmits
lastBuffer = 1 – This is the last buffer
doneInterrupt = 1 - Post an interrupt when status is completed for PCL
waitSelect = 0 – Don't wait to continue execution of PCL
command = 2 - Binary:0010 = Command: XMT memory to 1394 FIFO
Data Buffer0 Address:
Physical address of the data buffer (BufferPhysicalAddress was passed
79
as a parameter).
Once the dummy and transmit PCLs are constructed, they are in a
queue:
Dummy->PCL0->Halt Processing.
The dummy PCL should now be linked to a DMA channel. Design
requires that channel 0 be used, thus linkPcls is called, passing
PKT_XMT as the command, with channel=0 and passing the physical
address of the dummy PCL.
After linkPcls finishes, the function is complete and no status needs to
be returned.
6.3.4 oid.c
Name
Source
Parameters
Return Value
Call Type
Description
tilynxQueryInformation
oid.c
IN: MiniportAdapterContext - Handle of Adapter descriptor block
IN: Oid – The NDIS_OID to process
IN: InformationBuffer – Stores result of the query
IN: InformationBufferLength – Number of bytes left in buffer
OUT: BytesWritten – Number of bytes written to InformationBuffer
OUT: BytesNeeded – Contains bytes needed if not enough room in
InformationBuffer
Status of operation
NDIS Export
Is called by NDIS/protocols to query the OID (Object Identifier)
information relative to the adapter. This information includes such
details as the MAC address, media type, maximum number of packets
support at once etc.
Algorithm:
• switch(oid)
• get requested information
• copy into buffer
• if not enough room in buffer, request a larger buffer
Supported OIDs, which must be ready for querying, and the results they
should return, are:
OID_GEN_MAC_OPTIONS
= “ndis_mac_option_transfers_not_pend |
ndis_mac_option_receive_serialized |
ndis_mac_option_copy_lookahead_data |
ndis_mac_option_no_loopback)
80
OID_GEN_SUPPORTED_LIST
= List of supported OIDs
OID_GEN_HARDWARE_STATUS
= NdisHardwareStatusReady
OID_GEN_MEDIA_SUPPORTED
= OID_GEN_MEDIA_IN_USE
= Ethernet
OID_GEN_MAXIMUM_LOOKAHEAD
= Max payload (1024 for S200)
OID_GEN_MAXIMUM_FRAME_SIZE
= Max payload – Eth header size = 1024 – 14 = 1010 (at S200)
OID_GEN_MAXIMUM_SEND_PACKETS
= 1 (only single packet sends)
OID_GEN_MAXIMUM_TOTAL_SIZE
= Max 1394 payload size (eg 1024 for S200)
OID_GEN_LINK_SPEED
= 2,000,000 (For S200)
OID_GEN_TRANSMIT_BUFFER_SPACE
= Max packet size = Payload + Header = 1024 + 16 = 1040 (For S200)
OID_GEN_RECEIVE_BUFFER_SPACE
= Max packet size
OID_GEN_TRANSMIT_BLOCK_SIZE
= Max packet size (one block = one buffer. by design)
OID_GEN_RECEIVE_BLOCK_SIZE
= Max packet size
OID_GEN_VENDOR_ID
= Read from PCI config space (eg 0x8000104C for TI cards)
OID_GEN_VENDOR_DESCRIPTION
= “Texas Instruments 1394 PCILynx Card.\0”
OID_GEN_VENDOR_DRIVER_VERSION
= Project version number (eg 0.038)
OID_GEN_DRIVER_VERSION
= NDIS version number (4.0)
81
OID_GEN_MEDIA_CONNECT_STATUS
= NdisMediaStateConnected
OID_802_3_PERMANENT_ADDRESS
= OID_802_3_CURRENT_ADDRESS
= MAC Address stored in Adapter descriptor block
OID_802_3_MAXIMUM_LIST_SIZE
= Max multicast list size = 0 (not used)
If neither of these OIDs was passed: return
NDIS_STATUS_INVALID_OID
If buffer is too small, return NDIS_STATUS_INVALID_LENGTH
and pass the number of bytes needed.
Else copy into buffer and return NDIS_STATUS_SUCCESS
Name
Source
Parameters
Return Value
Call Type
Description
tilynxSetInformation
oid.c
IN: MiniportAdapterContext – Handle of Adapter descriptor block
IN: Oid – OID code to identify the set operation on the driver
IN: InformationBuffer – Buffer containing data to be used in the set
IN: InformationBufferLength – Number of bytes in InformationBuffer
OUT: BytesRead – To return number of bytes read from buffer
OUT: BytesNeeded – Returns if additional bytes needed for this OID
Status of the set operation
NDIS Export
Handles a set operation for a single OID.
Algorithm:
• verify length
• switch(oid)
• process request
OIDs:
OID_GEN_CURRENT_PACKET_FILTER
Return unsupported if set is for either of:
ndis_packet_type_source_routing
ndis_packet_type_smt
ndis_packet_type_mac_frame
ndis_packet_type_all_functional
ndis_packet_type_all_functional
ndis_packet_type_group
Otherwise set the packet type in Adapter descriptor block
82
OID_GEN_CURRENT_LOOKAHEAD
Copy into Adapter descriptor block.
If the OID passed was neither of these, return
NDIS_STATUS_INVALID_OID.
6.3.5 interrup.c
Name
Source
Parameters
Return Value
Call Type
Description
tilynxEnableInterrupt
interrup.c
IN: MiniportAdapterContext – Handle of Adapter descriptor block
None.
NDIS Export
Is called by NDIS to enable interrupts on the card.
This function only calls the compiler macro cardUnblockInterrupts.
This ensures that if the interrupt mask is to be altered, the code must
only be changed in one place.
This is usually called after tilynxHandleInterrupt.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxDisableInterrupt
interrup.c
IN: MiniportAdapterContext – Handle of Adapter descriptor block
None.
NDIS Export
Is called by NDIS to disable interrupts on the card.
This function only calls the compiler macro cardBlockInterrupts. This
makes for more readable code, and allows for easy code alteration in
the future. It is also included as an obvious pair to the macro
cardUnblockInterrupts.
This is usually called before tilynxHandleInterrupt.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxHandleInterrupt
interrup.c
IN: MiniportAdapterContext – Handle of Adapter block.
None.
NDIS Export
Interrupt handler during normal driver operation (after tilynxInitialize).
Should acknowledge interrupts when they occur, otherwise they will
stay set, and the machine will enter an infinite loop (calling
tilynxHandleInterrupt).
83
There are two interrupt registers, PCI and LLC. The LLC register holds
very hardware-specific interrupt status bits, such as incoming CRC
headers. The logic OR of the LLC is fed into one bit of the PCI
register, thus if any one LLC bit is set, it will cause a PCI interrupt.
Details on this can be found in the PCILynx specification6. All bits of
the PCI and LLC registers can be enabled or disabled, depending on the
requirement. Only a select few are enabled, otherwise the card would be
continually causing interrupts, and slowing the system down. To
acknowledge an interrupt, a binary 1 should be written to its status bit.
tilynxHandleInterrupt must first read the PCI reg, to determine where
the interrupt is coming from.
If it is a (PCI) DMA0_PCL interrupt, then a packet has been completed
on DMA0. This maybe a receive or a transmit. On receives, the data
should be indicated up to the protocols, in the lookahead buffer, using
an EthIndicateReceive function call. First however, the DMA0 status
register should be read to determine if it was successful. Finally the
interrupt must be acknowledged by writing a 1 to its status bit.
If it is a (PCI) DMA0_HLT, then DMA channel 0 has been halted.
Usually caused by a PCL queue which halts at the end of the queue.
The channel must be reenabled by writing to the DMA0 control
register. The interrupt should be acknowledged.
If the LLC_INT bit is set, then there is an LLC interrupt. The LLC_INT
register should be read, and checked for the following bits:
BUS_RESET – A bus reset has occurred. Acknowledge, and reenable
asynchronous receives/transmits by writing to the LLC_CONTROL
register (bus resets clear these bits). Also the self ID process after a bus
reset assigns the node a new 1394 ID, and this should be read from
PHY0 reg. There must be a pause of 400uS after a reset before this is
read, however NdisMSleep will not work at this IRQ level. Thus the
reading of PHY0 should be deferred until processed by a function
running at a different level, or until sufficient time has passed. See
HDR_ERR bit.
GRF_OFLOW – An overflow has occurred in the General Receive
FIFO. Acknowledge.
ATF_UFLOW – An underflow has occurred in the Asynchronous
Transmit FIFO. Acknowledge.
RXDATA_RDY – Received packet status bit. Acknowledge. Should
not really be turned on, as any proper receives are notified in the PCI
reg. This can happen very often.
AT_STUCK – Stuck on an asynchronous transmit. Acknowledge.
84
HDR_ERR – Incoming header CRC error. This also occurs when
physical layer packets are received, such as self ID packets. This is
because they don’t use the same CRC process. They are just one
quadlet of information followed by a quadlet which is the inverse of the
first quadlet. This can be used to read from the PHY0 register for the
1394 ID, as the last time this occurs will be after the last self ID packet
has been received.
Finally the LLC_INT bit should be acknowledged in the PCI register.
Interrupt handlers are useful when debugging, for displaying
information about received packets, and register status. It can be used
to dump the contents of receive buffers.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxIsr
interrup.c
OUT: InterruptRecognized – TRUE if interrupt was from this card
OUT: QueueDpc – TRUE if a DPC should be queued
IN: Context – Pointer to Adapter object
None.
NDIS Export
This is an interrupt handler, however it is only called if an interrupt
occurs during tilynxInitialize. This is because the Miniport has been
designed so that NDIS handles and identifies the interrupt, then calls
tilynxHandleInterrupt. This is done by setting requestIsr = FALSE on
the call to NdisMRegisterInterrupt.
This function should only be entered when a bus reset occurs, as this is
performed during initialize, thus tilynxIsr does not process packet
receives. It still must however check for and acknowledge the many
interrupts as done during tilynxHandleInterrupt. This is for robustness,
as one can never be entirely sure what might cause the interrupt. If a
rogue interrupt were to enter tilynxIsr, and it wasn’t acknowledged the
machine would enter an infinite loop.
Therefore see tilynxHandleInterrupt for the interrupt checking code.
However, there are extra functions which must be performed by
tilynxIsr, as follows:
Since NDIS has not identified the interrupt, it must check to see if the
interrupt has actually come from this card. It does this by reading the
PCI interrupt register. If INT_PEND is set, then the interrupt has
indeed come from this card. InterruptRecognized should be set to
TRUE, otherwise set to FALSE.
Also must block interrupts (using cardBlockInterrupts) before doing
any processing. tilynxDisableInterrupt is called before
85
tilynxHandleInterrupt, therefore tilynxHandleInterrupt need not do this.
Equally, after the function is complete, it should call
cardUnblockInterrupts, to reenable interrupts on the card.
Finally, set QueueDpc = FALSE, as all processing is performed inside
tilynxIsr.
No value is returned.
Name
Source
Parameters
Return Value
Call Type
Description
tilynxTransferData
interrup.c
OUT: Packet – To store and pass up the received data.
OUT: BytesTransferred – Number of bytes in packet
IN: MiniportAdapterContext – Handle of Adapter descriptor block
IN: MiniportReceiveContext – Handle for particular receive data
IN: ByteOffset – Offset in data to start copying from
IN: BytesToTransfer – Number of bytes to copy
Status of operation.
NDIS Export
This is called by NDIS when not all of the received data was copied in
the lookahead buffer. This is a translation from the protocol call
NdisTransferData.
By design, all data will be copied in the lookahead buffer. Therefore this
function is left empty. Only returns NDIS_STATUS_SUCCESS. For
completeness and robustness, this should eventually be coded to copy
the received data into a proper packet descriptor, where time is
available to do so.
86
6.4 Test Process
It was decided that testing be split up into two phases:
§
§
Module testing of the individual ‘C’ functions
Functional testing, based on the development stages listed in Section 5.6.
Testing can occur through including strategically placed debug output strings
throughout the code. Thus, the debug terminal screen displays these strings line-byline, indicating the progress of execution. Contents of variables should also be
displayed using these strings, to ensure that data is being processed correctly. Listing
all of these debug commands within this document would be unworkable, however
they have been kept within the source code, which should be checked in conjunction
with each module’s specification. Note that release versions will not include the debug
commands, therefore this will not have an adverse effect on the Miniport’s size.
Function tracking is important and can be implemented using debug strings such as:
“Entering function: tilynxInitialize”
“Leaving function: tilynxInitialize”
Given that functions are called dynamically by the NDIS wrapper, there are often gaps
in execution where one function has finished, while NDIS is performing other
operations, before the Miniport is called again at a different function. In this respect,
the Miniport cannot be tracked through a number of functions at a time. Determining
what is happening whilst the Miniport is not executing is extremely difficult. The only
method of watching what NDIS is doing, is to trace through assembly language lineby-line, which unfortunately gives away little of what is going on. The NDIS wrapper
does not output any debug strings to notify the terminal of what processing is currently
occurring.
Rather than repeat the actual tests that should be performed, they are listed in the Test
Results section in Chapter 7. All tests are to be carried out using Microsoft
WDEB386, as source-level debugging, such as that provided by SoftICE, is most
useful for debugging during development, rather than final tests. Finally, Microsoft
have provided a tool-set for testing NDIS Miniport drivers, known as the Windows
Hardware Quality Labs (WHQL) NDIS Tester. This should also be used to test the
Miniport, and can provide useful information on how well the driver interfaces with the
NDIS library. It is possible to also use this program to send test communication
between two machines running the NDIS Tester, which of course tests the hardware
interface as well.
References
1
Microsoft, Windows Version 4.0 Device Driver Kit, Microsoft Corporation
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI
3
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI, 6.2.11
4
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI, 5.3.2
5
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI, p37
6
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI, 5.3.1.7
2
87
7. TEST RESULTS
This chapter details the results of tests carried out on the project Miniport. These have
been carried out as detailed in Section 6.4, using both the WDEB386 debugger and the
Windows Hardware Quality Labs (WHQL) test tools.
In all cases, two diverse test systems were used to obtain the results, as shown in Table
7-1.
Test System 1
Windows95 updated to NDIS 4.0
Pentium 166MHz
TI 1394 PCILynx adapter
Table 7-1 - Test Systems
Test System 2
Windows95 OSR2
Pentium II-400MHz
TI 1394 PCILynx adapter
7.1 Module Tests
This section details the tests of the individual modules developed within the Miniport,
and described by the module specifications in Section 6.3. They are performed by
installing the Miniport in Windows, and running the WDEB386 debugger. Two
machines are required, one running the Miniport, and one viewing the debugger
output, as described in Section 5.5. Error-checking has been implemented throughout
the source code, such that the Miniport will always return a fail where problems occur.
Notification of the error is also displayed to the debugger terminal.
Only one PC was tested at a time, not connected to the other PC over the 1394 bus.
This is because these module tests are only to test the source, and identify any errors in
the path through the source. If there is a return value, modules should return
NDIS_STATUS_SUCCESS. Actual functional tests, such as communication between
nodes, will be tested later. Due to the nature of drivers, these modules are not called by
a “main” function, therefore the tests proceeded by causing situations where the
function would be called by NDIS. The developer cannot simply dictate the module
that should be run next. The format of these results are as shown in Table 7-2.
PASSED/FAILED
Function Name
A summary of the functionality performed by the module. This does not describe the
entire functionality performed, but identifies some of the important operations.
Table 7-2 - Module Test Results Format
The following results were obtained:
PASSED
DriverEntry
Returns NDIS_STATUS_SUCCESS.
The Miniport is properly registered with the NDIS wrapper, identifying that its
characteristics are deemed acceptable for loading.
tilynxInitialize
PASSED
88
Returns NDIS_STATUS_SUCCESS.
The Miniport reported itself as 802.3 media type, which was accepted by NDIS.
The card has been identified by NDIS, through Plug and Play, and NDIS has reported
the memory ranges and IRQ line that the card uses.
The call to tilynxSetupAdapter has succeeded, in setting up the hardware and all other
resource allocation.
PASSED
tilynxSetupAdapter
Returns NDIS_STATUS_SUCCESS
Allocations have been successful. These allocations include mapping the register space
in order that the card can be read, allocating memory for receive/transmit and
registering the interrupt.
Call to cardInitialize was successful, which set up settings on the 1394 hardware.
A ring of receive memory has been set up, and the card is ready to receive data.
PASSED
tilynxFreeResources
Tested by shutting down Windows, thus unloading the driver.
Is called, and deallocates resources, producing no error messages.
PASSED
tilynxHalt
Is also tested by unloading driver.
This calls tilynxFreeResources, which has been tested and passed.
PASSED
tilynxReset
Returns NDIS_STATUS_SUCCESS.
Very simple function, which writes one bit to hardware.
tilynxCheckForHang
Always returns FALSE.
PASSED
PASSED
myDbgPrintf
Outputs to the debugger terminal. Is already deemed to work, as is used during tests.
PASSED
cardInitialize
Returns NDIS_STATUS_SUCCESS.
Inputs settings to the 1394 hardware register-space.
Successfully causes a bus reset, and obtains a unique 1394 ID.
Successfully sets up a ring of receive memory.
setupReceivePcls
PASSED
89
Successfully sets up a PCL queue for receives.
Calls linkPcls to link the queue to the card.
PASSED
linkPcls
Successfully links the PCL to a DMA channel on the 1394 hardware.
Debug output displays the PCLs correctly, as required.
PENDING
tilynxSend
Due to problem with protocol communication, has yet to be tested. However, a similar
replacement send function has been created and tested. See Section 7.3.3.
PASSED
setupTransmitPcls
Although not called through a protocol send as yet, this has been tested via a test send
function. PCLs are correctly created, and displayed to the debug terminal during the
linkPcls function.
PASSED
tilynxQueryInformation
Returns NDIS_STATUS_SUCCESS.
On loading, NDIS queries a number of OIDs, which are returned successfully.
PASSED
tilynxSetInformation
Returns NDIS_STATUS_SUCCESS.
After OIDs have been queried, NDIS attempts to set various characteristics through
this function. These details are stored, and displayed to the debugger correctly.
PASSED
tilynxEnableInterrupt
Interrupts are enabled on the card. This is established by adding a device to the 1394
bus. A bus reset interrupt is generated.
PASSED
tilynxDisableInterrupt
Interrupts are disabled on the card. This is established by adding a device to the 1394
bus. A bus reset interrupt is not generated.
PASSED
tilynxHandleInterrupt
Interrupts are acknowledged. A large amount of card register information is displayed
to the debugger.
This can be induced by causing a bus reset.
PASSED
tilynxIsr
Interrupts are acknowledged. A large amount of card register information is displayed
to the debugger.
This is automatically induced during cardInitialize which forces a bus reset.
PASSED
tilynxTransferData
Merely outputs a debugger message.
90
7.2 Functional Tests
These tests have been specified by the developer, in order that the main functionality
required of the Miniport can be tested. They check the more general functionality
required of the driver, rather than strict module tests. These might be described as
system tests, insofar as a dynamic library can be tested as a whole system.
7.2.1 Resource Allocation/Deallocation
All resources were allocated correctly on the test systems, and no failures were
notified. Also these resources are correctly deallocated when the driver is unloaded or
halted.
7.2.2 Hardware Communication
Control of the TI 1394 cards has been achieved. The register-space on the card can be
read and written to, thus programming the hardware for operations. Simple tests were
performed for read and write access:
§
§
Read the very first quadlet of the register space, which contains the IEEE-assigned
vendor and device ID. For the project hardware, this ID is 0x8000104C.
Write to the LLC physical (PHY) registers to cause a 1394 bus reset. If the bus
reset interrupt is serviced, then the write was successful.
More extensive tests are not necessary, as the rest of the functional tests require that
the hardware is under control.
7.3 Plug and Play
This has been implemented successfully, and no configuration has to be performed
either on the physical card, or in Windows. If the TI 1394 card’s memory allocation or
interrupt (IRQ) line changes, this is detected on driver loading, and the Plug and Play
settings are automatically used. This was tested by introducing new PCI hardware to
the system, changing the PCI slot, and removing other PCI hardware. The slot number
is not fixed, thus when a card moves it is automatically searched for and found. Note
that Plug and Play is not supported in NT4, thus when a card is installed, the slot
number must also be written as a registry entry by the installation script. The IRQ and
memory resources, however, do not need to be set manually.
7.3.1 Integration into Windows Control Panel
The Miniport has been successfully integrated into the Windows device manager, such
that it can be viewed in the Control Panel, and also configured in the Network
properties applet. It is identified in the device manager by a unique name as part of the
Network device section, as shown in Figure 7-1.
91
Figure 7-1 - Windows Device Manager
The Miniport, and the 1394 bus network, can be set up by system administrators using
the Network properties applet, as shown in Figure 7-2. From here the administrator
can bind the chosen protocol drivers, such as TCP/IP or IPX/SPX, to the 1394
hardware.
Figure 7-2 - Network Properties Applet
92
7.3.2 Self ID Configuration
The Self ID capabilities of the Miniport and bus were tested, to ensure that each node
selects a unique 1394 ID for itself. This was tested by continually plugging and
unplugging the nodes on the bus, to induce bus resets. The interrupt service routine
subsequently displayed the new 1394 ID, which proved to be unique in every case.
7.3.3 Transmission Between 1394 Nodes
Test packets were set up and successfully transmitted between two machines running
the Miniport driver. Two transaction types were tested, as they are the required types
identified in the design:
§
§
Asynchronous Write with quadlet payload – required for building the 1394/MAC
translation table.
Asynchronous Write with block payload – required for sending the data passed
down by the protocol drivers.
A test system was implemented within the Miniport, for this purpose. One machine is
set as the Sender, and the other is set as the receiver. This distinction is made using the
Control Panel network applet, with a parameter called TestSend. If this parameter is
set to 1, this machine will send a packet to the other node.
Quadlet writes were tested by constructing 1394 packets with a quadlet payload of
0xDEADBEEF. A ‘C’ function was developed for this purpose, and can be found in
send.c in the source code1, named createTestSendQuad.
Block writes were tested by, similarly, constructing 1394 packets with a block payload.
This time, the payload consisted of 0xDEADBEEF, repeated throughout the payload.
Data sizes of one quadlet to 256 quadlets (S200 limit) were tested. A test function was
created, which can also be found in send.c, named createTestSendPacket.
In both cases, the tests were performed in both directions, by using both PCs as the
sender, and addressing the packet to the receiver node’s 1394 ID. The test packets
were successfully received at the receiver node. The packets were viewed by dumping
the receive memory to the debug terminal whenever a packet received interrupt is
generated. The memory dump could be seen to be exactly the same as the sent packet.
Packet addressing was tested by sending packets addressed to a 1394 ID that is not on
the bus. It was found that these packets were not picked up by either node, thus
explicit addressing was deemed to work properly. Also bus resets were induced to
force a 1394 ID change, after which, packets could still be received. Therefore the
receive comparators have been properly set, and the Miniport will continue to work
after ID changes.
These results are very important, and signify that proper 1394 communication has been
achieved. Thus the Miniport has successfully acquired full control over the hardware
and the 1394 bus, and is ready to immediately place frames passed down by the
protocols, into the block payload.
93
7.3.4 Communication with Protocol Layer
Communication between the Miniport and the protocol drivers above, uses the NDIS
wrapper as an intermediary, however for simplicity we will assume there is a direct link
herein. This communication usually takes the form of either status queries (object
identifiers) or actual packet transfer. Status functionality was found to be implemented
successfully, however a problem was identified with other protocol communication.
Object Identifiers (OIDs) are well documented in the NT 4.0 DDK2, but are basically
used by the protocol drivers to ask for certain information from the Miniport, such as
the MAC address, or the largest acceptable packet size. On loading the Miniport, a
number of OID queries and sets are performed by the protocol drivers, and these
complete successfully. The information queried and set is output to the debug terminal
to give an idea of what information the protocol is interested in.
However, once the OID stage is complete, a bug was found that causes a Page Fault or
Windows protection error. This proved to be a major stumbling block in the project
development, and is as yet unsolved. The problem in finding the cause of this, is that it
is occurring outwith the Miniport, and thus there is no information available in the
debugger, as to what the system is currently doing. If the problem had been within the
Miniport, the source could have been traced using SoftICE until the Page Fault
occurred, however it is being thrown up by some other driver or application.
Tracing through assembly language with SoftICE indicates that this problem is
occurring after a call to NdisSend, which should eventually be passed onto tilynxSend.
However, tilynxSend is never entered, therefore the page fault must be occurring
within NDIS. A great deal of time has been spent in fixing this, however nothing has
been found yet due to the lack of debug information. It is envisaged that the problem
can be fixed in a matter of days or possibly up to two weeks, as fault-finding had to be
postponed for the preparation of this document.
In the meantime, the problem can be bypassed by providing certain OID information to
the protocol drivers, in order to cause the protocols not to send any data. For instance,
by having the Miniport report that it does not support broadcast transmits, TCP/IP will
not send any data, however the driver still loads and is bound to the TCP/IP drivers.
This is useful, but ultimately the communication with the protocols must go past this
current stage.
The Miniport was tested by binding with TCP/IP, IPX/SPX and NetBEUI, producing
the same results. The problem is common across all of these protocols.
7.3.5 MAC/1394 Translation Table Mechanism
The code for creating and checking the translation table has been provisionally created,
and should be ready for such a time when the protocol drivers pass a frame down. The
code for sending the small packets has been based on the createTestSendQuad function
used for testing quadlet writes, and therefore should be working. Until the Page Fault
problem is bypassed, this functionality cannot be tested, due to the fact that no packets
are passed down from the protocol drivers.
94
7.3.6 Broadcast Mechanism
Code for implementing the broadcast mechanism outlined in Section 5.2.10 has been
provisionally written, and can be found in the tilynxSend function. Given that only two
cards have been provided for use with the project, it will be difficult to test this
functionality fully. However, the code is in place and ready for such a time when the
Page Fault is fixed.
7.4 Driver Resource Usage
Some tests were performed on the Miniport to find information on resource usage.
These were performed on a release version compile, thus the debug commands are not
present. The results are shown in Table 7-3.
File Size
SoftICE-reported memory footprint
Virtual memory allocated
Page-locked memory allocated
Total allocated memory
Table 7-3 - Resource Usage
26,080 Kbytes
26 Kbytes
1,104 Bytes
4,448 Bytes
5,552 Bytes
It can be seen that the dynamically allocated memory, for various uses within the
Miniport, amounts to only 5,552 bytes, and 1,104 bytes of this can be paged out.
7.5 WHQL Test Results
Finally, the WQHL NDIS Tester was used to verify the Miniport. The full detailed test
logs can be found on the companion CD-ROM3, however a summary is included here
in Table 7-4.
Test Performed
Total Variations
Master client test
5
Open/close adapter tests 45
Query OID information
28
Set lookahead size
58
Set multicast address
2
Set packet filter
320
Query OID statistics
33
Totals
491
Table 7-4 - WHQL Results
Passed
5
45
28
58
1
160
33
330
Failed
0
0
0
0
1
160
0
161
The send and receive WHQL tests have not been performed, due to the page fault
problem when starting send transactions. The 161 failures that have been identified by
the tests are related to multicast support. This is because the Miniport is provisionally
reporting that multicast is not supported, in order to bypass the page fault on Windows
loading. In eventual implementations, the Miniport will report that multicast is
supported, at which time all of the 161 variations will pass.
95
References
1
Companion CD-ROM, path ‘\source\’
Microsoft (1996), Windows NT Version 4.0 Device Driver Kit: Network Drivers
Design Guide, Microsoft Corporation, 2.4.6
3
Companion CD-ROM, path ‘\whql\’
2
96
8. DISCUSSION AND CONCLUSIONS
This final chapter takes stock of the achievements of the project, and discusses the
implications both now and in the future.
8.1 Evaluation of Test Results
Given the results documented in Chapter 7, it can be seen that a great deal has been
achieved in the time available. Taking first the required stages of development which
were identified in Section 5.6, the current project status is shown in Table 8-1.
Development Stage
Skeleton Miniport
Basic communication with hardware
Plug and Play
Integration into Windows and Control Panel
Self ID process
Transmission between 1394 nodes
Protocol layer communication
MAC/1394 Translation
Broadcast mechanism
Table 8-1 - Stage Completion Status
Status
Achieved.
Achieved.
Achieved.
Achieved.
Achieved.
Achieved.
Pending.
Pending / Ready
Pending / Ready
A Miniport has been developed which was a difficult process in itself, and it does
perform a great deal of functionality. A major step was to obtain full control over the
TI 1394 hardware, and packets can be sent between nodes. However, the NDIS
problem has temporarily halted actual packet transfer between the protocol drivers at
two nodes. Finally, proprietary and unique methods have been conceived by the
developer, to achieve a working relationship between 1394 and computer networking.
Although these have not yet been tested, provisional code has been written, and the
Miniport should be quite ready for such a time when the NDIS problem is overcome.
To look next at the Requirements Specification of Chapter 2, these goals were of a
higher level than the actual implementation, and would be more apparent to the user.
These requirements were as follows:
8.1.1 Operating System
The operating system decision lay with Windows95, and this has been the path
followed throughout the project. The Miniport is Windows95-ready, both with the first
release, and the later OSR2 release. However, during development care was taken to
ensure compatibility with other Windows versions, and it should be that the Miniport
works in Windows98 and versions of NT later than and including v4.0. These have not
been tested yet, as no machines were readily available, however they will be tested in
the near future. It is a possibility that the problem with NDIS may be non-existent on
these systems, as NDIS behaves differently in different versions. Secondly, NT and
Windows98 provide more debug information for NDIS drivers than Windows95, and it
is envisaged that it will be easier to identify the cause of the problem with either of
these operating systems.
97
8.1.2 Hardware
Control has been gained over the BTL-supplied hardware.
8.1.3 Transport Protocol
Although not yet fully working, the Miniport has been developed as protocolindependent thus any future Windows protocol chosen by BTL will be supported. The
Miniport can be bound to all Windows protocols, and communicates its characteristics
to these drivers properly. However, the NDIS problem has halted further binding with
these protocols. The aforementioned tests on Windows98 and NT should provide a
route to the resolution of this.
8.1.4 Software
The required System Administrator interactions have been achieved. The Miniport is
Plug and Play ready, and can be installed and set up in Windows as with any other
regular network device. The user-level interactions however cannot be tested, due to
the NDIS problem between the protocol and the Miniport.
8.1.5 System Resources
Resources have been consciously kept to a minimum, such that the Miniport makes a
very small footprint in Windows. (See Section 7.4).
8.1.6 Speeds
The Miniport is adaptable to support any current 1394-specified bandwidth, and can
also support all future bandwidth changes.
8.1.7 Schedule
As noted in the requirements specification, the schedule has extended slightly beyond
that of April 1999. As the problem is a bug, and it is believed that the code is otherwise
complete, the new completion date should be within two weeks.
8.1.8 Budget
The entire project has been completed at no cost to the customer, BTL, other than the
loan of one computer and two 1394 devices. The developer has also spent nothing in
achieving these results, other than development time.
8.2 Evaluation of 1394 and Networking
No direct measurements of a 1394 network’s capabilities have been taken as yet, and
these will be available as soon as the protocol drivers are able to pass packets down to
the Miniport. However some observations can be made based on the work carried out,
and these should stand in an eventual 1394 network. Actual tests will be useful to
check that there are no slight differences to the envisaged data rates, but these should
be small if any, as the developer has endeavoured to learn the characteristics of the
1394 bus, and has taken all of this into account.
A key point regarding 1394 and networks are the data rates, and the test system will be
capable of 200Mbps, and up to 400Mbps if the latest TI hardware is used. Secondly,
1394 uses a fair arbitration mechanism that will have a very positive effect on the
network traffic and actual data rates. To compare this to Ethernet, most adapters for
this media are capable of 10 or 100Mbps data rates, and use the collision detection
mechanism for bus access. Due to collision detection, when bus traffic on an Ethernet
network is high, there can be severe consequences to the data rates achieved. 1394,
98
however, avoids this with its fair arbitration, and should be able to cope well with any
amount of traffic, up to the available bandwidth of 200 or 400Mbps, and beyond.
Although 200Mbps is double the rate achievable with normal Ethernet hardware, it
may not be a significant improvement for companies to overhaul their existing
networks. At present this would be costly, as 1394 adapters are relatively expensive,
but 1394 hardware manufactures promise cheap interfaces in future, and if adopted by
Intel as seems likely, we may see 1394-ready motherboards in our PCs quite soon.
Thus there would be no cost in upgrading networks to 1394 from legacy media, and
the benefits could be achieved immediately. Coupled with this, given the eventual
results from this project, existing software will continue to work when the network is
changed, thanks to the NDIS concept. Implications for the home user are slightly
different, and consumers may be more enamoured to using the built-in 1394 plug that
they are already using to connect to their stereo and so on. They would have no reason
to stick to old media, as they do not have a large installation base of legacy hardware.
1394 is not entirely advantageous for networking however, as lengths between nodes
are currently limited to 4.5m. It may be that an environment is sufficiently dispersed
such that longer distances are required. There are two mitigating arguments; repeaters
can be used to extend the distance between nodes, and perhaps more attractively, work
is ongoing to increase these lengths. Without these improvements there may be
problems with the adoption of 1394 as a networking medium, and it must be
addressed. Secondly, the number of nodes per bus is limited to 63, and this may not
fulfil requirements in an office, however if bus bridges are sufficiently cheap this should
not pose such a problem. Coupled with this, there are arguments for limiting the
number of nodes per bus, such as not consuming too much bandwidth by overloading
the network.
The method in which this project has implemented 1394 networking should not cause
any adverse effect. Two issues are the encapsulation of Ethernet frames, and the
broadcast method. Ethernet encapsulation means that there are an extra 14 bytes per
packet. With packet data payloads of 1024 bytes at S200, the extra 14 bytes should not
adversely affect the bandwidth consumption. If Ethernet frames were consistently
small, this may have some effect if there is high bus traffic. In a busy network, the 14
extra bytes might be useful if freed up for less redundant data, however smaller packets
could be easily copied together into larger packets to reduce the overhead. A way
round this problem would be to have native 1394 support in the Windows NDIS
protocol drivers, an area which will hopefully be investigated for future versions of
Windows. The broadcast method, including the building of the MAC/1394 translation
cache, has been investigated and the effect on bus traffic has been shown to be very
small. However, if this is still regarded as detrimental, the other possibilities for
broadcast outlined in Section 5.2.9 can be investigated, that is using either isochronous
traffic or more intelligent asynchronous delivery paths.
Finally, and this applies to any 1394 network implementation, there is the overhead
from the 1394 packet header and CRCs. The asynchronous block write header contains
16 bytes with two CRCs of 4 bytes each. Thus each data payload is accompanied by 24
bytes of 1394 protocol information. To compare this to an Ethernet frame, data is
accompanied by 122 bytes of header and footer information if including the preamble
and delay fields. The delay between 1394 packets is determined by a ‘gap time’, and
99
this differs depending on node proximity, whereas Ethernet implements a worst-case
delay for each frame. Without measuring a physical implementation, it is not possible
to predict the delay between 1394 packets, however it can be seen that the 1394
packet header is likely to consume less bandwidth than the Ethernet frame information.
It may be useful to also investigate and compare with other network media, however
Ethernet is a good basis for a comparison, and the real proof of 1394’s suitability will
come in the eventual 1394 network.
8.3 Commercial Implications
The finished device driver will be an important achievement, and will bring a useful
new application to the home user and the office. Given that British Telecom Research
Labs (BTL) sponsored the project, the implications for them must be considered. The
LAN team at BTL specified the project as a feasibility study of the 1394 bus, and will
be able to perform a thorough analysis based on the results. They have the ability to
recommend BT-wide adoption of 1394 if deemed appropriate, and ultimately this
could result in the encouragement of adoption by BT’s many international customers.
The possible deployment of 1394 is immeasurable, and BT have the strength to at least
partly dictate this, and it is projects such as this which are needed for BT to make such
informed decisions.
Although some of the discussion within this chapter has mentioned improvements
which are forecast for the future of 1394, such as increased transmission distances, that
does not mean that it should not be investigated until such a time when these
improvements are made. BT, as a major international player in data communications,
must be at the forefront of promising new technologies and if 1394 does take off
commercially in the future, BT will be ahead of the game. The current status of the
project should provide the LAN team with information for digestion, and when a
working implementation is achieved, they will be able to perform a full study, using the
techniques they use for other network media.
Finally, although it would be difficult to sell the Miniport as a product to the public, it
may be that device and motherboard manufacturers that utilise the TI chipset would be
interested in adopting the software. Consumers would tend not to consider a device
driver as something for purchase, and instead would expect that the hardware
manufacturers or operating systems provide the necessary support for their hardware
at no cost. The Miniport would need further development and modification for this to
happen, but given the wide range of devices based on the PCILynx chip, there would
be many potential customers.
8.4 The Next Stage
The most pressing requirement for further work is currently the elimination of the
aforementioned NDIS page fault problem. The next step in combating this would be to
start testing with NT or Windows98. Technical support from Microsoft might also be
useful, for which a support contract would have to be purchased. That aside, some
areas for future investigation have been identified. None of these are necessary to the
project, they are merely included as ideas for the future. These are as follows:
100
§
§
§
§
§
§
§
§
§
Implementation of bus management – A primary reason for this would be to make
possible different speed capabilities on one bus. Through management different
speeds can co-exist, without reducing the entire bus to the lowest speed.
Isochronous – It may be useful to implement isochronous capabilities if quality of
service (QoS) is required. This would require that the protocol drivers attach a
QoS requirement to packets.
Broadcast – The current method was chosen mostly for simplicity. It could be
improved by using the discussed parent-child method or by implementing
isochronous transfers.
Tweaking – Software settings such as buffer sizes, FIFO thresholds or cachealignment could be fine-tuned to gain the best performance.
Full analysis – Packages are available which could fully test the network
capabilities, data rates, and performance under stress. Performance should also be
tested using different protocols, IPX/SPX etc, and under different traffic
characteristics or with many nodes on the bus.
IPover1394 – This could be supported when the standard eventually becomes
available. It will only, however, work with p1394a hardware, and will limit the
protocol to only IP. There is something to be said for conforming to standards,
however it would require a great deal of consideration given these limitations.
Investigation of 1394 internetworks.
Adaptation for other 1394 hardware – This should be painless due to the nature of
the Miniport, especially given that a great deal of hardware is based on TI chips.
Linux – An invitation has been received from the founder of the Linux 1394
project, to implement their Texas Instruments hardware support.
8.5 Conclusions
The project has proved to be very interesting, and a great deal has been learned in the
process of development. The experience gained in NDIS and 1394 is valuable as these
subjects are not covered in University coursework, and were not covered during the
work placement at BTL. The conception of proprietary techniques for implementing
otherwise non-existent procedures was found particularly challenging and fulfilling, as
was the prospect of commercial adoption. Although the project required skills in many
different areas of technology, all work was carried out independently and successfully
managed by the developer, and the resultant product has brought together all of these
technologies.
No funding or technical assistance was required of the customer, for what turned out
to be a far more complex project than originally envisaged by BTL. The one
outstanding bug should be fixed very soon, and although it is expected that the
developer will complete the project, the documentation is sufficiently full that a new
developer can pick up from here. Finally, the project management skills gained have
ensured the progress of the work in the short time available, and will be very useful for
future work.
101
APPENDIX A - Windows95 and NDIS 4.0
If support for NDIS v4.0 Miniports is required in Windows95, the NDIS wrapper must
be updated to version 4.0, as Windows95 comes with a v3.1 NDIS wrapper as
standard. This process is not documented by Microsoft, but is widely accepted by the
NDIS developer community.
This merely involves replacing the NDIS library system file NDIS.VXD, by the NDIS
4.0 version. The replacement can be easily achieved by installing the Microsoft DUN
(Dialup Networking) update v1.3, available from the Microsoft web site, which
contains the new NDIS.VXD.
This is only necessary for the “off-the-shelf” release of Windows95, as NDIS 4.0 is
included in later updates, starting from Windows95 OSR2. Alternatively the
NDIS.VXD file included in OSR2 can be copied to the older Windows95 system.
102
APPENDIX B - Miniport Installation in Windows95
The installation of the project Miniport is much simplified by the Plug and Play
capability. The process occurs as follows:
§
§
§
§
§
§
With the PC switched off, install the TI 1394 hardware into a spare PCI slot.
Boot the PC into Windows95.
Windows95 discovers the hardware and asks for a disk containing the device
driver.
Insert the CD-ROM containing the Miniport (tilynx.sys) and the installation script
(tilynx.inf). There are two versions, debug and release, in separate directories.
The Miniport is installed, as well as any necessary Windows system files for
Windows networking. The device now should appear in Control Panel Device
Manager.
Set up the network using the Network applet of Control Panel. Bind the required
protocol and set up the parameters such as IP address for TCP/IP.
No hardware information has to be configured by the user, as this is taken care of by
Plug and Play. This process is common for all network device drivers, and as such
should fit into any company administration procedures.
This is achieved through the installation script, tilynx.inf, developed specifically for this
project, which sets parameters such as the requirement of NDIS v4.0, and writes the
necessary registry entries. It allows for any protocol to be bound to the TI hardware,
identified as an attractive project capability. The contents of this installation script
follow:
; Windows 95 Install script for Texas Instruments PCILynx 1394 Network Interface Card
; Requires NDIS 4.0 thus MS DUN update 1.3 or OSR2 must be installed
; Kelvin Lawson 4/99 <[email protected]>
[Version]
Signature=$CHICAGO$
Class=Net
Provider=%MS%
LayoutFile=LAYOUT.INF
[DestinationDirs]
DefaultDestDir=11
CopyDriverFiles =11
[Manufacturer]
%TI%=TI
[TI]
%DeviceName%=TI.Device,PCI\VEN_104C&DEV_8000
[TI.Device]
AddReg=tilynx.ndi.reg,tilynx2.ndi.reg
CopyFiles=CopyDriverFiles
Reboot
103
[CopyDriverFiles]
tilynx.sys
[tilynx.ndi.reg]
HKR,Ndi,DeviceID,,"PCI\VEN_104C&DEV_8000"
HKR,,AdapterCFID,,8000104C
[tilynx2.ndi.reg]
HKR,,DevLoader,,*ndis
HKR,,DeviceVxDs,,tilynx.sys
HKR,,EnumPropPages,,"netdi.dll,EnumPropPages"
HKR,,NetworkAddress,,"A3A3A3A3A3A3"
HKR,NDIS,LogDriverName,,"TILYNX"
HKR,NDIS,MajorNdisVersion,1,04
HKR,NDIS,MinorNdisVersion,1,00
HKR,Ndi\Interfaces,DefUpper,,"ndis3"
HKR,Ndi\Interfaces,DefLower,,"ethernet"
HKR,Ndi\Interfaces,UpperRange,,"ndis3"
HKR,Ndi\Interfaces,LowerRange,,"ethernet"
HKR,Ndi\Install,ndis3,,"tilynx.ndis3"
HKR,Ndi,CardType,,"PCI"
; For test purposes - if 1 this will send a test packet
; After installation this parameter can be changed in the Network applet.
HKR,Ndi\params\TestSend,ParamDesc,,"TestSend"
HKR,Ndi\params\TestSend,default,,0
HKR,Ndi\params\TestSend,min,,0
HKR,Ndi\params\TestSend,max,,1
HKR,Ndi\params\TestSend,step,,1
HKR,Ndi\params\TestSend,base,,10
HKR,Ndi\params\TestSend,type,,int
HKR,NDI\params\TestSend,flag,1,20,00,00,00
; Note: An NT 4.0 .INF script must add registry entries for the PCI SlotNumber.
; This is not necessary in Win9x or Win2K thanks to plug and play.
[ControlFlags]
CopyFilesOnly=PCI\VEN_104C&DEV_8000
[SourceDisksFiles]
tilynx.sys=1
tilynx.inf=1
[Strings]
MS="Microsoft"
TI="Texas Instruments"
DeviceName="TI 1394 TSB12LV21 PCILynx Network Interface Card"
104
APPENDIX C - Makefile for NDIS Miniport Compilation
This Makefile can be used to compile the project Miniport for use in Windows 95, NT
or 98. The command line options shown can be used for targeting the operating system
and choosing a debug or release target file. For Windows 98, either parameter can be
used, however for Plug and Play support Win95 should be specified. The file is a
configuration file for the NMAKE utility, part of Microsoft Visual C++.
#############################################################################
#
# Modified: Kelvin Lawson 2/12/98
#
# Standalone makefile for NDIS .SYS driver
#
# Usage:
# nmake [WINNT_PLATFORM=1 | WIN95_PLATFORM=1] [RELEASE=1]
#
# For nodebug build, add RELEASE=1
# Default is WIN95_PLATFORM=1, debug.
# For extra C defines, add C_DEFINES=-D....
#
# !!! No .h.c dependencies! add makedep or rebuild manually
#
#############################################################################
#---------------------------------------------------------!if !defined(WINNT_PLATFORM) && !defined(WIN95_PLATFORM)
!message "** BUILDING 95 version by default"
WIN95_PLATFORM=1
!endif
!if !defined(RELEASE)
!message "** CHECKED (debug) build **"
CKFREE=CHECKED
DBG=1
!else
!message "** RELEASE (nodebug) build **"
CKFREE=FREE
DBG=0
!endif
# running on nt or w9x?
!if defined(NUMBER_OF_PROCESSORS)
NULL=
CMD=cmd.exe
!else
NULL=nul
CMD=command.com
!endif
#---------------------------------------------------------DRNAME=TILYNX
#--- Directories - replace by yours! ----------------------------------DDKPATH=d:\DDKnt40
105
W95DDK=d:\DDK95
MSVCDIR=c:\progra~1\devstu~1\vc
ICEDIR=c:\siw95
BASEDIR=$(DDKPATH)
NDISINC=$(DDKPATH)\SRC\NETWORK\INC
INC95=$(W95DDK)\inc32
MSVCINC=$(MSVCDIR)\include
DDKINC=$(DDKPATH)\INC
#---------------------------------------------------------CL=$(MSVCDIR)\bin\cl
RC=c:\mssdk\bin\rc
LINK=$(MSVCDIR)\bin\link
NMSYM32=$(ICEDIR)\nmsym /translate:source,package
NTDDKLIB=$(DDKPATH)\lib\i386\$(CKFREE)
VXDWRAPLIB=$(W95DDK)\lib\vxdwraps.clb
# Modules ----------------------------------------------------------MODLIST=\
tilynx.obj interrup.obj card.obj send.obj oid.obj tilynx.res
# W95/NT specific:
W95MOD=
NTMOD=
#---------------------------------------------------------!if defined(WINNT_PLATFORM)
!MESSAGE "****** BUILDING NT version" $(C_DEFINES)
TARGETPATH=.\OUTNT
MODLIST=$(MODLIST)$(NTMOD)
NT95PLATF=-DWINNT_PLATFORM=1
!else
!if defined(WIN95_PLATFORM)
!message "****** BUILDING W95 version" $(C_DEFINES)
TARGETPATH=.\OUT95
MODLIST=$(MODLIST)$(W95MOD)
NT95PLATF=-DWIN95_PLATFORM=1
!endif
!endif
#---------------------------------------------------------!if $(DBG)
TARGDIR=$(TARGETPATH)D
OBJ=objd
!else
TARGDIR=$(TARGETPATH)
OBJ=obj
!endif
OBJL1=$(MODLIST:[=^$(OBJ^)\)
OBJL2=$(OBJL1:]=.obj )
106
OBJLIST=$(OBJL2)
#Write and include external file to substitute $(OBJ) in OBJLIST ...
!if [ $(CMD) /c echo > $(TEMP)\mktmp1.tmp OBJLIST=$(OBJLIST) ]
!endif
!include $(TEMP)\mktmp1.tmp
#--- Compile options ------# -FI: forces #include file
!if $(DBG)
!message "DEBUG build"
CFLAGS=-c -nologo -nologo \
-I. -I$(DDKINC) -I$(NDISINC) -I$(INC95) \
-I$(MSVCINC) -FI$(DDKINC)\warning.h -D_X86_=1 \
-Di386=1 -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DIS_32=1 \
-DNT_INST=0 -DWIN32=100 -D_NT1X_=100 -DWINNT=1 -D_WIN32_WINNT=0x0400 DWIN32_LEAN_AND_MEAN=1 \
-DDBG=1 -DDEVL=1 -DNDEBUG -DFPO=0 \
-D_DLL=1 -D_IDWBUILD -DRDRDBG -DSRVDBG \
-DNDIS_MINIPORT_DRIVER -DBRZWLAN $(NT95PLATF) \
/c /Zel /Zp8 /Gy -cbstring /W3 /WX /Gz /QIfdiv- /QIf /Gi- /Gm- /GX- /GR- /GF -Z7 /Od /Oi /Oy- \
LFLAGS=-map:$(OBJ)\$(DRNAME).map -debug:notmapped,FULL -debugtype:both -PDB:NONE
RCFLAGS2 = -DDBG=1 $(C_DEFINES)
!else
!message "RELEASE build"
CFLAGS=-c -nologo -nologo \
-I. -I$(DDKINC) -I$(NDISINC) -I$(INC95) \
-I$(MSVCINC) -FI$(DDKINC)\warning.h -D_X86_=1 \
-Di386=1 -DSTD_CALL -DCONDITION_HANDLING=1 -DNT_UP=1 -DIS_32=1\
-DNT_INST=0 -DWIN32=100 -D_NT1X_=100 -DWINNT=1 -D_WIN32_WINNT=0x0400 DWIN32_LEAN_AND_MEAN=1 \
-DDBG=0 -DDEVL=1 -DNDEBUG -DFPO=0 \
-D_DLL=1 -D_IDWBUILD -DRDRDBG -DSRVDBG \
-DNDIS_MINIPORT_DRIVER -DBRZWLAN $(NT95PLATF) \
/c /Zel /Zp8 /Gy -cbstring /W3 /WX /Gz /QIfdiv- /QIf /Gi- /Gm- /GX- /GR- /GF -Z7 /Oi /Oy- /Ob1
/Ot
#LFLAGS=-map:$(OBJ)\$(DRNAME).map -debug:notmapped,FULL -debugtype:both -PDB:NONE
# This strips dbg info!
LFLAGS=-map:$(OBJ)\$(DRNAME).map -debugtype:coff -PDB:$(OBJ)\$(DRNAME).pdb
RCFLAGS2 = -DDBG=0
!endif
# ---------- TARGETS -----------ALL: $(OBJ) $(TARGDIR) $(TARGDIR)\$(DRNAME).SYS
$(TARGDIR):
107
if not exist $(TARGDIR)\$(NULL) md $(TARGDIR)
$(OBJ):
if not exist $(OBJ)\$(NULL) md $(OBJ)
#------- LNK.RSP --------------$(OBJ)\lnk.rsp:
echo Writing: <<$(OBJ)\lnk.rsp
$(LFLAGS)
$(OBJLIST)
-machine:i386
-verbose
-MERGE:_PAGE=PAGE
-MERGE:_TEXT=.text
-MERGE:.rdata=.text
-SECTION:INIT,d
-OPT:REF
-FULLBUILD
-INCREMENTAL:NO
-FORCE:MULTIPLE
-RELEASE
-version:4.00
-osversion:4.00
-subsystem:native,4.00
-optidata
-driver
-align:0x20
-base:0x10000
-entry:DriverEntry@8
-IGNORE:4001,4037,4039,4065,4070,4078,4087,4089,4096
-NODEFAULTLIB
$(NTDDKLIB)\int64.lib
$(NTDDKLIB)\ntoskrnl.lib
$(NTDDKLIB)\hal.lib
$(NTDDKLIB)\ndis.lib
$(VXDWRAPLIB)
<<KEEP
#--- This forces recompile if cc.rsp changes (MS NMAKE feature)
$(OBJ)\*.obj: $(OBJ)\cc.rsp
# ----------Link the driver:
$(TARGDIR)\$(DRNAME).SYS: $(OBJLIST) $(OBJ)\lnk.rsp
$(LINK) -out:$@ @$(OBJ)\lnk.rsp
@if not exist $@ echo *** $@ not built! ***
#--------- CLEANUP -----CLEAN:
echo Deleting built files
- del *.obj
- del $(OBJ)\*.obj
- del $(OBJ)\*.rsp
- del $(OBJ)\$(DRNAME).*
#-- SoftIce .NMS file: ------$(TARGDIR)\$(DRNAME).nms: $(TARGDIR)\$(DRNAME).sys
- $(NMSYM32) $?
#-------END ------------
108
APPENDIX D – Companion CD-ROM
The following directories are on the CD-ROM.
Directory
source
archive
docs
whql
debug
release
Contents
Full project source code
Source code history
Relevant specifications
WHQL NDIS tester results
Debug build Miniport and installer
Release build Miniport and installer
Installation of the Miniport is easy using this CD-ROM. When Windows asks for a
disk containing the device driver, insert the CD and point it to the \debug or \release
directory, depending on which version is to be installed. The rest is automatic.
109
BIBLIOGRAPHY
The following documents are useful as background information on all aspects of the
project work. No sources were found, however, to provide an introduction and
instruction guide to NDIS development, which this document has provided.
Armitage G.J. and Adams K.M. (1995). How Efficient is IP over ATM anyway ?,
IEEE Network vol 9 Jan/Feb pp18-26
Bennatan E.M. (1995), Software Project Management – A Practitioner’s Approach,
2nd Ed, McGraw-Hill
Bertsekas D. and Gallager R. (1992), Data Networks, 2nd Ed, Prentice-Hall
Borrill P.L. (1991), Microprocessor Bus Structures and Standards”. IEEE Micro
Magazine, vol 1, pp 84-95, Feb 1981
Bradely T. and Brown C. (1992), RFC:1293 – Inverse Address Resolution Protocol,
IETF
Buchanan W. (1997), Advanced Data Communications and Networks, Chapman &
Hall
Buchanan W. (1999), PC Interfacing, Communications and Windows Programming,
Addison-Wesley, p648
Conger S. (1994), The New Software Engineering, International Thomson Publishing
Custer H. (1992), Inside Windows NT, Microsoft Press
Day J.D. and Zimmerman H. (1983), The OSI reference model,. Proceedings IEEE 71,
pp1334-40
Deering S. (1989), RFC:1112 - Host Extensions for IP Multicasting, IETF
Dhawan S. (1995), Networking Device Drivers, Van Nostrand Reinhold
Fair L. and Pearson B. (1998), The Best Way to Implement 1394 Technology – Q&A
With Intel’s 1394 Experts, Intel Platform Solutions Archive
Goldman J. (1998), Applied Data Communications: A Business-Oriented Approach,
John Wiley & Sons, pp203-5
Halsall F. (1996), Data Communications, Computer Networks and Open Systems, 4th
Ed, Addison-Wesley
IEEE Std 1394-1995, Standard for a High Performance Serial Bus, IEEE
110
IEEE Project p1394a, Draft Specification for a High Performance Serial Bus
(Supplement), IEEE
IEEE Project p1394b, Draft Standard for a High Performance Serial Bus
(Supplement), IEEE
Intel, Fundamentals of Ethernet Technology, Intel Certification Course FN2
ISO (1984), Basic Reference Model for Open Systems Interconnection, ISO:7498
ISO/IEC 13213:1994, ANSI/IEEE Std 1212, 1994 Edition, Control and Status
Register (CSR) Architecture for Microcomputer Buses, ISO/IEC
ISO/IEC 8802-2 (1990), ANSI/IEEE Std 802.2 Information Processing Systems –
Local Area Networks – Part 2: Logical Link Control, ISO/IEC
ISO/IEC 8802-3 (1990), ANSI/IEEE Std 802.3 Information Processing Systems –
Local Area Networks – Part 3: Carrier Sense Multiple Access with Collision
Detection (CSMA/CD) Access Method and Physical Layer Specifications,
ISO/IEC
James M. and Chapman K. (1989), Local Area Networks Architectures and
Implementations, Prentice-Hall
Jennings R. (1997), Fire on the Wire: The IEEE 1394 High Performance Serial Bus,
Adaptec Inc.
Johansson P. (1999), Internet Draft: Ipv4 over IEEE 1394, IETF
Hoffman G. and Moore D. (1995), IEEE 1394: A Ubiquitous Bus, presented at
Compcon’95 in San Francisco, 5 Mar 1995
Laubach M. (1998), RFC:2225 - Classical IP and ARP over ATM, IETF
Lewis G. (1999), FireWire – A Bus for all Systems ?, Electronics World (Jan 99)
Mackenzie L. (1998), Communications and Networks. McGraw-Hill
Markley R. (1990), Data Communications and Interoperability, Prentice-Hall
Messmer H. (1997), The Indispensable PC Hardware Book, 3rd Ed, Addison-Wesley
Microsoft (1996), Windows 95 Device Driver Kit, Microsoft Corporation
Microsoft (1998), Windows 98 Resource Kit, Microsoft Corporation
Microsoft (1996), Windows NT Version 4.0 Device Driver Kit, Microsoft Corporation
111
Microsoft (1999), Plug and Play Design Specification for IEEE 1394, Microsoft
Corporation
Microsoft, PE General Concepts, Microsoft Corporation
Norton D. (1992), Writing Windows Device Drivers, Addison-Wesley
PCISIG (1995), PCI Local Bus Specification Revision 2.1, PCI Special Interest Group
Pearson B. (1998), USB and 1394, Intel Platform Solutions Archive
Pietrek M. (1994), Peering Inside the PE: A Tour of the Win32 Portable Executable
File Format, Microsoft Systems Journal (March 1994)
Plummer D. (1982), RFC:826 – An Ethernet Address Resolution Protocol – or –
Converting Network Protocol Addresses to 48.bit Ethernet Address for
Transmission on Ethernet Hardware, IETF
Postel J. and Reynolds J. (1988), RFC:1042 - A Standard for the Transmission of IP
Datagrams over IEEE 802 Networks, IETF
Rose M. (1990), A Practical Perspective on OSI, Prentice-Hall
Schildt H. (1995), ‘C’ The Complete Reference, 3rd Ed, Osborne
Sommerville I. (1992), Software Engineering, Addison-Wesley
Tanenbaum A. (1996), Computer Networks, 3rd Ed, Prentice-Hall London, pp420-3
Tanenbaum A. (1990), Structured Computer Organization, Prentice-Hall
Texas Instruments (1998), 1394 Technical Overview, TI
Texas Instruments (1997), Data Transmission Seminar, TI
Texas Instruments (1998), Lynxsoft 1394 Software Application Programmer User’s
Guide- SLLU003 v2.2, TI, Chapter 6
Texas Instruments (1997), PCILynx Functional Specification, Rev 1.2, TI
Thielen D. and Woodruff B. (1993), Writing Windows Virtual Device Drivers,
Addison-Wesley
Truong H. et al (1995) LAN Emulation on an ATM Network, IEEE Communications
vol33 May pp70-85
Wickelgren I.J. (1997), The Facts about FireWire, IEEE Journal “Spectrum” (April
1997) pp19-25