forked from troydhanson/kernel
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
nopage is obsolete in vm_operations_struct, saving
- Loading branch information
1 parent
47737a1
commit eda46af
Showing
7 changed files
with
220 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,3 +27,6 @@ | |
*.i*86 | ||
*.x86_64 | ||
*.hex | ||
|
||
# editor | ||
*.swp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# invoke as | ||
# | ||
# make -C /path/to/kernel/source SUBDIRS=$PWD modules | ||
# | ||
# e.g., | ||
# make -C /lib/modules/3.13.0-24-generic/build/ SUBDIRS=$PWD modules | ||
# | ||
|
||
obj-m := kex.o | ||
|
||
rig: rig.c | ||
|
||
clean: | ||
rm -f rig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
Pagefault | ||
vma ops | ||
|
||
This kex module implements mmap and includes a test rig to exercise it. | ||
When the test rig invokes mmap on the device, kex uses alloc_page | ||
to get as many pages as the rig requested. It uses vm_insert_page on | ||
each page to map it into rig's address space. These pages, while | ||
physically disjoint, appear as a single contiguous virtual memory area | ||
(VMA) inside the rig address space. The VMA is visible using pmap: | ||
|
||
``` | ||
% ./build.sh | ||
% sudo insmod kex.ko | ||
% cat /proc/devices | grep kex | ||
250 kex | ||
% sudo mknod dev c 250 0 | ||
% sudo chmod a+rw dev | ||
% ./rig dev 1 | ||
pid: 10195 | ||
press a key to exercise memory write | ||
``` | ||
|
||
Leave the rig waiting. In another terminal run pmap. See the dev VMA: | ||
|
||
``` | ||
% pmap -x 10195 | ||
Address Kbytes RSS Dirty Mode Mapping | ||
00007fd0125b6000 4 4 0 rw-s- dev | ||
``` | ||
|
||
It's 4kb because rig asked for one page (the final argument), which is 4kb. | ||
Now we can ask rig to write to this memory. In the original terminal, press | ||
enter. Then re-run pmap in the second terminal: | ||
|
||
``` | ||
Address Kbytes RSS Dirty Mode Mapping | ||
00007fd0125b6000 4 4 4 rw-s- dev | ||
``` | ||
|
||
Notice that the Dirty column now shows the mapped page is Dirty. (TODO: is | ||
this an MMU flag set on write to the page?). Press enter to terminate rig. | ||
|
||
Clean up: | ||
|
||
% rm dev | ||
% sudo rmmod kex | ||
% ./build.sh clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#!/bin/bash | ||
KERNELHEADERS=/lib/modules/$(uname -r)/build/ | ||
make -C ${KERNELHEADERS} SUBDIRS=$PWD $1 | ||
|
||
if [ "$1" == "clean" ] | ||
then | ||
make clean | ||
else | ||
make rig | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#include <linux/module.h> | ||
#include <linux/kernel.h> | ||
#include <asm/uaccess.h> | ||
#include <linux/cdev.h> | ||
#include <linux/slab.h> | ||
#include <linux/init.h> | ||
#include <linux/fs.h> | ||
#include <linux/mm.h> | ||
|
||
/* module information */ | ||
MODULE_AUTHOR("Troy D. Hanson"); | ||
MODULE_DESCRIPTION("Example of character device"); | ||
MODULE_LICENSE("Dual BSD/GPL"); | ||
|
||
#define NUM_MINORS 1 | ||
|
||
DEFINE_MUTEX(mutex); | ||
|
||
struct chardev_t { | ||
dev_t dev; /* has major and minor bits */ | ||
struct cdev cdev; /* has our ops, owner, etc */ | ||
} c; | ||
|
||
static | ||
struct page *fault(struct vm_area_struct *vma, unsigned long addr, int *type) { | ||
struct page *page=NULL; | ||
//get_page(); | ||
if (type) *type=VM_FAULT_MINOR; | ||
return page; | ||
} | ||
|
||
/* ops for VMA open, close and fault. See Linux Device Drivers, 3rd ed, p427. */ | ||
static struct vm_operations_struct vm_ops = { | ||
.nopage = fault, /* page fault handler */ | ||
}; | ||
|
||
int _mmap(struct file *f, struct vm_area_struct *vma) { | ||
unsigned long pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | ||
int rc=-ENODEV; | ||
printk(KERN_DEBUG "vma->vm_end %lu vm_start %lu len %lu pages %lu vm_pgoff %lu\n", | ||
vma->vm_end, vma->vm_start, vma->vm_end - vma->vm_start, pages, vma->vm_pgoff); | ||
|
||
if (0) goto done; | ||
vma->vm_ops = &vm_ops; | ||
vma->vm_private_data = (void*)0xa1fa1fa; /* could store private data here */ | ||
|
||
rc = 0; | ||
|
||
done: | ||
return rc; | ||
} | ||
|
||
struct file_operations ops = { | ||
.mmap = _mmap | ||
}; | ||
|
||
int __init chardev_init(void) { | ||
int rc; | ||
|
||
/* ask for a dynamic major */ | ||
rc = alloc_chrdev_region(&c.dev, 0, NUM_MINORS, "kex"); | ||
if (rc) { | ||
rc = -ENODEV; | ||
goto done; | ||
} | ||
|
||
/* init the struct cdev */ | ||
cdev_init(&c.cdev, &ops); | ||
c.cdev.owner = THIS_MODULE; | ||
|
||
/* make device live */ | ||
rc = cdev_add(&c.cdev, c.dev, NUM_MINORS); | ||
if (rc) { | ||
rc = -ENODEV; | ||
printk(KERN_WARNING "cdev_add: can't add device\n"); | ||
unregister_chrdev_region(c.dev, NUM_MINORS); | ||
cdev_del(&c.cdev); | ||
goto done; | ||
} | ||
|
||
rc = 0; | ||
|
||
done: | ||
return rc; | ||
} | ||
|
||
void __exit chardev_cleanup(void) { | ||
cdev_del(&c.cdev); | ||
unregister_chrdev_region(c.dev, NUM_MINORS); | ||
} | ||
|
||
module_init(chardev_init); | ||
module_exit(chardev_cleanup); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include <stdio.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <sys/stat.h> | ||
#include <sys/mman.h> | ||
#include <sys/types.h> | ||
#include <sys/fcntl.h> | ||
|
||
|
||
int main(int argc, char * argv[]) { | ||
char *file = (argc > 1) ? argv[1] : "dev"; | ||
int npages = (argc > 2) ? atoi(argv[2]) : 1; | ||
int fd,rc=-1; | ||
char *buf, *b, unused; | ||
size_t len = 4096 * npages; // FIXME getpagesz | ||
|
||
fprintf(stderr,"pid: %u\n", (int)getpid()); | ||
|
||
if ( (fd = open(file, O_RDWR)) == -1) { | ||
fprintf(stderr,"can't open %s: %s\n", file, strerror(errno)); | ||
goto done; | ||
} | ||
|
||
buf = mmap(0, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); | ||
if (buf == MAP_FAILED) { | ||
fprintf(stderr, "failed to mmap %s: %s\n", file, strerror(errno)); | ||
goto done; | ||
} | ||
|
||
rc = 0; | ||
|
||
/* make the program block so we can examine it */ | ||
|
||
fprintf(stderr,"press a key to exercise memory write\n"); | ||
read(STDIN_FILENO,&unused,sizeof(unused)); | ||
for(b=buf; b < buf+len; b++) *b=1; | ||
|
||
fprintf(stderr,"press a key to terminate\n"); | ||
read(STDIN_FILENO,&unused,sizeof(unused)); | ||
|
||
|
||
done: | ||
munmap(buf, len); | ||
close(fd); | ||
return rc; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,4 +14,8 @@ TODO | |
* ops: poll, mmap | ||
* kernel linked list, kfifo | ||
* pci, usb | ||
|
||
* kgdb | ||
* initramfs | ||
* kvm | ||
* net nic | ||
* waitqueues |