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