Next | Prev | Up | Top | Contents | Index

Working With Page and Sector Units

In a 32-bit kernel, the page size for memory and I/O is 4 KB. In a 64-bit kernel, the memory page size is 16 KB, but because of hardware constraints such as the 4 KB span of DMA mapping registers in the Challenge and Onyx systems, a 4 KB page is used for I/O operations.

The header files sys/immu.h and sys/sysmacros.h contain constants and macros for working with page units. Some of the most useful are listed below:

NBPPNumber of bytes in a virtual memory page.
NBPSCTRNumber of bytes (512) in a standard disk "sector."
IO_NBPPNumber of bytes in an I/O page.
IO_PNUMSHFTNumber of bits to right-shift an address to get the I/O page number.
IO_POFFMASKMask to extract the I/O-page-offset value from an address.
btod()Return number of 512-byte "sectors" in a byte count (rounded up)
btop(x) Return number of I/O pages in a byte count (truncated)
io_pnum(x)Return the I/O page number from an address x.
io_poff(x)Return the I/O page offset from an address x.
io_numpages( addr, len)Return the number of I/O pages that span a given address for a length.
io_ctob(x)Return number of bytes in x I/O pages (rounded up).
io_ctobt(x)Return number of bytes in x I/O pages (truncated).

The functions summarized in Table 9-11 are also provided as functions.

Functions to Convert Bytes to Sectors or Pages
Function NameHeader FilesCan Sleep?Purpose
btop(D3) ddi.hNReturn number of I/O pages in a byte count (truncate).
btopr(D3) ddi.hNReturn number of I/O pages in a byte count (round up).
ptob(D3) ddi.hNConvert size in I/O pages to size in bytes.

Using these functions and macros, you can make your driver independent of the size of pages. When examining an existing driver, be alert for any assumption that a virtual memory page has a particular size, or that an I/O page is the same size as a memory page, and convert the code to use portable functions and macros.


Next | Prev | Up | Top | Contents | Index