我想在Mac OS上实现kext和应用程序之间的IPC。当我尝试将数据从app传输到kext时,我遇到了一些问题。
互联网上的一些示例需要更多系统功能来在Mac上实现Mach IPC编程,例如设置服务器(bootstrap_create_service)或获取服务器端口(bootstrap_look_up)。但是我不能使用除kernel.framework之外的其他框架或系统标准库来进行kext编程。
所以这是我的问题:有没有其他方法可以在kext或其他方法中获得系统级支持(如bootstrap_create_service函数)以在kernel.framework中实现IPC?
非常感谢..
此外,在kernel.framework中,我不能使用mmap(),open()在kext和app之间共享内存。
http://flylib.com/books/en/3.126.1.90/1/的一个例子: 像:
服务器端代码:
char *ptr;
kern_return_t kr;
mach_vm_address_t address = 0;
memory_object_size_t size = (memory_object_size_t)vm_page_size;
mach_port_t object_handle = MACH_PORT_NULL;
msg_format_request_r_t recv_msg;
msg_format_response_t send_msg;
mach_msg_header_t *recv_hdr, *send_hdr;
mach_port_t server_port;
kr = mach_vm_allocate(mach_task_self(),
&address,
size,
VM_FLAGS_ANYWHERE);
printf("memory allocated at %p\n", (void *)address);
// Create a named entry corresponding to the given mapped portion of our
// address space. We can then share this named entry with other tasks.
kr = mach_make_memory_entry_64( (vm_map_t)mach_task_self(), // target address map
&size, // so many bytes
(memory_object_offset_t)address, // at this address
(vm_prot_t)(VM_PROT_READVM_PROT_WRITE), // with these permissions
(mem_entry_name_port_t *)&object_handle, // outcoming object handle
(mem_entry_name_port_t)NULL); // parent handle
// ideally we should vm_deallocate() before we exit
// put some data into the shared memory
ptr = (char *)address;
strcpy(ptr, "Hello, Mach!");
// become a Mach server
kr = bootstrap_create_service(bootstrap_port, SERVICE_NAME, &server_port);
//EXIT_ON_MACH_ERROR("bootstrap_create_service", kr, BOOTSTRAP_SUCCESS);
kr = bootstrap_check_in(bootstrap_port, SERVICE_NAME, &server_port);
//EXIT_ON_MACH_ERROR("bootstrap_check_in", kr, BOOTSTRAP_SUCCESS);
for (;;) {
// server loop
// receive a message
recv_hdr = &(recv_msg.header);
recv_hdr->msgh_local_port = server_port;
recv_hdr->msgh_size = sizeof(recv_msg);
kr = mach_msg(recv_hdr, // message buffer
MACH_RCV_MSG, // option indicating service
0, // send size
recv_hdr->msgh_size, // size of header + body
server_port, // receive name
MACH_MSG_TIMEOUT_NONE, // no timeout, wait forever
MACH_PORT_NULL); // no notification port
EXIT_ON_MACH_ERROR("mach_msg(recv)", kr, KERN_SUCCESS); // send named entry object handle as the reply
send_hdr = &(send_msg.header);
send_hdr->msgh_bits = MACH_MSGH_BITS_LOCAL(recv_hdr->msgh_bits);
send_hdr->msgh_bits = MACH_MSGH_BITS_COMPLEX;
send_hdr->msgh_size = sizeof(send_msg);
send_hdr->msgh_local_port = MACH_PORT_NULL;
send_hdr->msgh_remote_port = recv_hdr->msgh_remote_port;
send_hdr->msgh_id = recv_hdr->msgh_id;
send_msg.body.msgh_descriptor_count = 1;
send_msg.data.name = object_handle;
send_msg.data.disposition = MACH_MSG_TYPE_COPY_SEND;
send_msg.data.type = MACH_MSG_PORT_DESCRIPTOR;
kr = mach_msg(send_hdr, // message buffer
MACH_SEND_MSG, // option indicating send
send_hdr->msgh_size, // size of header + body
0, // receive limit
MACH_PORT_NULL, // receive name
MACH_MSG_TIMEOUT_NONE, // no timeout, wait forever
MACH_PORT_NULL);
// no notification port
EXIT_ON_MACH_ERROR("mach_msg(send)", kr, KERN_SUCCESS);
}
mach_port_deallocate(mach_task_self(), object_handle);
mach_vm_deallocate(mach_task_self(), address, size);
return kr;
客户端代码:
kern_return_t kr;
msg_format_request_t send_msg;
msg_format_response_r_t recv_msg;
mach_msg_header_t *send_hdr, *recv_hdr;
mach_port_t client_port, server_port, object_handle;
// find the server
kr = bootstrap_look_up(bootstrap_port, SERVICE_NAME, &server_port);
// allocate a port for receiving the server's reply
kr = mach_port_allocate(mach_task_self(), // our task is acquiring
MACH_PORT_RIGHT_RECEIVE, // a new receive right
&client_port);
// prepare and send a request message to the server
send_hdr = &(send_msg.header);
send_hdr->msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MAKE_SEND);
send_hdr->msgh_size = sizeof(send_msg);
send_hdr->msgh_remote_port = server_port;
send_hdr->msgh_local_port = client_port;
send_hdr->msgh_reserved = 0;
send_hdr->msgh_id = SHM_MSG_ID;
kr = mach_msg(send_hdr, // message buffer
MACH_SEND_MSG, // option indicating send
send_hdr->msgh_size, // size of header + body
0, // receive limit
MACH_PORT_NULL, // receive name
MACH_MSG_TIMEOUT_NONE, // no timeout, wait forever
MACH_PORT_NULL); // no notification port
do {
recv_hdr = &(recv_msg.header);
recv_hdr->msgh_remote_port = server_port;
recv_hdr->msgh_local_port = client_port;
recv_hdr->msgh_size = sizeof(recv_msg);
recv_msg.data.name = 0;
kr = mach_msg(recv_hdr, // message buffer
MACH_RCV_MSG, // option indicating receive
0, // send size
recv_hdr->msgh_size, // size of header + body
client_port, // receive name
MACH_MSG_TIMEOUT_NONE, // no timeout, wait forever
MACH_PORT_NULL); // no notification port
printf("recv_msg.data.name = %#08x\n", recv_msg.data.name);
object_handle = recv_msg.data.name;
{
// map the specified memory object to a region of our address space
mach_vm_size_t size = vm_page_size;
mach_vm_address_t address = 0;
kr = mach_vm_map( mach_task_self(), // target address space (us)
(mach_vm_address_t *)&address, // map it and tell us where
(mach_vm_size_t)size, // number of bytes to allocate
(mach_vm_offset_t)0, // address mask for alignment
TRUE, // map it anywhere
(mem_entry_name_port_t)object_handle, // the memory object
(memory_object_offset_t)0, // offset within memory object
FALSE, // don't copy -- directly map
VM_PROT_READVM_PROT_WRITE, // current protection
VM_PROT_READVM_PROT_WRITE, // maximum protection
VM_INHERIT_NONE);
// inheritance properties
if (kr != KERN_SUCCESS)
mach_error("vm_map", kr);
else {
// display the current contents of the memory
printf("%s\n", (char *)address);
if (argc == 2) {
// write specified string to the memory
printf("writing \"%s\" to shared memory\n", argv[1]);
strncpy((char *)address, argv[1], (size_t)size);
((char *)address)[size - 1] = '';
}
mach_vm_deallocate(mach_task_self(), address, size);
}
}
} while (recv_hdr->msgh_id != SHM_MSG_ID);
exit(0);
答案 0 :(得分:1)
在我自己开发内核扩展的工作中,Apple确实一直在推动开发人员使用"Kernel Control" sockets, which are elaborated upon here。这适用于网络内核扩展,而对于其他关键字,您还有一些其他选项,包括BSD通知,内核队列和扩展。事件,文件系统事件等These options (plus a few others you might recognize) are described in this Apple documentation。