OS/2, eCS & ArcaOS - Technical > Hardware
Read and Write to driver
Igor:
Hi All!
I am researching how to work with 32-bit drivers.
I need to write to the driver and read characters using the standard DosRead/DosWrite
--- Code: ---
PBYTE plData = NULL;
plData = (PBYTE)Far16ToFlat(prp->io.ulAddress);
--- End code ---
I am receiving an incorrect address.
Which function should I use?
Help me please!
Martin Iturbide:
Hello Igor
I apologize in advance if this is wrong, since I have no idea. I asked the Gemini AI.
--- Quote ---Working with memory addresses in the OS/2 Warp 16/32-bit "mixed" environment can be a bit of a headache, especially when transitioning between the kernel's 16-bit physical addressing and the 32-bit flat model of a driver or application.
The issue you're likely facing is that `Far16ToFlat` is generally used for converting 16:16 segmented pointers. However, if `prp->io.ulAddress` contains a **physical address** (which is common in Request Packets for I/O operations), you need to map that physical memory into your driver's linear address space before you can touch it.
### The Correct Function: DevHelp_PhysToVirt
In the context of an OS/2 Physical Device Driver (PDD), the standard way to convert a physical address to a usable linear (flat) pointer is using the **PhysToVirt** DevHelp call.
Since you are likely in a 32-bit segment of a 4.52 (Warp CP2) driver, you should use the **Lin** version if you are operating in flat space.
#### Implementation Logic
1. **Verify the Address Type**: Ensure `prp->io.ulAddress` is actually a 32-bit physical address.
2. **Call PhysToVirt**: This maps the physical memory to a linear address that your 32-bit code can understand.
3. **Address Context**: Remember that these addresses are often process-context dependent. If you need to access this memory later (outside the current strategy routine), you may need to "lock" the memory or map it globally.
### Example Code Snippet
If you are using a C wrapper for DevHelps (common in the Watcom or IBM DDK environments), it should look something like this:
```c
APIRET rc;
LIN linearAddr;
// Convert physical address to a 32-bit flat (linear) address
// 0 indicates the mapping is for the current process context
rc = DevHelp_PhysToVirt(prp->io.ulAddress, prp->io.usLength, &linearAddr);
if (rc == 0) {
plData = (PBYTE)linearAddr;
// You can now use plData for DosRead/DosWrite logic
} else {
// Handle error: Mapping failed
}
```
---
### Important Considerations for Warp 4.52
* **Segment vs. Flat**: If `Far16ToFlat` was giving you "incorrect" addresses, it’s usually because it was treating a physical address as a `SEL:OFFSET` pair. A physical address `0x000B8000` is very different from a segmented address `0x000B:0x8000`.
* **The Kernel Helper**: If you are specifically trying to convert a **16:16 pointer** (Selector:Offset) passed from a 16-bit application to your 32-bit driver, use `DevHelp_LinTo24` or ensure your selector is valid in the current LDT/GDT before conversion.
* **DosRead/DosWrite**: Remember that inside a driver, you aren't usually calling `DosRead`. You are *implementing* the response to a `DosRead` called by an app. You move data from your driver buffer to the user buffer provided in the Request Packet (`prp->io.ulAddress`) using `DevHelp_MoveBytes` or simple pointer assignment once mapped.
**Quick Tip**: Check your `CONFIG.SYS`. If you are doing heavy 32-bit development on 4.52, ensure you have `BASEDEV=OS2DASD.DMD` and related drivers updated, as memory management quirks were often patched in the later Convenience Packages.
Is the address you are receiving coming specifically from a user-space application's buffer, or is it a memory-mapped I/O address from a hardware device?
--- End quote ---
I'm just curios to know how right or wrong the AI is.
I will prefer if someone with more knowledge on this area can comment.
Regards
Roderick Klein:
Does David his 32 bit driver kit not help out ?
drv32
https://88watts.net/software.html
Roderick
Lars:
The driver entry point that is called on a DosWrite/DosRead passes a physical address to read from/write to.
You need to call device driver helpers to convert a physical address to a virtual address. Or, for a 32-bit driver, to a linear address with the DS selector set to the flat selector.
By the way, the Gemini code is wrong. PhysToVirt maps from physical to virtual (16:16 pointer) and not to flat (0:32 pointer).
And it heavily phantasizes on what DevHelp calls are available. Seems there is not enough OS/2 code floating around...
Lars:
By the way: there is no DevHelp "PhysToLin". But there are other DevHelps that are equivalent to that.
I used "PagelistToLin" in my USBMSD.ADD driver.
Navigation
[0] Message Index
[#] Next page
Go to full version