|
|
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.