On Thu, 2007-08-09 at 11:14 -0400, Matt Bailey wrote:
> Here's the example I was working from
> http://www.filibeto.org/~aduritz/truetrue/solaris10/device-driver-html/faatl.html#ffdqq
> Kernel Code:
> case DDI_MODEL_NONE:
> if (ddi_copyin((void *)arg, &new_len;, sizeof
> (size_t),
> mode) != 0)
> return (EFAULT);
>
> break;
>
> User Code:
> static void
> set_size(const char *dev, size_t sz)
> {
> int fd;
>
> if ((fd = open(dev, O_RDWR)) < 0) {
> perror("open");
>
> exit(3);
> }
>
> if (ioctl(fd, QOTDIOCSSZ, &sz;) < 0) {
> perror("QOTDIOCSSZ");
> exit(4);
> }
>
> (void) close(fd);
>
> }
> I am able to ge this to work by declaring a size32_t in the kernel
> code, looks like size_t is 64 bit in kernel space by default.
Yes, you have to deal with the differences between a 64-bit kernel and
32-bit userland programs.
There are standard ways to do this. What you do is use
ddi_model_convert_from()... the man page has some example code.
>
> So I was trying to change this to copy strings instead. Thanks for
> the advice, I will try out some of the suggestions, but I figured this
> would provide better context to my question.
Here's at least one way to copy a string:
struct mybuf {
size_t count;
char *buffer;
};
#ifdef _KERNEL
struct mybuf32 {
size32_t count;
caddr32_t buffer;
}
#endif
switch (ddi_model_convert_from(mode & FMODELS)) {
case DDI_MODEL_ILP32:
{
struct mybuf32 mb32;
if (ddi_copyin(arg, &mb32, sizeof (mb32), mode) != DDI_SUCCESS)
return (EFAULT);
mb.count = mb32.count;
mb.buffer = mb32.buffer;
break;
}
default:
if (ddi_copyin(arg, &mb, sizeof (mb), mode) != DDI_SUCCESS)
return (EFAULT);
}
str = kmem_zalloc(mb.count, KM_SLEEP);
if (ddi_copyin(mb.buffer, str, mb.count, mode) != DDI_SUCCESS) {
kmem_free(str, mb.count);
return (EFAULT);
}
/* now str is available for use ... */
>
> -Matt
>
> On 8/9/07, Darren J Moffat <[EMAIL PROTECTED]> wrote:
> Matt Bailey wrote:
> > I'm trying to use ddi_copyin to copy a string from a user
> application to a psuedo driver in kernel space.
> >
> > How do I copy data and print it out? Anyone know of any
> resources I can look at with an example?
> >
> > Here's the ioctl code:
> >
> > char *strPtr, *string;
> > ...
> > case STR_COPY:
> > ddi_copyin((char *)arg, strPtr,
> sizeof (char*), mode);
> > strcpy(string, strPtr); // EXPLODES
> HERE
> > break;
>
> Did you kmem_alloc(9F) space for strPtr ? Also I'm pretty
> sure that you
> don't want sizeof (char *) as the 3rd argument to ddi_copyin
> but the
> actual size.
>
> Are you 100% sure it is the strcpy that is causing the panic
> and not the
> ddi_copyin ? Also what is mode set to ?
>
> As for actually printing it out, I tend to use cmn_err with
> CE_NOTE if I
> really want to do that rather than just stopping in the
> function with
> mdb and displaying the data.
>
> In general it is normal to define a struct that is shared
> between user
> and kernel space and in that struct you would have size
> information for
> any variable size data. Note that you need to be careful
> about using
> generic types like size_t or uint_t if you do this, always be
> explicit,
> eg uint32_t or uint64_t so that you reduce the likely hood of
> problems
> with 32 bit app and 64 bit kernel.
>
>
> --
> Darren J Moffat
>
> _______________________________________________
> opensolaris-code mailing list
> [email protected]
> http://mail.opensolaris.org/mailman/listinfo/opensolaris-code
_______________________________________________
opensolaris-code mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code