Annotation of Examples/UNIX/LKSOutOfLineData/KernelServer/mydriver_main.c, revision 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.