O'Reilly logo

Linux Device Drivers, Second Edition by Alessandro Rubini, Jonathan Corbet



Start Free Trial

No credit card required

Backward Compatibility


Changes to Memory Management




#ifdef MAP_NR

The MAP_NR macro went away when virt_to_page was introduced. The get_page macro also didn’t exist prior to 2.4, so sysdep.h defines it as follows:

#ifndef get_page


The page_table_lock was introduced in 2.3.10. Earlier code would obtain the “big kernel lock” (by calling lock_kernel and unlock_kernel) before traversing page tables.


  • The vm_pgoff field was called vm_offset in 2.2 and before. It was an offset in bytes, not pages.

  • The vm_private_data field did not exist in Linux 2.2, so drivers had no way of storing their own information in the VMA. A number of them did so anyway, using the vm_pte field, but it would be safer to obtain the minor device number from vm_file and use it to retrieve the needed information.

  • The 2.4 kernel initializes the vm_file pointer before calling the mmap method. In 2.2, drivers had to assign that value themselves, using the file structure passed in as an argument.

  • The vm_file pointer did not exist at all in 2.0 kernels; instead, there was a vm_inode pointer pointing to the inode structure. This field needed to be assigned by the driver; it was also necessary to increment inode->i_count in the mmap method.

  • The VM_RESERVED flag was added in kernel 2.4.0-test10.


  • 2.2 and earlier kernels had a method called advise, which was never actually used by the kernel. There was also a swapin method, which was used to bring in memory from backing store; it was not generally of interest to driver writers.

  • The nopage and wppage methods returned unsigned long (i.e., a logical address) in 2.2, rather than struct page *.

  • The NOPAGE_SIGBUS and NOPAGE_OOM return codes for nopage did not exist. nopage simply returned 0 to indicate a problem and send a bus signal to the affected process.




static struct mm_struct *init_mm_ptr;

static void retrieve_init_mm_ptr(void)
    struct task_struct *p;

        if (p->pid == 0)

    init_mm_ptr = p->mm;


Another thing the 2.0 kernel did not have was maintenance of the module’s usage count in the presence of memory-mapped areas. Drivers that implement mmap under 2.0 need to provide open and close VMA operations to adjust the usage count themselves. The sample source modules that implement mmap provide these operations.

Finally, the 2.0 version of the driver mmap method, like most others, had a struct inode argument; the method’s prototype was

            struct vm_area_struct *vma);

Changes to DMA

The PCI DMA interface as described earlier did not exist prior to kernel 2.3.41. Before then, DMA was handled in a more direct—and system-dependent—way. Buffers were “mapped” by calling virt_to_bus, and there was no general interface for handling bus-mapping registers.




Start Free Trial

No credit card required