I'm experimenting with FreeBSD device drivers, and am attempting to share memory between kernel space and user space. Here's the overall flow I'm trying to accomplish:
The kernel module loader code, at MOD_LOAD, looks like:
To handle the mmap, I specify a d_mmap_single function as follows:
When the userspace application runs, I see the kernel address and string value printed out as expected. The userspace mmap() returns successfully, but the memory location does not contain the string specified. Where have I gone wrong?
- Driver is loaded.
- At load time, kernel memory is allocated and filled with the string "HELLO".
- At load time, a /dev/foo device is created.
- Userspace application runs, and performs an open("/dev/foo")
- After opening the device, it performs a mmap(), and attempts to puts() the returned address.
The kernel module loader code, at MOD_LOAD, looks like:
Code:
my_dev = make_dev(&my_cdevsw, 0, UID_ROOT,
GID_WHEEL, 0666, "foo");
my_mem = kmem_alloc(kmem_map, PAGE_SIZE);
vm_map_lookup(&kmem_map, my_mem, VM_PROT_ALL,
&my_entry, &my_mem_obj, &my_index, &my_prot, &my_wired);
vm_map_lookup_done(kmem_map, my_entry);
char_ptr = (char*)my_mem;
char_ptr[0] = 'H';
char_ptr[1] = 'E';
char_ptr[2] = 'L';
char_ptr[3] = 'L';
char_ptr[4] = 'O';
char_ptr[5] = '\0';
To handle the mmap, I specify a d_mmap_single function as follows:
Code:
static int my_mmap_single (
struct cdev* dev, vm_ooffset_t* offset,
vm_size_t size, struct vm_object** object, int prot)
{
if(*offset != 0 || size != PAGE_SIZE)
return ENOMEM;
*object = my_mem_obj;
uprintf("mmap kernel address, string: %p %s\n", (void*)my_mem, (char*)my_mem);
return 0;
}
When the userspace application runs, I see the kernel address and string value printed out as expected. The userspace mmap() returns successfully, but the memory location does not contain the string specified. Where have I gone wrong?