exec_multiboot1.c revision 1.1 1 /* $NetBSD: exec_multiboot1.c,v 1.1 2019/09/13 02:19:46 manu Exp $ */
2
3 /*
4 * Copyright (c) 2019 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
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
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
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
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
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/param.h>
30 #include <sys/reboot.h>
31
32 #include <i386/multiboot.h>
33
34 #include <lib/libsa/stand.h>
35 #include <lib/libkern/libkern.h>
36
37 #include "loadfile.h"
38 #include "libi386.h"
39 #include "bootinfo.h"
40 #include "bootmod.h"
41 #include "vbe.h"
42
43 extern struct btinfo_modulelist *btinfo_modulelist;
44
45 static int
46 exec_multiboot1(struct multiboot_package *mbp)
47 {
48 struct multiboot_info *mbi;
49 struct multiboot_module *mbm;
50 int i, len;
51 char *cmdline;
52 struct bi_modulelist_entry *bim;
53
54 mbi = alloc(sizeof(struct multiboot_info));
55 mbi->mi_flags = MULTIBOOT_INFO_HAS_MEMORY;
56
57 mbi->mi_mem_upper = mbp->mbp_extmem;
58 mbi->mi_mem_lower = mbp->mbp_basemem;
59
60 if (mbp->mbp_args) {
61 mbi->mi_flags |= MULTIBOOT_INFO_HAS_CMDLINE;
62 len = strlen(mbp->mbp_file) + 1 + strlen(mbp->mbp_args) + 1;
63 cmdline = alloc(len);
64 snprintf(cmdline, len, "%s %s", mbp->mbp_file, mbp->mbp_args);
65 mbi->mi_cmdline = (char *) vtophys(cmdline);
66 }
67
68 /* pull in any modules if necessary */
69 if (btinfo_modulelist) {
70 mbm = alloc(sizeof(struct multiboot_module) *
71 btinfo_modulelist->num);
72
73 bim = (struct bi_modulelist_entry *)
74 (((char *) btinfo_modulelist) +
75 sizeof(struct btinfo_modulelist));
76 for (i = 0; i < btinfo_modulelist->num; i++) {
77 mbm[i].mmo_start = bim->base;
78 mbm[i].mmo_end = bim->base + bim->len;
79 mbm[i].mmo_string = (char *)vtophys(bim->path);
80 mbm[i].mmo_reserved = 0;
81 bim++;
82 }
83 mbi->mi_flags |= MULTIBOOT_INFO_HAS_MODS;
84 mbi->mi_mods_count = btinfo_modulelist->num;
85 mbi->mi_mods_addr = vtophys(mbm);
86 }
87
88 #ifdef DEBUG
89 printf("Start @ 0x%lx [%ld=0x%lx-0x%lx]...\n",
90 mbp->mbp_marks[MARK_ENTRY],
91 mbp->mbp_marks[MARK_NSYM],
92 mbp->mbp_marks[MARK_SYM],
93 mbp->mbp_marks[MARK_END]);
94 #endif
95
96 /* Does not return */
97 multiboot(mbp->mbp_marks[MARK_ENTRY], vtophys(mbi),
98 x86_trunc_page(mbi->mi_mem_lower * 1024), MULTIBOOT_INFO_MAGIC);
99
100 return 0;
101 }
102
103 static void
104 cleanup_multiboot1(struct multiboot_package *mbp)
105 {
106 dealloc(mbp->mbp_header, sizeof(*mbp->mbp_header));
107 dealloc(mbp, sizeof(*mbp));
108
109 return;
110 }
111
112
113 struct multiboot_package *
114 probe_multiboot1(const char *path)
115 {
116 int fd = -1;
117 size_t i;
118 char buf[8192 + sizeof(struct multiboot_header)];
119 ssize_t readen;
120 struct multiboot_package *mbp = NULL;
121
122 if ((fd = open(path, 0)) == -1)
123 goto out;
124
125 readen = read(fd, buf, sizeof(buf));
126 if (readen < sizeof(struct multiboot_header))
127 goto out;
128
129 for (i = 0; i < readen; i += 8) {
130 struct multiboot_header *mbh;
131
132 mbh = (struct multiboot_header *)(buf + i);
133
134 if (mbh->mh_magic != MULTIBOOT_HEADER_MAGIC)
135 continue;
136
137 if (mbh->mh_magic + mbh->mh_flags + mbh->mh_checksum)
138 continue;
139
140 mbp = alloc(sizeof(*mbp));
141 mbp->mbp_version = 1;
142 mbp->mbp_file = path;
143 mbp->mbp_header = alloc(sizeof(*mbp->mbp_header));
144 mbp->mbp_probe = *probe_multiboot1;
145 mbp->mbp_exec = *exec_multiboot1;
146 mbp->mbp_cleanup = *cleanup_multiboot1;
147
148 memcpy(mbp->mbp_header, mbh, sizeof(*mbp->mbp_header));
149
150 goto out;
151
152 }
153
154 out:
155 if (fd != -1)
156 close(fd);
157
158 return mbp;
159 }
160