KernelNewbies:

Part of the WritingPortableDrivers section

As we saw in the example in InternalKernelDataTypes taken from drivers/char/serial.c, you can ask the kernel for a memory page. The size of a memory page is not always 4KB of data (as it is on i386). If you are going to be referencing memory pages, you need to use the PAGE_SHIFT and PAGE_SIZE defines.

PAGE_SHIFT is the number of bits to shift one bit left to get the PAGE_SIZE value. Different architectures define this to different values. The table below shows a short list of some architectures and the values of PAGE_SHIFT and the resulting value for PAGE_SIZE.

Architecture

PAGE_SHIFT

PAGE_SIZE

i386

12

4K

MIPS

12

4K

Alpha

13

8K

m68k

12

4K

m68k

13

8K

ARM

12

4K

ARM

14

16K

ARM

15

32K

IA-64

12

4K

IA-64

13

8K

IA-64

14

16K

IA-64

16

64K

Even on the same base architecture type, you can have different page sizes. This depends sometimes on a configuration option (like IA-64) or is due to different variants of the processor type (like on ARM).

The code snippet from drivers/usb/class/audio.c below shows how PAGE_SHIFT and PAGE_SIZE are used when accessing memory directly:

   1 static int dmabuf_mmap(...)
   2 {
   3         size >>= PAGE_SHIFT;
   4         for(nr = 0; nr < size; nr++)
   5                 if (!db->sgbuf[nr])
   6                         return -EINVAL;
   7         db->mapped = 1;
   8         for (nr = 0; nr < size; nr++) {
   9                 unsigned long pfn;
  10 
  11                 pfn = virt_to_phys(db->sgbuf[nr]) >> PAGE_SHIFT;
  12                 if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, prot))
  13                         return -EAGAIN;
  14                 start += PAGE_SIZE;
  15         }
  16         return 0;
  17 }

KernelNewbies: MemoryIssues (last edited 2017-12-30 01:29:57 by localhost)