Annotation of Examples/UNIX/LKSOutOfLineData/KernelServer/mydriver_main.c, revision 1.1.1.1

1.1       root        1: /* mydriver_main.c:  major functions of mydriver */
                      2: 
                      3: #import <kernserv/kern_server_types.h>
                      4: #import <kernserv/prototypes.h>
                      5: #import <ansi/string.h>
                      6: #import "../Library/mydefs.h"
                      7: 
                      8: kern_server_t instance;
                      9: 
                     10: /* Pointer to hold local data in the kernel_task's vm */
                     11: static user_data_t local_data;
                     12: 
                     13: /* mydriver_init:  Called when mydriver is loaded. */
                     14: void mydriver_init(void)
                     15: {
                     16:     kern_return_t r;
                     17:     port_t kernel_task = kern_serv_kernel_task_port(); 
                     18: 
                     19:     //
                     20:     // Get a page of publically readable vm to be used to access the mig
                     21:     // messages out of line data.  Also used to hold data across import
                     22:     // and export calls.
                     23:     //
                     24:     r = vm_allocate
                     25:        (kernel_task, (vm_address_t *) &local_data, page_size, TRUE);
                     26:     if (r != KERN_SUCCESS)
                     27:     {
                     28:        printf("Call to vm_allocate failed %d\n", r);
                     29:        local_data = NULL;
                     30:     }
                     31: 
                     32:     //
                     33:     // Clear the newly acquired memory
                     34:     //
                     35:     memset(local_data, '\0', page_size);
                     36:     
                     37:     printf("My driver loaded\n");
                     38: }
                     39: 
                     40: 
                     41: /* mydriver_signoff:  Called when mydriver is unloaded. */
                     42: void mydriver_signoff(void)
                     43: {
                     44:     kern_return_t r;
                     45:     port_t kernel_task = kern_serv_kernel_task_port(); 
                     46: 
                     47:     // Deallocate the kernel vm's local_data buffer
                     48:     r = vm_deallocate(kernel_task, (vm_address_t) local_data, page_size);
                     49:     if (r != KERN_SUCCESS)
                     50:     {
                     51:        printf("Call to vm_deallocate failed %d\n", r);
                     52:        local_data = NULL;
                     53:     }
                     54:     
                     55:     printf("My driver unloaded\n\n");
                     56: }
                     57: 
                     58: /* mydriver_import:  Called by mydriver_server, which was created by MiG. */
                     59: kern_return_t mydriver_import
                     60:     (port_t server, in_user_data_t user_data, unsigned int length)
                     61: {
                     62:     kern_return_t r;
                     63:     user_data_t tmp;
                     64:     port_t kernel_task = kern_serv_kernel_task_port(); 
                     65: 
                     66:     if (!local_data)
                     67:        return KERN_FAILURE;
                     68: 
                     69:     //
                     70:     // Warning:  Loadable kernel servers run outside of the kernel task,
                     71:     // even though they use the kernel address map.
                     72:     //
                     73:     // This means that we have to get the task_self's user_data into the
                     74:     // kernel's vm.  To do this we have to, counterintuitively, write the
                     75:     // received data into our previously acquired vm page (kernel_task).
                     76:     //
                     77:     r = vm_write((vm_task_t) kernel_task, (vm_address_t) local_data,
                     78:        (pointer_t) user_data, page_size);
                     79: 
                     80:     if (r == KERN_SUCCESS)
                     81:     {
                     82:        tmp = local_data;
                     83:        printf("\nTrying to access data.\n");
                     84:        printf("First  data element is: %c\n", *tmp++);
                     85:        printf("Second data element is: %c\n", *tmp++);
                     86:        printf("Third  data element is: %c\n", *tmp++);
                     87:        printf("Fourth data element is: %c\n", *tmp++);
                     88:        printf("Fifth  data element is: %c\n", *tmp++);
                     89:        
                     90:        printf("Contents of data are: %s\n", local_data);
                     91:     }
                     92:     else switch(r)
                     93:     {
                     94:     case KERN_INVALID_ARGUMENT:
                     95:            printf("vm_write: KERN_INVALID_ARGUMENT %d\n", r);
                     96:            break;
                     97:     case KERN_PROTECTION_FAILURE:
                     98:            printf("vm_write: KERN_PROTECTION_FAILURE %d\n", r);
                     99:            break;
                    100:     case KERN_INVALID_ADDRESS:
                    101:            printf("vm_write: KERN_INVALID_ADDRESS %d\n", r);
                    102:            break;
                    103:     default:
                    104:            printf("Call to vm_write failed %d\n", r);
                    105:     }
                    106:     
                    107:     // 
                    108:     // Remove the out_of_band data from the kernel server task's vm.
                    109:     // Otherwise we would have a memory leak across the mach message interface.
                    110:     //
                    111:     r = vm_deallocate(task_self(), (vm_address_t) user_data, page_size);
                    112:     if (r != KERN_SUCCESS)
                    113:        printf("Call to vm_deallocate user_data failed %d\n", r);
                    114:     
                    115:     return r;
                    116: }      
                    117: 
                    118: /* mydriver_export:  Called by mydriver_server, which was created by MiG. */
                    119: kern_return_t mydriver_export
                    120:     (port_t server, out_user_data_t *user_data, unsigned int *length)
                    121: {
                    122:     kern_return_t r;
                    123:     port_t kernel_task = kern_serv_kernel_task_port();
                    124:     unsigned int tmp;
                    125:     
                    126:     if (!local_data)
                    127:     {
                    128:        // Get some vm for the mig out of band data to deallocate
                    129:        (void) vm_allocate
                    130:            (task_self(), (vm_address_t *) user_data, page_size, TRUE);
                    131:        
                    132:        return KERN_FAILURE;
                    133:     }
                    134:     
                    135:     // Tack an ACK on the end of the imported data
                    136:     strcat(local_data, "ACK");
                    137:     *length = strlen(local_data) + 1;
                    138:     printf("\nData is: %s\n", local_data);
                    139: 
                    140:     //
                    141:     // Warning:  Loadable kernel servers run outside of the kernel task,
                    142:     // even though they use the kernel address map.
                    143:     //
                    144:     // This means that we have to load the task_self's user_data pointer from
                    145:     // the kernel's vm.  To do this we have to, counterintuitively again,
                    146:     // vm_read the local_data into our task's vm, NB we do not have to
                    147:     // previously allocate the vm.  The vm_read data will be deallocated
                    148:     // automatically by the mach message system as the type was declared
                    149:     // with dealloc on the mig type.
                    150:     //
                    151:     r = vm_read((vm_task_t) kernel_task, (vm_address_t) local_data,
                    152:            page_size, (pointer_t *) user_data, &tmp);
                    153:     if (r != KERN_SUCCESS)
                    154:     {
                    155:        // Get some vm for the mig out of band data to deallocate
                    156:        (void) vm_allocate
                    157:            (task_self(), (vm_address_t *) user_data, page_size, TRUE);
                    158:        
                    159:        switch (r)
                    160:        {
                    161:        case KERN_INVALID_ARGUMENT:
                    162:                printf("vm_read: KERN_INVALID_ARGUMENT %d\n", r);       break;
                    163:        case KERN_NO_SPACE:
                    164:                printf("vm_read: KERN_NO_SPACE %d\n", r);               break;
                    165:        case KERN_PROTECTION_FAILURE:
                    166:                printf("vm_read: KERN_PROTECTION_FAILURE %d\n", r);     break;
                    167:        case KERN_INVALID_ADDRESS:
                    168:                printf("vm_read: KERN_INVALID_ADDRESS %d\n", r);        break;
                    169:        default: printf("Call to vm_read failed: %d\n", r);             break;
                    170:        }
                    171:     }
                    172: 
                    173:     //
                    174:     // No matter what path we take through this function we always have some
                    175:     // disposable vm in task_self's memory for dealloc-ing.
                    176:     //
                    177:     return r;
                    178: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.