I was reading the memory management chapter of Linux Device drivers and i came accross the vm_area_struct .The structure has an offfset field namely unsigned long vm_pgoff .
I checked the comment for the member as /* Offset (within vm_file) in PAGE_SIZE units, *not* PAGE_CACHE_SIZE */
. I'm not quite sure whether it is the offset within the vma region or the offset in side the memory mapped file .
And i have seen driver's mmap implementation code to have the following line to recalculate the offset again by shifting the member by the PAGE_SHIFT bits .
unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
I'm not able to understand the same and any help on this would be great .
According to the book Linux Device Drivers, 3rd edition,
unsigned long vm_pgoff;
The offset of the area in the file, in pages. When a file or device is mapped, this is the file position of the first page mapped in this area.
Thus, it is the offset, measured in number of pages, in the file/device. Thus, the first page in the vm_area is the page "vm_pgoff" of the file/device.
The file mm_types.h says the same.
In the source code (file mm.h) of function
static inline unsigned long do_mmap(struct file *file, unsigned long addr,
unsigned long len, unsigned long prot,
unsigned long flag, unsigned long offset)
I have found expression offset >> PAGE_SHIFT
(right shift) that is used as pgoff
parameter of do_mmap_pgoff
, so it is obvious, to "restore" original offset
value we need to do Left Shift with the same PAGE_SHIFT
(as function lowmem_page_address
do that).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With