1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
$NetBSD: patch-ah,v 1.2 1999/12/18 22:10:02 christos Exp $
--- doscmd_loader.c.orig Fri Dec 17 22:48:20 1999
+++ doscmd_loader.c Sat Dec 18 17:01:53 1999
@@ -31,38 +31,50 @@
*/
#include <stdio.h>
-#include <a.out.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
/*
* reserve space in "low" memory for the interrupt vector table
*/
static const char filler[4096] = { 0, };
-#define _PATH_DOS_KERNEL_DIR "%PREFIX%/libexec/"
+#define _PATH_DOS_KERNEL_DIR "/usr/pkg/libexec/"
#define _PATH_DOS_KERNEL "doscmd.kernel"
-int
+static char *locations[] = {
+ _PATH_DOS_KERNEL,
+ "obj/" _PATH_DOS_KERNEL,
+ _PATH_DOS_KERNEL_DIR _PATH_DOS_KERNEL,
+ NULL
+};
+
+u_long
load_kernel(void)
{
- FILE *fp;
- struct exec exec;
- int start_address;
-
- if ((fp = fopen(_PATH_DOS_KERNEL, "r")) == NULL &&
- (fp = fopen("obj/" _PATH_DOS_KERNEL, "r")) == NULL &&
- (fp = fopen(_PATH_DOS_KERNEL_DIR _PATH_DOS_KERNEL, "r")) == NULL)
+ int i, fd;
+ size_t size;
+ struct stat st;
+
+ for (i = 0; locations[i] != NULL; i++) {
+ if ((fd = open(locations[i], O_RDONLY)) != -1)
+ break;
+ }
+ if (locations[i] == NULL)
err(1, "load_kernel");
- if (fread(&exec, sizeof(exec), 1, fp) != 1 || N_GETMAGIC(exec) != OMAGIC)
- errx(1, "bad kernel file format");
+ if (fstat(fd, &st) == -1)
+ err(1, "fstat");
- start_address = exec.a_entry & (~(getpagesize() - 1));
- if (brk(start_address + exec.a_text + exec.a_data + exec.a_bss) < 0)
- err(1, "load_kernel");
- fread((char *)start_address, exec.a_text + exec.a_data, 1, fp);
- bzero((char *)(start_address + exec.a_text + exec.a_data), exec.a_bss);
- fclose(fp);
- return(exec.a_entry);
+ size = st.st_size + START_ADDRESS;
+
+ if (mmap((void *)START_ADDRESS, st.st_size,
+ PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0) == MAP_FAILED)
+ err(1, "mmap");
+
+ return(START_ADDRESS);
}
void
|