Re: how to use the function copyout()

From: Julian Elischer (julian_at_elischer.org)
Date: 07/25/05

  • Next message: Scott Long: "Re: how to use the function copyout()"
    Date: Mon, 25 Jul 2005 13:06:34 -0700
    To: Felix-KM@yandex.ru
    
    

    Felix-KM wrote:

    >>>#define IOCTL_GET_B _IOWR("F", 127, 0x4)
    >>>
    >>>
    >>I think the third parameter to _IOWR should directly specify a type,
    >>e.g. _IOWR("F", 127, int) or _IOWR("F", 127, struct MyStruct).
    >>
    >>
    >>
    >>>---- driver ----
    >>>
    >>>struct my_softc {
    >>> ...
    >>> short unsigned int B;
    >>>};
    >>>
    >>>...
    >>>
    >>>static int
    >>>my_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
    >>> struct thread *td)
    >>>{
    >>> struct my_softc *my_sc;
    >>> int unit, error;
    >>> unit = minor(dev);
    >>> my_sc = (struct my_softc *)devclass_get_softc(my_devclass, unit);
    >>> if (my_sc == NULL)
    >>> return (ENXIO);
    >>> switch(cmd)
    >>> {
    >>> ...
    >>> case IOCTL_GET_B:
    >>> error = copyout(&my_sc->B, data, sizeof(my_sc->B));
    >>> switch (error)
    >>> {
    >>> case 0:
    >>> printf(" IOCTL_GET_B: %d\n", my_sc->B);
    >>> break;
    >>> case EFAULT:
    >>> printf("EFAULT\n");
    >>> break;
    >>> case EIO:
    >>> printf("EIO\n");
    >>> break;
    >>> case ENOMEM:
    >>> printf("ENOMEM\n");
    >>> break;
    >>> case ENOSPC:
    >>> printf("ENOSPC\n");
    >>> break;
    >>> }
    >>> break;
    >>> default:
    >>> break;
    >>> }
    >>> return 0;
    >>>}
    >>>
    >>>---user program ----------------------
    >>>
    >>>...
    >>>
    >>>short unsigned int Data[32768];
    >>>
    >>>int
    >>>main(int argc, char *argv[])
    >>>{ ...
    >>>
    >>> if (ioctl(fd0, IOCTL_GET_B, Data) == -1)
    >>> err(1, "IOCTL_GET_B");
    >>>
    >>> ...
    >>>}
    >>>
    >>>-------
    >>>
    >>>Here I get EFAULT.
    >>>
    >>>What have I done wrong? How can I do it correctly?
    >>>
    >>>
    >>The caddr_t data in your ioctl is already mapped into kernel
    >>memory. Look into the source of other device drivers. You'll
    >>find a lot of *(int *) data = ...
    >>So your copyout() has to fail because it tries to address
    >>memory which is not a part of your application's
    >>memory.
    >>>From errno(2): EFAULT: Bad address...
    >>
    >>I have no idea if it is possible for ioctls to have mapped more
    >>than a few 100 bytes for data exchange.
    >>You should use read and uiomove() instead.
    >>
    >>
    >
    >So if I get it right, it's impossible in FreeBSD to gain access to 64KB of user's program memory with ioctl?
    >
    >

    no you do not get it right.

    you should pass in a pointer to your 64k object.
    ioccom.h describes the definition of the ioctl name.
    this includes:
    #define IOCPARM_MASK 0x1fff /* parameter length, at most 13
    bits */
    so the maximum that the system will AUTOMATICALLY COPYIN() is 8k
    For larger amounts you can always have the address as teh parameter and
    do the copyin yourself.
    in other words the automatically moved data would be only a smal
    structure specifying address and size,
    and you would use those parameters to copyin the larger structure.

    >My situation is this - I have a device driver for Linux. My task is port it as it is (1:1) into FreeBSD.
    >
    >In the Linux driver Ioctl is realized with the macroses _put_user _get_user all over it. As I understand in FreeBSD their analogues are functions described in store(9), copy(9) and fetch(9).
    >
    >So the problem is that in my user program an array short unsigned int Data[32768] is defined. I need to gain access to the array(to each element of it) from device driver with Ioctl handler.
    >
    >Is it possible to do? If yes, then how it can be done?
    >
    >

    >
    >
    >>Norbert
    >>_______________________________________________
    >>freebsd-hackers@freebsd.org mailing list
    >>http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    >>To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"
    >>
    >>
    >
    >
    >
    >
    _______________________________________________
    freebsd-hackers@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-hackers
    To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"


  • Next message: Scott Long: "Re: how to use the function copyout()"

    Relevant Pages

    • Re: Handling memory inside kernel
      ... I would probably try to create a very simple IOCTL passing let's say a ULONG ... First of all if I try to obtain the memory buffer directly to use less cod ... bytesToTansfer); ...
      (microsoft.public.development.device.drivers)
    • Re: [PATCH 3/4] add ksm kernel shared memory driver
      ... Should this loop maybe check kthread_run too? ... Given that the KSM_REGISTER_MEMORY_REGION ioctl() creates unswappable ... memory, should there be some sort of capability check done there? ... Any benchmarks on the runtime cost of having KSM running? ...
      (Linux-Kernel)
    • Linux-2.6.12 memory mapping broken
      ... To the memory expert that made the massive changes to mm/memory.c: ... Memory allocation is 18656 bytes ... +void pgd_clear_bad ...
      (Linux-Kernel)
    • Re: communication between user mode and kernel mode
      ... You have the application send down the chunk of memory on an IOCTL ... Windows 2k/XP/2k3 Filesystem and Driver Consulting ...
      (microsoft.public.development.device.drivers)
    • [PATCH -mm 4/5] Hibernation: Correct definitions of some ioctls (rev. 2)
      ... new ioctl numbers for these ioctls and mark the existing ones as deprecated. ... SNAPSHOT_FREE - free memory allocated for the snapshot image ... partition, or a swap file as storage space (if a swap file is used, the resume ... it MAY mount a file system that was not ...
      (Linux-Kernel)