| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: kloader.c,v 1.31 2021/10/11 14:16:43 rin Exp $ */ | | 1 | /* $NetBSD: kloader.c,v 1.32 2021/10/11 14:25:05 rin Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2001, 2002, 2004 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2001, 2002, 2004 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -17,33 +17,33 @@ | | | @@ -17,33 +17,33 @@ |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. | | 26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __KERNEL_RCSID(0, "$NetBSD: kloader.c,v 1.31 2021/10/11 14:16:43 rin Exp $"); | | 30 | __KERNEL_RCSID(0, "$NetBSD: kloader.c,v 1.32 2021/10/11 14:25:05 rin Exp $"); |
31 | | | 31 | |
32 | #include "debug_kloader.h" | | 32 | #include "debug_kloader.h" |
33 | | | 33 | |
34 | #include <sys/param.h> | | 34 | #include <sys/param.h> |
35 | #include <sys/fcntl.h> | | 35 | #include <sys/fcntl.h> |
36 | #include <sys/malloc.h> | | 36 | #include <sys/kmem.h> |
37 | #include <sys/namei.h> | | 37 | #include <sys/namei.h> |
38 | #include <sys/proc.h> | | 38 | #include <sys/proc.h> |
39 | #include <sys/systm.h> | | 39 | #include <sys/systm.h> |
40 | #include <sys/vnode.h> | | 40 | #include <sys/vnode.h> |
41 | | | 41 | |
42 | #define ELFSIZE 32 | | 42 | #define ELFSIZE 32 |
43 | #include <sys/exec_elf.h> | | 43 | #include <sys/exec_elf.h> |
44 | | | 44 | |
45 | #include <uvm/uvm_extern.h> | | 45 | #include <uvm/uvm_extern.h> |
46 | | | 46 | |
47 | #include <machine/kloader.h> | | 47 | #include <machine/kloader.h> |
48 | | | 48 | |
49 | #define PRINTF(fmt, args...) printf("kloader: " fmt, ##args) | | 49 | #define PRINTF(fmt, args...) printf("kloader: " fmt, ##args) |
| @@ -164,75 +164,75 @@ kloader_reboot(void) | | | @@ -164,75 +164,75 @@ kloader_reboot(void) |
164 | /* NOTREACHED */ | | 164 | /* NOTREACHED */ |
165 | } | | 165 | } |
166 | | | 166 | |
167 | | | 167 | |
168 | int | | 168 | int |
169 | kloader_load(void) | | 169 | kloader_load(void) |
170 | { | | 170 | { |
171 | Elf_Ehdr eh; | | 171 | Elf_Ehdr eh; |
172 | Elf_Phdr *ph, *p; | | 172 | Elf_Phdr *ph, *p; |
173 | Elf_Shdr *sh; | | 173 | Elf_Shdr *sh; |
174 | Elf_Addr entry; | | 174 | Elf_Addr entry; |
175 | vaddr_t kv; | | 175 | vaddr_t kv; |
176 | size_t sz; | | 176 | size_t sz; |
177 | size_t shstrsz; | | 177 | size_t phsz, shsz, shstrsz; |
178 | char *shstrtab; | | 178 | char *shstrtab; |
179 | int symndx, strndx; | | 179 | int symndx, strndx; |
180 | size_t ksymsz; | | 180 | size_t ksymsz; |
181 | struct kloader_bootinfo nbi; /* new boot info */ | | 181 | struct kloader_bootinfo nbi; /* new boot info */ |
182 | char *oldbuf, *newbuf; | | 182 | char *oldbuf, *newbuf; |
183 | char **ap; | | 183 | char **ap; |
184 | int i; | | 184 | int i; |
185 | | | 185 | |
186 | ph = NULL; | | 186 | ph = NULL; |
187 | sh = NULL; | | 187 | sh = NULL; |
188 | shstrtab = NULL; | | 188 | shstrtab = NULL; |
189 | | | 189 | |
190 | /* read kernel's ELF header */ | | 190 | /* read kernel's ELF header */ |
191 | kloader_read(0, sizeof(Elf_Ehdr), &eh); | | 191 | kloader_read(0, sizeof(Elf_Ehdr), &eh); |
192 | | | 192 | |
193 | if (eh.e_ident[EI_MAG0] != ELFMAG0 || | | 193 | if (eh.e_ident[EI_MAG0] != ELFMAG0 || |
194 | eh.e_ident[EI_MAG1] != ELFMAG1 || | | 194 | eh.e_ident[EI_MAG1] != ELFMAG1 || |
195 | eh.e_ident[EI_MAG2] != ELFMAG2 || | | 195 | eh.e_ident[EI_MAG2] != ELFMAG2 || |
196 | eh.e_ident[EI_MAG3] != ELFMAG3) { | | 196 | eh.e_ident[EI_MAG3] != ELFMAG3) { |
197 | PRINTF("not an ELF file\n"); | | 197 | PRINTF("not an ELF file\n"); |
198 | goto err; | | 198 | goto err; |
199 | } | | 199 | } |
200 | | | 200 | |
201 | /* read program headers */ | | 201 | /* read program headers */ |
202 | sz = eh.e_phentsize * eh.e_phnum; | | 202 | phsz = eh.e_phentsize * eh.e_phnum; |
203 | if ((ph = malloc(sz, M_TEMP, M_NOWAIT)) == NULL) { | | 203 | if ((ph = kmem_alloc(phsz, KM_NOSLEEP)) == NULL) { |
204 | PRINTF("can't allocate program header table.\n"); | | 204 | PRINTF("can't allocate program header table.\n"); |
205 | goto err; | | 205 | goto err; |
206 | } | | 206 | } |
207 | if (kloader_read(eh.e_phoff, sz, ph) != 0) { | | 207 | if (kloader_read(eh.e_phoff, phsz, ph) != 0) { |
208 | PRINTF("program header read error.\n"); | | 208 | PRINTF("program header read error.\n"); |
209 | goto err; | | 209 | goto err; |
210 | } | | 210 | } |
211 | | | 211 | |
212 | /* read section headers */ | | 212 | /* read section headers */ |
213 | sz = eh.e_shentsize * eh.e_shnum; | | 213 | shsz = eh.e_shentsize * eh.e_shnum; |
214 | if ((sh = malloc(sz, M_TEMP, M_NOWAIT)) == NULL) { | | 214 | if ((sh = kmem_alloc(shsz, KM_NOSLEEP)) == NULL) { |
215 | PRINTF("can't allocate section header table.\n"); | | 215 | PRINTF("can't allocate section header table.\n"); |
216 | goto err; | | 216 | goto err; |
217 | } | | 217 | } |
218 | if (kloader_read(eh.e_shoff, eh.e_shentsize * eh.e_shnum, sh) != 0) { | | 218 | if (kloader_read(eh.e_shoff, shsz, sh) != 0) { |
219 | PRINTF("section header read error.\n"); | | 219 | PRINTF("section header read error.\n"); |
220 | goto err; | | 220 | goto err; |
221 | } | | 221 | } |
222 | | | 222 | |
223 | /* read section names */ | | 223 | /* read section names */ |
224 | shstrsz = ROUND4(sh[eh.e_shstrndx].sh_size); | | 224 | shstrsz = ROUND4(sh[eh.e_shstrndx].sh_size); |
225 | shstrtab = malloc(shstrsz, M_TEMP, M_NOWAIT); | | 225 | shstrtab = kmem_alloc(shstrsz, KM_NOSLEEP); |
226 | if (shstrtab == NULL) { | | 226 | if (shstrtab == NULL) { |
227 | PRINTF("unable to allocate memory for .shstrtab\n"); | | 227 | PRINTF("unable to allocate memory for .shstrtab\n"); |
228 | goto err; | | 228 | goto err; |
229 | } | | 229 | } |
230 | DPRINTF("reading 0x%x bytes of .shstrtab at 0x%x\n", | | 230 | DPRINTF("reading 0x%x bytes of .shstrtab at 0x%x\n", |
231 | sh[eh.e_shstrndx].sh_size, sh[eh.e_shstrndx].sh_offset); | | 231 | sh[eh.e_shstrndx].sh_size, sh[eh.e_shstrndx].sh_offset); |
232 | kloader_read(sh[eh.e_shstrndx].sh_offset, sh[eh.e_shstrndx].sh_size, | | 232 | kloader_read(sh[eh.e_shstrndx].sh_offset, sh[eh.e_shstrndx].sh_size, |
233 | shstrtab); | | 233 | shstrtab); |
234 | | | 234 | |
235 | /* save entry point, code to construct symbol table overwrites it */ | | 235 | /* save entry point, code to construct symbol table overwrites it */ |
236 | entry = eh.e_entry; | | 236 | entry = eh.e_entry; |
237 | | | 237 | |
238 | /* | | 238 | /* |
| @@ -406,31 +406,31 @@ kloader_load(void) | | | @@ -406,31 +406,31 @@ kloader_load(void) |
406 | KDASSERT(kloader.cur_pg); | | 406 | KDASSERT(kloader.cur_pg); |
407 | kloader.loader = (void *)PG_VADDR(kloader.cur_pg); | | 407 | kloader.loader = (void *)PG_VADDR(kloader.cur_pg); |
408 | memcpy(kloader.loader, kloader.ops->boot, PAGE_SIZE); | | 408 | memcpy(kloader.loader, kloader.ops->boot, PAGE_SIZE); |
409 | | | 409 | |
410 | /* loader stack starts at the bottom of that page */ | | 410 | /* loader stack starts at the bottom of that page */ |
411 | kloader.loader_sp = (vaddr_t)kloader.loader + PAGE_SIZE; | | 411 | kloader.loader_sp = (vaddr_t)kloader.loader + PAGE_SIZE; |
412 | | | 412 | |
413 | DPRINTF("[loader] addr=%p sp=%p [kernel] entry=%p\n", | | 413 | DPRINTF("[loader] addr=%p sp=%p [kernel] entry=%p\n", |
414 | kloader.loader, (void *)kloader.loader_sp, (void *)nbi.entry); | | 414 | kloader.loader, (void *)kloader.loader_sp, (void *)nbi.entry); |
415 | | | 415 | |
416 | return (0); | | 416 | return (0); |
417 | err: | | 417 | err: |
418 | if (ph != NULL) | | 418 | if (ph != NULL) |
419 | free(ph, M_TEMP); | | 419 | kmem_free(ph, phsz); |
420 | if (sh != NULL) | | 420 | if (sh != NULL) |
421 | free(sh, M_TEMP); | | 421 | kmem_free(sh, shsz); |
422 | if (shstrtab != NULL) | | 422 | if (shstrtab != NULL) |
423 | free(shstrtab, M_TEMP); | | 423 | kmem_free(shstrtab, shstrsz); |
424 | | | 424 | |
425 | return 1; | | 425 | return 1; |
426 | } | | 426 | } |
427 | | | 427 | |
428 | | | 428 | |
429 | int | | 429 | int |
430 | kloader_alloc_memory(size_t sz) | | 430 | kloader_alloc_memory(size_t sz) |
431 | { | | 431 | { |
432 | int n, error; | | 432 | int n, error; |
433 | | | 433 | |
434 | n = (sz + BUCKET_SIZE - 1) / BUCKET_SIZE /* kernel &co */ | | 434 | n = (sz + BUCKET_SIZE - 1) / BUCKET_SIZE /* kernel &co */ |
435 | + 1; /* 2nd loader */ | | 435 | + 1; /* 2nd loader */ |
436 | | | 436 | |