|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.