Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/i386/libi386/bootinfo32.c
34860 views
1
/*-
2
* Copyright (c) 1998 Michael Smith <[email protected]>
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
#include <stand.h>
28
#include <sys/param.h>
29
#include <sys/reboot.h>
30
#include <sys/linker.h>
31
#include <machine/bootinfo.h>
32
#include <machine/metadata.h>
33
#include "bootstrap.h"
34
#include "modinfo.h"
35
#include "libi386.h"
36
#include "btxv86.h"
37
38
#ifdef LOADER_GELI_SUPPORT
39
#include "geliboot.h"
40
#endif
41
42
static struct bootinfo *bi;
43
44
/*
45
* Load the information expected by an i386 kernel.
46
*
47
* - The 'boothowto' argument is constructed
48
* - The 'bootdev' argument is constructed
49
* - The 'bootinfo' struct is constructed, and copied into the kernel space.
50
* - The kernel environment is copied into kernel space.
51
* - Module metadata are formatted and placed in kernel space.
52
*/
53
int
54
bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t *modulep, vm_offset_t *kernendp)
55
{
56
struct preloaded_file *xp, *kfp;
57
struct i386_devdesc *rootdev;
58
struct file_metadata *md;
59
vm_offset_t addr;
60
vm_offset_t kernend;
61
vm_offset_t envp;
62
vm_offset_t size;
63
vm_offset_t ssym, esym;
64
char *rootdevname;
65
int bootdevnr, i, howto;
66
char *kernelname;
67
const char *kernelpath;
68
69
howto = bi_getboothowto(args);
70
71
/*
72
* Allow the environment variable 'rootdev' to override the supplied device
73
* This should perhaps go to MI code and/or have $rootdev tested/set by
74
* MI code before launching the kernel.
75
*/
76
rootdevname = getenv("rootdev");
77
i386_getdev((void **)(&rootdev), rootdevname, NULL);
78
if (rootdev == NULL) { /* bad $rootdev/$currdev */
79
printf("can't determine root device\n");
80
return(EINVAL);
81
}
82
83
/* Try reading the /etc/fstab file to select the root device */
84
getrootmount(devformat(&rootdev->dd));
85
86
/* Do legacy rootdev guessing */
87
88
/* XXX - use a default bootdev of 0. Is this ok??? */
89
bootdevnr = 0;
90
91
bi = calloc(sizeof(*bi), 1);
92
switch(rootdev->dd.d_dev->dv_type) {
93
case DEVT_CD:
94
case DEVT_DISK:
95
/* pass in the BIOS device number of the current disk */
96
bi->bi_bios_dev = bd_unit2bios(rootdev);
97
bootdevnr = bd_getdev(rootdev);
98
break;
99
100
case DEVT_NET:
101
case DEVT_ZFS:
102
break;
103
104
default:
105
printf("WARNING - don't know how to boot from device type %d\n",
106
rootdev->dd.d_dev->dv_type);
107
}
108
if (bootdevnr == -1) {
109
printf("root device %s invalid\n", devformat(&rootdev->dd));
110
return (EINVAL);
111
}
112
free(rootdev);
113
114
/* find the last module in the chain */
115
addr = 0;
116
for (xp = file_findfile(NULL, NULL); xp != NULL; xp = xp->f_next) {
117
if (addr < (xp->f_addr + xp->f_size))
118
addr = xp->f_addr + xp->f_size;
119
}
120
/* pad to a page boundary */
121
addr = md_align(addr);
122
123
addr = build_font_module(addr);
124
125
/* copy our environment */
126
envp = addr;
127
addr = md_copyenv(addr);
128
129
/* pad to a page boundary */
130
addr = md_align(addr);
131
132
kfp = file_findfile(NULL, md_kerntype);
133
if (kfp == NULL)
134
panic("can't find kernel file");
135
kernend = 0; /* fill it in later */
136
file_addmetadata(kfp, MODINFOMD_HOWTO, sizeof howto, &howto);
137
file_addmetadata(kfp, MODINFOMD_ENVP, sizeof envp, &envp);
138
file_addmetadata(kfp, MODINFOMD_KERNEND, sizeof kernend, &kernend);
139
bios_addsmapdata(kfp);
140
#ifdef LOADER_GELI_SUPPORT
141
geli_export_key_metadata(kfp);
142
#endif
143
bi_load_vbe_data(kfp);
144
145
/* Figure out the size and location of the metadata */
146
*modulep = addr;
147
size = md_copymodules(0, false);
148
kernend = md_align(addr + size);
149
*kernendp = kernend;
150
151
/* patch MODINFOMD_KERNEND */
152
md = file_findmetadata(kfp, MODINFOMD_KERNEND);
153
bcopy(&kernend, md->md_data, sizeof kernend);
154
155
/* copy module list and metadata */
156
(void)md_copymodules(addr, false);
157
158
ssym = esym = 0;
159
md = file_findmetadata(kfp, MODINFOMD_SSYM);
160
if (md != NULL)
161
ssym = *((vm_offset_t *)&(md->md_data));
162
md = file_findmetadata(kfp, MODINFOMD_ESYM);
163
if (md != NULL)
164
esym = *((vm_offset_t *)&(md->md_data));
165
if (ssym == 0 || esym == 0)
166
ssym = esym = 0; /* sanity */
167
168
/* legacy bootinfo structure */
169
kernelname = getenv("kernelname");
170
i386_getdev(NULL, kernelname, &kernelpath);
171
bi->bi_version = BOOTINFO_VERSION;
172
bi->bi_size = sizeof(*bi);
173
bi->bi_memsizes_valid = 1;
174
bi->bi_basemem = bios_basemem / 1024;
175
bi->bi_extmem = bios_extmem / 1024;
176
bi->bi_envp = envp;
177
bi->bi_modulep = *modulep;
178
bi->bi_kernend = kernend;
179
bi->bi_kernelname = VTOP(kernelpath);
180
bi->bi_symtab = ssym; /* XXX this is only the primary kernel symtab */
181
bi->bi_esymtab = esym;
182
183
/* legacy boot arguments */
184
*howtop = howto | RB_BOOTINFO;
185
*bootdevp = bootdevnr;
186
*bip = VTOP(bi);
187
188
return(0);
189
}
190
191