Additions:
Last change 09/05/2007
Device drivers come in two flavors, block and character. Block devices are used for mass storage devices and character devices handle data one character at a time. Is this true? I have read that it is so, most of the time. However, in Gordon Letwin's //Inside OS/2// he says the following:
//OS/2 device drivers are divided into two general categories: those for character mode devices and those for block mode devices. This terminology is traditional, but dont take it too literally because character mode operations can be done to block mode devices. The actual distinction is that character mode device drivers do I/O synchronously; that is, they do operations in first in, first out order. Block mode device drivers can be asynchronous; they can perform I/O requests in an order different from the one I which they received them.//
Device drivers operate in three different modes: INIT, Kernel (or task), and Interrupt. INIT mode is a special mode executed during at system boot with RING 3 privileges, however, it is allowed some RING 0 privileges (see OS/2 PDD reference). The Kernel mode is in effect when the device driver is called by the kernel in response to an I/O request. The Interrupt mode is in effect when the device driver's interrupt handler is called in response to an external interrupt. In this example I will only be concerned with INIIT and Kernel modes.
Deletions:
Last change 08/12/2007
Device drivers come in two flavors, block and character. Block devices are used for mass storage devices and character devices handle data one character at a time. Also, device drivers operate in three different modes: INIT, Kernel (or task), and Interrupt. INIT mode is a special mode executed during at system boot with RING 3 privileges, however, it is allowed some RING 0 privileges (see OS/2 PDD reference). The Kernel mode is in effect when the device driver is called by the kernel in response to an I/O request. The Interrupt mode is in effect when the device driver's interrupt handler is called in response to an external interrupt. In this example I will only be concerned with INIIT and Kernel modes.
Additions:
A more detailed description of the header is [[PDDHeader located here]].
Additions:
**Note 1:** I believe there are PDF versions of this book floating around, I have a hard cover copy. However, I did email Dr. Kogan asking if he would release it to the masses. He reply that he had wanted to do this sometime ago, but his coauthor would not agree to it.
Deletions:
**Note 1:** I believe there are PDF versions of this book floating around, I have a hard cover copy. However, I did email Dr. Kogan asking if he would release it to the masses. He reply that he had wanted to do the sometime ago, but his coauthor would not agree to it.
Additions:
~- 2. Design of OS/2 by Harvey M. Deitel and Michael S. Kogan //**(note 1)**//
~- 3. Writing OS - 2 2.1 Device Drivers in C by Steven J. Mastrianni //**(note 2)**//
**Note 1:** I believe there are PDF versions of this book floating around, I have a hard cover copy. However, I did email Dr. Kogan asking if he would release it to the masses. He reply that he had wanted to do the sometime ago, but his coauthor would not agree to it.
**Note 2:** I know there is an unpublished 3rd revision PDF floating around which covers Warp (approx 1997).
Deletions:
~- 2. Design of OS/2 by Harvey M. Deitel and Michael S. Kogan //(note 1)//
~- 3. Writing OS - 2 2.1 Device Drivers in C by Steven J. Mastrianni //(note 2)//
Note 1: I believe there are PDF versions of this book floating around, I have a hard cover copy. However, I did email Dr. Kogan asking if he would release it to the masses. He reply that he had wanted to do the sometime ago, but his coauthor would not agree to it.
Note 2: I know there is an unpublished 3rd revision PDF floating around which covers Warp (approx 1997).
Additions:
~- 2. Design of OS/2 by Harvey M. Deitel and Michael S. Kogan //(note 1)//
~- 3. Writing OS - 2 2.1 Device Drivers in C by Steven J. Mastrianni //(note 2)//
//
Note 1: I believe there are PDF versions of this book floating around, I have a hard cover copy. However, I did email Dr. Kogan asking if he would release it to the masses. He reply that he had wanted to do the sometime ago, but his coauthor would not agree to it.
Note 2: I know there is an unpublished 3rd revision PDF floating around which covers Warp (approx 1997).
//
Deletions:
~- 2. Design of OS/2 by Harvey M. Deitel and Michael S. Kogan //(note 1)//
~- 3. Writing OS - 2 2.1 Device Drivers in C by Steven J. Mastrianni
//Note 1: I believe there are PDF versions of this book floating around, I have a hard cover copy. However, I did email Dr. Kogan asking if he would release it to the masses. He reply that he had wanted to do the sometime ago, but his coauthor would not agree to it.//
Additions:
~- 2. Design of OS/2 by Harvey M. Deitel and Michael S. Kogan //(note 1)//
//Note 1: I believe there are PDF versions of this book floating around, I have a hard cover copy. However, I did email Dr. Kogan asking if he would release it to the masses. He reply that he had wanted to do the sometime ago, but his coauthor would not agree to it.//
Deletions:
~- 2. Design of OS/2 by Harvey M. Deitel and Michael S. Kogan
Additions:
The initialization routine performs two important jobs. First, to save the value of the entry point for the device's DevHlp routines (REQP_INIT rp->in.devhlp). Second, and to set the end of data and code segments (REQP_INIT rp->out.finalcs and REQP_INIT rp->out.finalds). The data and code segments after these points will be discarded after all device driver headers in the driver have been initialized. If the data length is set to zero then the driver will be unloaded.
Deletions:
Two important jobs of the initialization routine are to save the value of the entry point for the device's DevHlp routines (REQP_INIT rp->in.devhlp) and to set the size of data and code segments (REQP_INIT rp->out.finalcs and REQP_INIT rp->out.finalds).
Additions:
On entry to [[DevDriver1strategyc Strategy( )]] REQP_INIT rp->command will be set to RP_INIT which will call [[DevDriver1initc StratInit( )]] to perform initialization. Again, it is important to remember during INIT the driver is actually at ring level 3 with some access ring level 0 functions. The following tables lists the API calls available at INIT:
{{table columns="2" cellpadding="1" cells="DosBeep;Generate sound from speaker;DosCaseMap;Perform case mapping;DosChgFilePtr;Change (move) file read/write pointer;DosClose Close;file handle;DosDelete;Delete file;DosDevConfig;Get device configuration;DosDevIOCtl;I/O control for devices;DosFindClose;Close find handle;DosFindFirst;Find first matching file;DosFindNext;Find next matching file;DosGetEnv;Get address of process environment string;DosGetInfoSeg;Get address of system variables segment;DosGetMessage;Get system message with variable text;DosOpen;Open file;DosPutMessage;Output message text to indicated handle;DosQCurDir;Query current directory;DosQCurDisk;Query current disk;DosQFileInfo;Query file information;DosQFileMode;Query file mode;DosRead;Read from file;DosSMRegisterDD;Register session switch notification;DosWrite;Synchronous write to file"}}
Two important jobs of the initialization routine are to save the value of the entry point for the device's DevHlp routines (REQP_INIT rp->in.devhlp) and to set the size of data and code segments (REQP_INIT rp->out.finalcs and REQP_INIT rp->out.finalds).
Deletions:
On entry to [[DevDriver1strategyc Strategy( )]] REQP_INIT rp->command will be set to RP_INIT which will call [[DevDriver1initc StratInit( )]] to perform initialization. Again, it is important to remember during INIT the driver is actually at ring level 3 with some ring level 0 access. Two important jobs of the initialization routine are to save the value of the entry point for the device's DevHlp routines (REQP_INIT rp->in.devhlp) and to set the size of data and code segments (REQP_INIT rp->out.finalcs and REQP_INIT rp->out.finalds).
Additions:
Last change 08/12/2007
Deletions:
Last change 07/27/2007
Additions:
Let me first state that I fully intend to plagiarize as much as possible, deal with it. There seems to be only a few options for the hobbyist programmer to easily learn how to build a device driver for eCS-OS/2. Some good examples that exist are [[PikeOs2 Alger Pike's EDM/2]] articles from years ago, so they are somewhat dated. Another example is contained in the Open Watcom directory [samples\os2\pdd]. Of course there are various driver examples available from many additional sources, just use Google. This text deals with 16 bit eCS-OS/2 drivers.
Deletions:
Let me first state that I fully intend to plagiarize as much as possible, deal with it. There seems to be only a few options for the hobbyist programmer to easily learn how to build a device driver for eCS-OS/2. Some good examples that exist are [[PikeOs2 Alger Pike's EDM/2]] articles from years ago, so they are somewhat dated. Another example is contained in the Open Watcom directory [samples\os2\pdd]. Of course there are various driver examples available from many additional sources, just use Google.
Additions:
The device driver consists of at least one code segment and one data segment, although more memory can be allocated if required. Additionally, the device driver is an EXE type program which is linked as a DLL. The header contains information used by the kernel during initialization. The data segment, which contains the Device Header, must appear as the very first data item. No data items or code can be placed before the Device Header. An OS/2 device driver which does not adhere to this rule will not load. While I do not intend to get ASM deep, the [[DevDriver1devsegsasm devsegs.asm]] source and **""#pragma data_seg ( "_HEADER", "DATA" )""** in header.c keeps the segments in order.
The initialization thread opens the driver module and reads the first segment into low memory (below 1M). This segment will be the main data segment. The second segment is loaded into low memory and will be the main code segment. Any additional segments are read into high memory (above 1M).
Deletions:
The device driver consists of at least one code segment and one data segment, although more memory can be allocated if required. Additionally, the device driver is an EXE type program which is linked as a DLL. The first item in the data segment is the header. The header MUST be the first! It contains information used by the kernel during initialization. While I do not intend to get ASM deep, the [[DevDriver1devsegsasm devsegs.asm]] source and **""#pragma data_seg ( "_HEADER", "DATA" )""** in header.c keeps the segments in order. Some of the initial feedback to this article included a "why does it have to be first?" question. Reference 5 explains it like this:
The initialization thread opens the driver module and reads the first segment into low memory (below 1M). This segment will be the main data segment. The second segment is loaded into low memory and will be the main code segment. Any additional segments are read into high memory (above 1M).
No differences.
Additions:
-1L, // Link to next header in chain
Need to add - MKG
Deletions:
FENCE, // Link to next header in chain
Additions:
The "next driver in chain" link is set to -1L to mark the end of DEVHEADER chain (see [[DevDriver1devhdrh devhdr.h]]) because the example device driver contains only a single device. If a second device were to be defined in this driver then the field would point to it. Next, the Device Attribute Word which is used to define the operational characteristics of the device driver. This is set to DAW_CHARACTER | DAW_OPENCLOSE | DAW_LEVEL1 which are listed and explained in [[DevDriver1devhdrh devhdr.h]]. The strategy routine entry point is next and is explained in section 4 of this article. The IDC entry point offset follows and is used if the device driver supports inter-device driver communications. The Hello World driver does not support IDC so this is set to 0. The Device driver name is next and must be 8 characters in length, notice how the Hello$ name is padded with spaces. The final field is the Capabilities Bit Strip word defines additional features on level 3 drivers (OS/2 v2.0 (support of memory above 16MB). See [[DevDriver1devhdrh devhdr.h]] for Capabilities Bit Strip options, however, the Hello World driver does not utilize level 3 options.
Deletions:
The "next driver in chain" link is set to FENCE to mark the end of DEVHEADER chain (see [[DevDriver1devhdrh devhdr.h]]) because the example device driver contains only a single device. Next, the Device Attribute Word which is used to define the operational characteristics of the device driver. This is set to DAW_CHARACTER | DAW_OPENCLOSE | DAW_LEVEL1 which are listed and explained in [[DevDriver1devhdrh devhdr.h]]. The strategy routine entry point is next and is explained in section 4 of this article. The IDC entry point offset follows and is used if the device driver supports inter-device driver communications. The Hello World driver does not support IDC so this is set to 0. The Device driver name is next and must be 8 characters in length, notice how the Hello$ name is padded with spaces. The final field is the Capabilities Bit Strip word defines additional features on level 3 drivers (OS/2 v2.0 (support of memory above 16MB). See [[DevDriver1devhdrh devhdr.h]] for Capabilities Bit Strip options, however, the Hello World driver does not utilize level 3 options.
Additions:
I intend only to deal with 16-bit driver and not some of the 32-bit additions IBM added.
Deletions:
More to come
Additions:
You need some knowledge of C and enough ASM know-how to understand some basic source. For ASM I know how to do a [[http://en.wikipedia.org/wiki/Hello_world HelloWorld]] executable but that is the extent. Also, the current version of [[http://www.openwatcom.org/index.php/Main_Page Open Watcom]] needs to be installed and working. Later you might want to read up on privilege levels and a good explanation exists on [[http://www.edm2.com/0307/32-bit-io.html EDM/2 by Holger Veit]] (what happened to him?).
Deletions:
You need some knowledge of C and enough ASM know-how to understand some basic source. For ASM I know how to do a [[http://en.wikipedia.org/wiki/Hello_world HelloWorld]] executable but that is the extent. Also, the current version of [[http://www.openwatcom.org/index.php/Main_Page Open Watcom]] needs to be installed and working.
Additions:
Let me first state that I fully intend to plagiarize as much as possible, deal with it. There seems to be only a few options for the hobbyist programmer to easily learn how to build a device driver for eCS-OS/2. Some good examples that exist are [[PikeOs2 Alger Pike's EDM/2]] articles from years ago, so they are somewhat dated. Another example is contained in the Open Watcom directory [samples\os2\pdd]. Of course there are various driver examples available from many additional sources, just use Google.
Reference 3 and 5 are very good, but only deal with 16 bit drivers. However, there is rumored to be an unpublished version of reference 3 for OS/2 Warp (1997) floating around the net somewhere. I will be taking parts of all the above and with luck provide something that can be used to learn what I did much quicker for a beginner.
You need some knowledge of C and enough ASM know-how to understand some basic source. For ASM I know how to do a [[http://en.wikipedia.org/wiki/Hello_world HelloWorld]] executable but that is the extent. Also, the current version of [[http://www.openwatcom.org/index.php/Main_Page Open Watcom]] needs to be installed and working.
I have modified Pike's Hello World example so it can be compiled with [[http://www.openwatcom.org/index.php/Main_Page Open Watcom]] and does not require the OS/2 DDK [here]. It outlines the basic parts of a device driver, but really does nothing. During system boot it displays a message which indicates it has loaded and executed initialization. I have provided a test.exe which when run opens and closes the driver. The driver will beep on open and close, not very exciting but it does provide feedback that things are working correctly.
Deletions:
Let me first state that I fully intend to plagiarize as much as possible, deal with it. There seem to be very few options for the hobbyist programmer to easily learn how to build a device driver for eCS-OS/2. Some good example that exist would be [[PikeOs2 Alger Pike's EDM/2]] articles from years ago, so they are somewhat dated. Another good example is contained in the Open Watcom directory [samples\os2\pdd]. Of course there are various driver examples available from many additional sources, just use Google.
I will be taking parts of the above and with luck provide something that can be used to learn what I did much quicker.
You need some knowledge of C and enough ASM know-how to understand some basic source. For ASM I know how to do a [[http://en.wikipedia.org/wiki/Hello_world HelloWorld]] executable but that is the extent. Also, the current version of Open Watcom installed and working.
I have modified Pike's Hello World example so it can be compiled with Open Watcom and does not require the OS/2 DDK [here]. It outlines the basic parts of a device driver, but really does nothing. During system boot it displays a message which indicates it has loaded and executed initialization. I have provided a test.exe which when run opens and closes the driver. The driver will beep on open and close, not very exciting but it does provide feedback that things are working correctly.
Additions:
Last change 07/27/2007
~- 1. OS/2 Physical Device Driver Reference
~- 2. Design of OS/2 by Harvey M. Deitel and Michael S. Kogan
~- 3. Writing OS - 2 2.1 Device Drivers in C by Steven J. Mastrianni
~- 4. Device driver information contained on the second eCS CD
~- 5. [[http://www.amazon.com/Writing-Os-2-Device-Drivers/dp/0201522349 Writing OS/2 Device Drivers by Raymond Westwater]]
The device driver consists of at least one code segment and one data segment, although more memory can be allocated if required. Additionally, the device driver is an EXE type program which is linked as a DLL. The first item in the data segment is the header. The header MUST be the first! It contains information used by the kernel during initialization. While I do not intend to get ASM deep, the [[DevDriver1devsegsasm devsegs.asm]] source and **""#pragma data_seg ( "_HEADER", "DATA" )""** in header.c keeps the segments in order. Some of the initial feedback to this article included a "why does it have to be first?" question. Reference 5 explains it like this:
The initialization thread opens the driver module and reads the first segment into low memory (below 1M). This segment will be the main data segment. The second segment is loaded into low memory and will be the main code segment. Any additional segments are read into high memory (above 1M).
More to come
Deletions:
Last change 07/22/2007
~- OS/2 Physical Device Driver Reference
~- Design of OS/2 by Harvey M. Deitel and Michael S. Kogan
~- Writing OS - 2 2.1 Device Drivers in C by Steven J. Mastrianni
~- Device driver information contained on the second eCS CD
The device driver consists of at least one code segment and one data segment, although more memory can be allocated if required. Additionally, the device driver is an EXE type program which is linked as a DLL. The first item in the data segment is the header. The header MUST be the first! It contains information used by the kernel during initialization. While I do not intend to get ASM deep, the [[DevDriver1devsegsasm devsegs.asm]] source and **""#pragma data_seg ( "_HEADER", "DATA" )""** in header.c keeps the segments in order.
Additions:
Last change 07/22/2007
Deletions:
Last change 07/18/2007