RE: Sharing memory between kernel and user space.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I got a lot of good help in the last couple days, thank you to everyone
who responded; I made major progress but I'm still having a hang up and
a bit confused.

I my driver, I allocate this structure:

typedef struct rtc_shared {
    unsigned long       snap_addrs_loc;
    time_t              ntimestamp;
} RtcShared;

In the driver like this:

static int
alloc_rtc_usr_shared(RtcSoftDev *rtc_sp)
{
    unsigned long addr;
    unsigned long bytes = PAGE_SIZE << get_order(RTC_COMMON_SIZE);
    unsigned long sz;

    rtc_sp->shared_host_mem =
        __get_free_pages(GFP_KERNEL, get_order(RTC_COMMON_SIZE));

    if (rtc_sp->shared_host_mem == NULL) {
        debug_out(("alloc_rtc_usr_shared: out of memory.\n"));
        return(0);
    }

    memset((void *)rtc_sp->shared_host_mem, 0, bytes);

    for (addr = rtc_sp->shared_host_mem, sz = bytes;
        sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {

            SetPageReserved(virt_to_page(addr));
    }

    return(0);
}

And then in my driver mmap routine:

int
rtc_mmap(struct file *filep, struct vm_area_struct *vma)
{
    RtcSoftDev *rtc_sp = filep->private_data;

    unsigned long start = vma->vm_start;
    unsigned long size = vma->vm_end - vma->vm_start;
    unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
    unsigned long page = ((rtc_sp->iobase + offset) >> PAGE_SHIFT);

    if (offset > __pa(high_memory) || (filep->f_flags & O_SYNC)) {
        vma->vm_flags |= VM_IO;
    }

    vma->vm_flags |= VM_RESERVED;

    if (offset == RTC_COMMON_VADDR) {
        debug_out(("RTC_COMMON_VADDR: %x\n", offset));

        // page = virt_to_phys((void*)((unsigned
long)rtc_sp->shared_host_mem));
        // page = page_to_pfn(virt_to_page(phys_to_virt(__pa(page))));
        while (size > 0) {
            debug_out(("START: %#lx, SIZE: %#lx, OFFSET: %#lx, PAGE:
%#lx\n",
                start, size, offset, page));

            if (remap_pfn_range(vma,
                start,
                    page,
                        PAGE_SIZE,
                            PAGE_SHARED)) {
                return(-EAGAIN);
            }

            start += PAGE_SIZE;
            page += PAGE_SIZE;

            if (size > PAGE_SIZE) {
                size -= PAGE_SIZE;
            } else {
                size = 0;
            }
        }
    }

    else {
        debug_out(("RTC_???_OFFSET --- WE'RE BROKEN --- %x\n", offset));
    }

    return(0);
}

Now the driver like that loads and attaches without blowing up.
However, from userspace, when I open("/dev/mvp_rtc", O_RDWR) and then
try and mmap it, when I read it back, I can read back rtc_shared but I
can't read rtc_shared->snap_addrs_loc.

My main hope is that someone will spot something I'm obviously doing
wrong but if not, my next question is:

Is the virtual address that I get back from the kernel in
all_rtc_usr_shared going to be the same address that I read in
userspace?  Because right now I'm getting back something like 0xc11a0000
from the kernel and then I'm seeing something like 0xbf73000 in
userspace.

Thanks again for all the help and with a little more coaching I just
might get this blasted thing working before I retire 99 years from now!

:b!

Brian D. McGrew { [email protected] || [email protected] }
--
> This is a test.  This is only a test!
  Had this been an actual emergency, you would have been
  told to cancel this test and seek professional assistance!

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux