Re: cross-bounday memory communication b/w user app and the Kernel.How?
Re: cross-bounday memory communication b/w user app and the Kernel.How?
- Subject: Re: cross-bounday memory communication b/w user app and the Kernel.How?
- From: "rohit dhamija" <email@hidden>
- Date: Fri, 2 Jun 2006 09:36:15 +0530
Thanks a lot for your comments !! Your suggestions are very good and valuable.
B/w i have one query ,
Create the IOMemoryDescriptors directly against the user-space
addresses and do your I/O with those.
At this point i have memory of type IOMemoryDescriptor*. But Now I
need to copy some information in this memory. So is it fine to copy
using memcopy :to copy information in descr (of type
IOMemoryDescriptor* ) ??
like
IOMemoryDescriptor * outDescriptor = NULL;
// Get the data into kernel space
outDescriptor = IOMemoryDescriptor::withAddress(
(vm_address_t)pComm->command_payload,
sizeof(command_structure),
kIODirectionOut,
fClientTask);
now I need to copy some data into
so is it fine to do:
memcpy((void*)&outDescriptor, mydataBuffer, sizeof(MYDATABUFFER));
IF not, then how to copy/fill info in the descriptor ?
Please correct me if I am going wrong.
Regards,
Rohit Dhamija
When I get the data into kernel using IOMemoryDescriptor
On 6/1/06, Michael Smith <email@hidden> wrote:
On Jun 1, 2006, at 9:51 AM, rohit dhamija wrote:
> 1) Shared structure
> Below is the common structure to be shared by user and kernel
> application for communication across user-kernel boundary:
>
> //////
> typedef struct _CS {
> int cmd; // my command number
> void* cmd_payload; // command payload
> void* response; // response
> } COMMAND_STRUCTURE, *PCOMMAND_STRUCTURE;
> //////
>
> Note: The maximum size of command payload was of 4272 bytes , so i
> want to send the command with the required bytes (and not the whole
> structure, as void* com_payload)
>
> 2) User-Application
> The user application sends the structure to the kernel space, and
> recieve the output in the same structure. So it will be a "Scalar
> Input and Scalar output"
>
> /////////
> kernReturn = IOConnectMethodStructureIStructureO(*dataPort,
> kGnsGetVersion, //cmd
> inBuffSize, //insize
> &outBuffSize, //outSize
> &structIn,
> &structOut);
> /////////
That would be "Structure Input, Scalar output" since your response
buffer
is already in user space. You don't change the structure in the kernel
so there is no need to copy it back out.
> 3) Kernel Level.
> At KEXT level, Now, the main point of discussion is ,"how does the
> kernel allocate/map the user-level structure in kernel and return back
> the data from kernel memory back to user space"?
>
> After studying the apple docs i have come to following conculsion and
> wrote the steps for the same. Following steps needs your
> review/comments ( i am not sure about these steps, so please correct
> me incase i am wrong)
>
> For Sending the data into kernel space from the user-application.
>
> step a) Use IOMemoryDescriptor::withAddress to create and initializes
> an IOMemoryDescriptor
>
> ///////////
> IOMemoryDescriptor *descriptor = NULL;
>
> descriptor = IOMemoryDescriptor::= withAddress(
> address_of_CommandStructure,
> sizeof(command_structure),
> kIODirectionIn, // I am not sure about this , why do we need
> this ?
> kernel_task // since we are passing data into kernel
> );
> //////////////
You need to create the memory descriptor using the client's task, not
the kernel task.
The direction is the default for I/O setup operations (prepare and
complete)
against this descriptor.
You should create two; one with kIODirectionOut for your outbound
buffer,
and one with kIODirectionIn for the response buffer.
> b) Now copy data from the memory descriptor's buffer to the buffer
> allocated in the kernel space.
Why do you do this? Your I/O method uses an IOMemoryDescriptor,
and you have just created these using the user buffers. Copying is
inefficient and wastes memory.
> ///////////////
> ret= descriptor ->prepare( kIODirectionOut );
>
> IOByteCount bytecont = descriptor->readBytes(
> 0, //offset
> myBuff,
> Ientocopy);
>
> descriptor->complete();
> ////////////////
>
> c) Now use this myBuff to communicate with the device.(The module
> works fine)
Again, a waste. Create the IOMemoryDescriptors directly against the
user-space
addresses and do your I/O with those.
> d) now we have got the data say,in outBuff, and this needs to be sent
> back to user space.
> Now at this point, do we need to map output data recieved from the
> device data in-order to send to user space ? If yes, then how ?
>
> Is the method correct ? Or there is some alternate methods available ?
Please see above.
> I also wanted to mention one more thing: In case of my fixed structure
> , mentioned below
>
> //////////
> typedef struct packet{
> unsigned long pid;
> unsigned long cmdId;
> } packet, *ppacket;
> ////////
>
> I have not mapped the data into the kernel space, still it works fine
> i.e the data is successfully sent to communication module and the
> output is successfully sent back to user without any issues.
>
> Is the mapping is required when the data allocation is dynamic ?
Mapping is only required if you need to dereference the contents of
the descriptor. In your case I expect that you do not, so there is no
need to map anything.
PCOMMAND_STRUCTURE pComm;
outDescriptor = IOMemoryDescriptor::withAddress(
(vm_address_t)pComm->command_payload,
sizeof(command_structure),
kIODirectionOut,
fClientTask);
inDescriptor = IOMemoryDescriptor::withAddress(
(vm_address_t)pComm->response,
sizeof(response_structure),
kIODirectionIn,
fClientTask);
outDescriptor->prepare();
inDescriptor->prepare();
result = do_output(outDescriptor);
if (result == kIOReturnSuccess)
result = do_input(inDescriptor);
outDescriptor->complete();
outDescriptor->release();
inDescriptor->complete();
inDescriptor->release();
return(result);
= Mike
--
Rohit Dhamija(M) 9818446545
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden