reading Memory-Mapped IO registers How to (from datasheet) and using them in mmap
in kernel function iomem_is_exclusive check IS_ENABLED(CONFIG_IO_STRICT_DEVMEM) or IORESOURCE_EXCLUSIVE flag is set:
if (IS_ENABLED(CONFIG_IO_STRICT_DEVMEM)
|| p->flags & IORESOURCE_EXCLUSIVE) {
err = true;
break;
}
we can simply use stap to pass through the check for test:
stap -g -e 'probe kernel.function("iomem_is_exclusive").return { $return = 0 }'
difference between a pci device driver with module_pci_driver and a pci driver with __init() but without module_pci_driver() in Linux
module_pci_driver()
is a helper meant for drivers that don't do anything special in their module init and exit (i.e. modules whose init and exit functions just register/unregister).
It generates the init and exit functions for you, reducing some boilerplate.
In this specific case, the 8139too driver might do something in addition to registering the driver (in this case, logging the driver name), so isn't using module_pci_driver()
The probe
function is called for existing or new devices that match the ID table and aren't already owned (see How To Write Linux PCI Drivers for details).
It returns a value indicating if the driver will be taking ownership of the device (either 0 or an error code).
How to mmap a Linux kernel buffer to user space?
The simplest way to map a set of pages from the kernel in your mmap method is to use the fault handler to map the pages. Basically you end up with something like:
static int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
vma->vm_ops = &my_vm_ops;
return 0;
}
static const struct file_operations my_fops = {
.owner = THIS_MODULE,
.open = nonseekable_open,
.mmap = my_mmap,
.llseek = no_llseek,
};
(where the other file operations are whatever your module needs). Also in my_mmap
you do whatever range checking etc. is needed to validate the mmap parameters.
Then the vm_ops
look like:
static int my_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
vmf->page = my_page_at_index(vmf->pgoff);
get_page(vmf->page);
return 0;
}
static const struct vm_operations_struct my_vm_ops = {
.fault = my_fault
}
where you just need to figure out for a given vma / vmf passed to your fault function which page to map into userspace. This depends on exactly how your module works. For example, if you did
my_buf = vmalloc_user(MY_BUF_SIZE);
then the page you use would be something like
vmalloc_to_page(my_buf + (vmf->pgoff << PAGE_SHIFT));
But you could easily create an array and allocate a page for each entry, use kmalloc, whatever.
[just noticed that my_fault
is a slightly amusing name for a function]
Related Topics
Not Authorized for Query on Admin.System.Namespaces on Mongodb
How to Check If Hadoop Daemons Are Running
Can't Use a Variable Out of While and Pipe in Bash
Hiding User Input on Terminal in Linux Script
Colors with Unix Command "Watch"
Nginx Not Listening to Port 80
Get MAC Address Using Shell Script
Register Variables in Loop in an Ansible Playbook
Starting Point for Clock_Monotonic
Deleting Old Files Using Crontab
Importing Shapefiles in Postgresql in Linux Using Pgadmin 4
Linux Shell Script for Each File in a Directory Grab the Filename and Execute a Program
Error: Gdal-Config Not Found While Installing R Dependent Packages Whereas Gdal Is Installed
Exclude List of Files from Find
Create New File But Add Number If Filename Already Exists in Bash