17 |
|
|
18 |
#include "tm.h" |
#include "tm.h" |
19 |
#include "bootstrap.h" |
#include "bootstrap.h" |
20 |
|
#include "trace.h" |
21 |
|
#include "task.h" |
22 |
|
#include "thread.h" |
23 |
|
#include "objfmt-elf.h" |
24 |
|
|
25 |
/* Array of loaded modules. */ |
/* Array of loaded modules. */ |
26 |
|
|
27 |
struct bootstrap bootstrap_modules [MAX_BOOTSTRAP_MODULES]; |
struct bootstrap bootstrap_modules [MAX_BOOTSTRAP_MODULES]; |
28 |
|
|
29 |
/* Number of loaded modules. */ |
/* Number of loaded modules. */ |
30 |
|
|
31 |
int bootstrap_count = 0; |
int bootstrap_count = 0; |
32 |
|
|
33 |
|
/* Bootstrap task. */ |
34 |
|
|
35 |
|
static struct task *bootstrap_task; |
36 |
|
|
37 |
|
/* Function for reading SIZE bytes at OFFSET into buffer DST. |
38 |
|
Number of bytes actual read returned in ACTUAL_SIZE. */ |
39 |
|
|
40 |
|
static int |
41 |
|
fmt_read_fn (void *handle, vm_offset_t offset, void *dst, |
42 |
|
vm_size_t size, vm_size_t *actual_size) |
43 |
|
{ |
44 |
|
memcpy (dst, (void *) (handle + offset), size); |
45 |
|
*actual_size = size; |
46 |
|
return 0; |
47 |
|
} |
48 |
|
|
49 |
|
/* Function for writing FSIZE bytes from FOFFSET into virtual |
50 |
|
address VOFFSET. Allocate VSIZE bytes for memory object. |
51 |
|
Memory protection is specified with PROTECTION. */ |
52 |
|
|
53 |
|
static int |
54 |
|
fmt_write_fn (void *handle, vm_offset_t foffset, vm_size_t fsize, |
55 |
|
vm_offset_t voffset, vm_size_t vsize, vm_prot_t protection) |
56 |
|
{ |
57 |
|
struct vm_object *object; |
58 |
|
vm_offset_t offset; |
59 |
|
kern_return_t kr; |
60 |
|
|
61 |
|
trace_printf ("should write %d bytes at %x", vsize, voffset); |
62 |
|
trace_printf ("foffset %x, fsize %d, prot %d", foffset, fsize, |
63 |
|
protection); |
64 |
|
|
65 |
|
vsize = vm_round_page (vsize); |
66 |
|
object = vm_object_allocate (vsize); |
67 |
|
|
68 |
|
kr = vm_map_enter (bootstrap_task->map, voffset, vsize, object, |
69 |
|
VM_PROT_ALL, VM_PROT_ALL, VM_INHERIT_NONE); |
70 |
|
if (kr != KERN_SUCCESS) |
71 |
|
return kr; |
72 |
|
|
73 |
|
trace_printf ("kr = %d", kr); |
74 |
|
|
75 |
|
copyout (voffset, (vm_offset_t) (handle + foffset), fsize); |
76 |
|
|
77 |
|
/* ??? vm_map_protect (...) */ |
78 |
|
|
79 |
|
return 0; |
80 |
|
} |
81 |
|
|
82 |
|
/* "Bootstrap bootstrap" thread function. ARG is unused. */ |
83 |
|
|
84 |
|
static void |
85 |
|
bootstrap_thread_fn (void *arg) |
86 |
|
{ |
87 |
|
struct bootstrap *boostrap = & bootstrap_modules [0]; |
88 |
|
vm_offset_t entry_point; |
89 |
|
kern_return_t kr; |
90 |
|
|
91 |
|
trace_printf ("bootstrap fn"); |
92 |
|
|
93 |
|
kr = elf_load ((void *) boostrap->offset, fmt_read_fn, fmt_write_fn, |
94 |
|
& entry_point); |
95 |
|
trace_printf ("kr = %d", kr); |
96 |
|
|
97 |
|
for (;;) |
98 |
|
; |
99 |
|
} |
100 |
|
|
101 |
|
/* Initialize the bootstrap. */ |
102 |
|
|
103 |
|
void |
104 |
|
bootstrap_init (void) |
105 |
|
{ |
106 |
|
struct thread *bootstrap_thread; |
107 |
|
kern_return_t kr; |
108 |
|
|
109 |
|
/* We can not do without a bootstrap. */ |
110 |
|
|
111 |
|
if (bootstrap_count == 0) |
112 |
|
panic ("No bootstrap loaded with the kernel!"); |
113 |
|
|
114 |
|
/* Create bootstrap task and one bootstrap thread. */ |
115 |
|
|
116 |
|
kr = task_create (TASK_KERNEL (), false, &bootstrap_task); |
117 |
|
assert (kr == KERN_SUCCESS); |
118 |
|
|
119 |
|
kr = thread_create (bootstrap_task, &bootstrap_thread); |
120 |
|
assert (kr == KERN_SUCCESS); |
121 |
|
|
122 |
|
/* Give the thread a kernel stack and put it on a run queue. */ |
123 |
|
|
124 |
|
thread_start (bootstrap_thread, bootstrap_thread_fn, 0); |
125 |
|
thread_setrun (bootstrap_thread, false); |
126 |
|
} |