Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
9259 libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
loader: pxe receive cleanup
9475 libefi: Do not return only if ReceiveFilter
installboot: should support efi system partition
8931 boot1.efi: scan all display modes rather than
loader: spinconsole updates
loader: gfx experiment to try GOP Blt() function.
sha1 build test
loader: add sha1 hash calculation
common/sha1: update for loader build
loader: biosdisk rework
uts: 32-bit kernel FB needs mapping in low memory
uts: add diag-device
uts: boot console mirror with diag-device
uts: enable very early console on ttya
kmdb: add diag-device as input/output device
uts: test VGA memory exclusion from mapping
uts: clear boot mapping and protect boot pages test
uts: add dboot map debug printf
uts: need to release FB pages in release_bootstrap()
uts: add screenmap ioctl
uts: update sys/queue.h
loader: add illumos uts/common to include path
loader: tem/gfx font cleanup
loader: vbe checks
uts: gfx_private set KD_TEXT when KD_RESETTEXT is
uts: gfx 8-bit update
loader: gfx 8-bit fix
loader: always set media size from partition.
uts: MB2 support for 32-bit kernel
loader: x86 should have tem 80x25
uts: x86 should have tem 80x25
uts: font update
loader: font update
uts: tem attributes
loader: tem.c comment added
uts: use font module
loader: add font module
loader: build rules for new font setup
uts: gfx_private update for new font structure
uts: early boot update for new font structure
uts: font update
uts: font build rules update for new fonts
uts: tem update to new font structure
loader: module.c needs to include tem_impl.h
uts: gfx_private 8x16 font rework
uts: make font_lookup public
loader: font rework
uts: font rework
libefi: efi_alloc_and_read should check for PMBR
uts: tem utf-8 support
loader: implement tem utf-8 support
loader: tem should be able to display UTF-8
7784 uts: console input should support utf-8
7796 uts: ldterm default to utf-8
uts: do not reset serial console
uts: set up colors even if tem is not console
uts: add type for early boot properties
uts: gfx_private experiment with drm and vga
uts: gfx_private should use setmode drm callback.
uts: identify FB types and set up gfx_private based
loader: replace gop and vesa with framebuffer
uts: boot needs simple tem to support mdb
uts: boot_keyboard should emit esc sequences for
uts: gfx_private FB showuld be written by line
kmdb: set terminal window size
uts: gfx_private needs to keep track of early boot FB
pnglite: move pnglite to usr/src/common
loader: gfx_fb
ficl-sys: add gfx primitives
loader: add illumos.png logo
ficl: add fb-putimage
loader: add png support
loader: add alpha blending for gfx_fb
loader: use term-drawrect for menu frame
ficl: add simple gfx words
uts: provide fb_info via fbgattr dev_specific array.
uts: gfx_private add alpha blending
uts: update sys/ascii.h
uts: tem OSC support (incomplete)
uts: implement env module support and use data from
uts: tem get colors from early boot data
loader: use crc32 from libstand (libz)
loader: optimize for size
loader: pass tem info to the environment
loader: import tem for loader console
loader: UEFI loader needs to set ISADIR based on
loader: need UEFI32 support
8918 loader.efi: add vesa edid support
uts: tem_safe_pix_clear_prom_output() should only
uts: tem_safe_pix_clear_entire_screen() should use
uts: tem_safe_check_first_time() should query cursor
uts: tem implement cls callback & visual_io v4
uts: gfx_vgatext use block cursor for vgatext
uts: gfx_private implement cls callback & visual_io
uts: gfx_private bitmap framebuffer implementation
uts: early start frame buffer console support
uts: font functions should check the input char
uts: font rendering should support 16/24/32bit depths
uts: use smallest font as fallback default.
uts: update terminal dimensions based on selected
7834 uts: vgatext should use gfx_private
uts: add spacing property to 8859-1.bdf
terminfo: add underline for sun-color
terminfo: sun-color has 16 colors
uts: add font load callback type
loader: do not repeat int13 calls with error 0x20 and
8905 loader: add skein/edonr support
8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c
+++ new/usr/src/boot/sys/boot/i386/gptzfsboot/zfsboot.c
1 1 /*-
2 2 * Copyright (c) 1998 Robert Nordier
3 3 * All rights reserved.
4 4 *
5 5 * Redistribution and use in source and binary forms are freely
6 6 * permitted provided that the above copyright notice and this
7 7 * paragraph and the following disclaimer are duplicated in all
8 8 * such forms.
9 9 *
10 10 * This software is provided "AS IS" and without any express or
11 11 * implied warranties, including, without limitation, the implied
12 12 * warranties of merchantability and fitness for a particular
13 13 * purpose.
14 14 */
15 15
|
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
16 16 #include <sys/cdefs.h>
17 17 #include <stand.h>
18 18
19 19 #include <sys/param.h>
20 20 #include <sys/errno.h>
21 21 #include <sys/diskmbr.h>
22 22 #include <sys/vtoc.h>
23 23 #include <sys/disk.h>
24 24 #include <sys/reboot.h>
25 25 #include <sys/queue.h>
26 -#include <multiboot.h>
26 +#include <sys/multiboot.h>
27 27
28 28 #include <machine/bootinfo.h>
29 29 #include <machine/elf.h>
30 30 #include <machine/pc/bios.h>
31 31
32 32 #include <stdarg.h>
33 33 #include <stddef.h>
34 34
35 35 #include <a.out.h>
36 36 #include "bootstrap.h"
37 37 #include "libi386.h"
38 38 #include <btxv86.h>
39 39
40 40 #include "lib.h"
41 41 #include "rbx.h"
42 42 #include "cons.h"
43 43 #include "bootargs.h"
44 44 #include "disk.h"
45 45 #include "part.h"
46 46 #include "paths.h"
47 47
48 48 #include "libzfs.h"
49 49
50 50 #define ARGS 0x900
51 51 #define NOPT 14
52 52 #define NDEV 3
53 53
54 54 #define BIOS_NUMDRIVES 0x475
55 55 #define DRV_HARD 0x80
56 56 #define DRV_MASK 0x7f
57 57
58 58 #define TYPE_AD 0
59 59 #define TYPE_DA 1
60 60 #define TYPE_MAXHARD TYPE_DA
61 61 #define TYPE_FD 2
62 62
63 63 extern uint32_t _end;
64 64
65 65 /*
66 66 * Fake multiboot header to provide versioning and to pass
67 67 * partition start LBA. Partition is either GPT partition or
68 68 * VTOC slice.
69 69 */
70 70 extern const struct multiboot_header mb_header;
71 71 extern uint64_t start_sector;
72 72
73 73 static const char optstr[NOPT] = "DhaCcdgmnpqrsv"; /* Also 'P', 'S' */
74 74 static const unsigned char flags[NOPT] = {
75 75 RBX_DUAL,
76 76 RBX_SERIAL,
77 77 RBX_ASKNAME,
78 78 RBX_CDROM,
79 79 RBX_CONFIG,
80 80 RBX_KDB,
81 81 RBX_GDB,
82 82 RBX_MUTE,
83 83 RBX_NOINTR,
84 84 RBX_PAUSE,
85 85 RBX_QUIET,
86 86 RBX_DFLTROOT,
87 87 RBX_SINGLE,
88 88 RBX_VERBOSE
89 89 };
90 90 uint32_t opts;
91 91
92 92 static const unsigned char dev_maj[NDEV] = {30, 4, 2};
93 93
94 94 static struct i386_devdesc *bdev;
95 95 static char cmd[512];
96 96 static char cmddup[512];
97 97 static char kname[1024];
98 98 static int comspeed = SIOSPD;
99 99 static struct bootinfo bootinfo;
100 100 static uint32_t bootdev;
101 101 static struct zfs_boot_args zfsargs;
102 102
103 103 extern vm_offset_t high_heap_base;
104 104 extern uint32_t bios_basemem, bios_extmem, high_heap_size;
105 105
106 106 static char *heap_top;
107 107 static char *heap_bottom;
108 108
109 109 static void i386_zfs_probe(void);
110 110 void exit(int);
111 111 static void load(void);
112 112 static int parse_cmd(void);
113 113
114 114 struct arch_switch archsw; /* MI/MD interface boundary */
115 115 static char boot_devname[2 * ZFS_MAXNAMELEN + 8]; /* disk or pool:dataset */
116 116
117 117 struct devsw *devsw[] = {
118 118 &biosdisk,
119 119 &zfs_dev,
120 120 NULL
121 121 };
122 122
123 123 struct fs_ops *file_system[] = {
124 124 &zfs_fsops,
125 125 &ufs_fsops,
126 126 &dosfs_fsops,
127 127 NULL
128 128 };
129 129
130 130 int
131 131 main(void)
132 132 {
133 133 int auto_boot, i, fd;
134 134 struct disk_devdesc devdesc;
135 135
136 136 bios_getmem();
137 137
138 138 if (high_heap_size > 0) {
139 139 heap_top = PTOV(high_heap_base + high_heap_size);
140 140 heap_bottom = PTOV(high_heap_base);
141 141 } else {
142 142 heap_bottom = (char *)
143 143 (roundup2(__base + (int32_t)&_end, 0x10000) - __base);
144 144 heap_top = (char *) PTOV(bios_basemem);
145 145 }
146 146 setheap(heap_bottom, heap_top);
147 147
148 148 /*
149 149 * Initialise the block cache. Set the upper limit.
150 150 */
151 151 bcache_init(32768, 512);
152 152
153 153 archsw.arch_autoload = NULL;
154 154 archsw.arch_getdev = i386_getdev;
155 155 archsw.arch_copyin = NULL;
156 156 archsw.arch_copyout = NULL;
157 157 archsw.arch_readin = NULL;
158 158 archsw.arch_isainb = NULL;
159 159 archsw.arch_isaoutb = NULL;
160 160 archsw.arch_zfs_probe = i386_zfs_probe;
161 161
162 162 bootinfo.bi_version = BOOTINFO_VERSION;
163 163 bootinfo.bi_size = sizeof(bootinfo);
164 164 bootinfo.bi_basemem = bios_basemem / 1024;
165 165 bootinfo.bi_extmem = bios_extmem / 1024;
166 166 bootinfo.bi_memsizes_valid++;
167 167 bootinfo.bi_bios_dev = *(uint8_t *)PTOV(ARGS);
168 168
169 169 /* Set up fall back device name. */
170 170 snprintf(boot_devname, sizeof (boot_devname), "disk%d:",
171 171 bd_bios2unit(bootinfo.bi_bios_dev));
172 172
173 173 for (i = 0; devsw[i] != NULL; i++)
174 174 if (devsw[i]->dv_init != NULL)
175 175 (devsw[i]->dv_init)();
176 176
177 177 disk_parsedev(&devdesc, boot_devname+4, NULL);
178 178
179 179 bootdev = MAKEBOOTDEV(dev_maj[devdesc.d_type], devdesc.d_slice + 1,
180 180 devdesc.d_unit, devdesc.d_partition >= 0? devdesc.d_partition:0xff);
181 181
182 182 /*
183 183 * zfs_fmtdev() can be called only after dv_init
184 184 */
185 185 if (bdev != NULL && bdev->d_type == DEVT_ZFS) {
186 186 /* set up proper device name string for ZFS */
187 187 strncpy(boot_devname, zfs_fmtdev(bdev), sizeof (boot_devname));
188 188 }
|
↓ open down ↓ |
152 lines elided |
↑ open up ↑ |
189 189
190 190 /* now make sure we have bdev on all cases */
191 191 if (bdev != NULL)
192 192 free(bdev);
193 193 i386_getdev((void **)&bdev, boot_devname, NULL);
194 194
195 195 env_setenv("currdev", EV_VOLATILE, boot_devname, i386_setcurrdev,
196 196 env_nounset);
197 197
198 198 /* Process configuration file */
199 - setenv("LINES", "24", 1);
199 + setenv("screen-#rows", "24", 1);
200 200 auto_boot = 1;
201 201
202 202 fd = open(PATH_CONFIG, O_RDONLY);
203 203 if (fd == -1)
204 204 fd = open(PATH_DOTCONFIG, O_RDONLY);
205 205
206 206 if (fd != -1) {
207 207 read(fd, cmd, sizeof(cmd));
208 208 close(fd);
209 209 }
210 210
211 211 if (*cmd) {
212 212 /*
213 213 * Note that parse_cmd() is destructive to cmd[] and we also want
214 214 * to honor RBX_QUIET option that could be present in cmd[].
215 215 */
216 216 memcpy(cmddup, cmd, sizeof(cmd));
217 217 if (parse_cmd())
218 218 auto_boot = 0;
219 219 if (!OPT_CHECK(RBX_QUIET))
220 220 printf("%s: %s\n", PATH_CONFIG, cmddup);
221 221 /* Do not process this command twice */
222 222 *cmd = 0;
223 223 }
224 224
225 225 /*
226 226 * Try to exec stage 3 boot loader. If interrupted by a keypress,
227 227 * or in case of failure, switch off auto boot.
228 228 */
229 229
230 230 if (auto_boot && !*kname) {
231 231 memcpy(kname, PATH_LOADER_ZFS, sizeof(PATH_LOADER_ZFS));
232 232 if (!keyhit(3)) {
233 233 load();
234 234 auto_boot = 0;
235 235 }
236 236 }
237 237
238 238 /* Present the user with the boot2 prompt. */
239 239
240 240 for (;;) {
241 241 if (!auto_boot || !OPT_CHECK(RBX_QUIET)) {
242 242 printf("\nillumos/x86 boot\n");
243 243 printf("Default: %s%s\nboot: ", boot_devname, kname);
244 244 }
245 245 if (ioctrl & IO_SERIAL)
246 246 sio_flush();
247 247 if (!auto_boot || keyhit(5))
248 248 getstr(cmd, sizeof(cmd));
249 249 else if (!auto_boot || !OPT_CHECK(RBX_QUIET))
250 250 putchar('\n');
251 251 auto_boot = 0;
252 252 if (parse_cmd())
253 253 putchar('\a');
254 254 else
255 255 load();
256 256 }
257 257 }
258 258
259 259 /* XXX - Needed for btxld to link the boot2 binary; do not remove. */
260 260 void
261 261 exit(int x)
262 262 {
263 263 }
264 264
265 265 static void
266 266 load(void)
267 267 {
268 268 union {
269 269 struct exec ex;
270 270 Elf32_Ehdr eh;
271 271 } hdr;
272 272 static Elf32_Phdr ep[2];
273 273 static Elf32_Shdr es[2];
274 274 caddr_t p;
275 275 uint32_t addr, x;
276 276 int fd, fmt, i, j;
277 277
278 278 if ((fd = open(kname, O_RDONLY)) == -1) {
279 279 printf("\nCan't find %s\n", kname);
280 280 return;
281 281 }
282 282 if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
283 283 close(fd);
284 284 return;
285 285 }
286 286 if (N_GETMAGIC(hdr.ex) == ZMAGIC)
287 287 fmt = 0;
288 288 else if (IS_ELF(hdr.eh))
289 289 fmt = 1;
290 290 else {
291 291 printf("Invalid %s\n", "format");
292 292 close(fd);
293 293 return;
294 294 }
295 295 if (fmt == 0) {
296 296 addr = hdr.ex.a_entry & 0xffffff;
297 297 p = PTOV(addr);
298 298 lseek(fd, PAGE_SIZE, SEEK_SET);
299 299 if (read(fd, p, hdr.ex.a_text) != hdr.ex.a_text) {
300 300 close(fd);
301 301 return;
302 302 }
303 303 p += roundup2(hdr.ex.a_text, PAGE_SIZE);
304 304 if (read(fd, p, hdr.ex.a_data) != hdr.ex.a_data) {
305 305 close(fd);
306 306 return;
307 307 }
308 308 p += hdr.ex.a_data + roundup2(hdr.ex.a_bss, PAGE_SIZE);
309 309 bootinfo.bi_symtab = VTOP(p);
310 310 memcpy(p, &hdr.ex.a_syms, sizeof(hdr.ex.a_syms));
311 311 p += sizeof(hdr.ex.a_syms);
312 312 if (hdr.ex.a_syms) {
313 313 if (read(fd, p, hdr.ex.a_syms) != hdr.ex.a_syms) {
314 314 close(fd);
315 315 return;
316 316 }
317 317 p += hdr.ex.a_syms;
318 318 if (read(fd, p, sizeof(int)) != sizeof(int)) {
319 319 close(fd);
320 320 return;
321 321 }
322 322 x = *(uint32_t *)p;
323 323 p += sizeof(int);
324 324 x -= sizeof(int);
325 325 if (read(fd, p, x) != x) {
326 326 close(fd);
327 327 return;
328 328 }
329 329 p += x;
330 330 }
331 331 } else {
332 332 lseek(fd, hdr.eh.e_phoff, SEEK_SET);
333 333 for (j = i = 0; i < hdr.eh.e_phnum && j < 2; i++) {
334 334 if (read(fd, ep + j, sizeof(ep[0])) != sizeof(ep[0])) {
335 335 close(fd);
336 336 return;
337 337 }
338 338 if (ep[j].p_type == PT_LOAD)
339 339 j++;
340 340 }
341 341 for (i = 0; i < 2; i++) {
342 342 p = PTOV(ep[i].p_paddr & 0xffffff);
343 343 lseek(fd, ep[i].p_offset, SEEK_SET);
344 344 if (read(fd, p, ep[i].p_filesz) != ep[i].p_filesz) {
345 345 close(fd);
346 346 return;
347 347 }
348 348 }
349 349 p += roundup2(ep[1].p_memsz, PAGE_SIZE);
350 350 bootinfo.bi_symtab = VTOP(p);
351 351 if (hdr.eh.e_shnum == hdr.eh.e_shstrndx + 3) {
352 352 lseek(fd, hdr.eh.e_shoff + sizeof(es[0]) * (hdr.eh.e_shstrndx + 1),
353 353 SEEK_SET);
354 354 if (read(fd, &es, sizeof(es)) != sizeof(es)) {
355 355 close(fd);
356 356 return;
357 357 }
358 358 for (i = 0; i < 2; i++) {
359 359 memcpy(p, &es[i].sh_size, sizeof(es[i].sh_size));
360 360 p += sizeof(es[i].sh_size);
361 361 lseek(fd, es[i].sh_offset, SEEK_SET);
362 362 if (read(fd, p, es[i].sh_size) != es[i].sh_size) {
363 363 close(fd);
364 364 return;
365 365 }
366 366 p += es[i].sh_size;
367 367 }
368 368 }
369 369 addr = hdr.eh.e_entry & 0xffffff;
370 370 }
371 371 close(fd);
372 372
373 373 bootinfo.bi_esymtab = VTOP(p);
374 374 bootinfo.bi_kernelname = VTOP(kname);
375 375
376 376 if (bdev->d_type == DEVT_ZFS) {
377 377 zfsargs.size = sizeof(zfsargs);
378 378 zfsargs.pool = bdev->d_kind.zfs.pool_guid;
379 379 zfsargs.root = bdev->d_kind.zfs.root_guid;
380 380 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
381 381 bootdev,
382 382 KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG,
383 383 (uint32_t) bdev->d_kind.zfs.pool_guid,
384 384 (uint32_t) (bdev->d_kind.zfs.pool_guid >> 32),
385 385 VTOP(&bootinfo),
386 386 zfsargs);
387 387 } else
388 388 __exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
389 389 bootdev, 0, 0, 0, VTOP(&bootinfo));
390 390 }
391 391
392 392 static int
393 393 mount_root(char *arg)
394 394 {
395 395 char *root;
396 396 struct i386_devdesc *ddesc;
397 397 uint8_t part;
398 398
399 399 root = malloc(strlen(arg) + 2);
400 400 if (root == NULL)
401 401 return (1);
402 402 sprintf(root, "%s:", arg);
403 403 if (i386_getdev((void **)&ddesc, root, NULL)) {
404 404 free(root);
405 405 return (1);
406 406 }
407 407
408 408 /* we should have new device descriptor, free old and replace it. */
409 409 if (bdev != NULL)
410 410 free(bdev);
411 411 bdev = ddesc;
412 412 if (bdev->d_type == DEVT_DISK) {
413 413 if (bdev->d_kind.biosdisk.partition == -1)
414 414 part = 0xff;
415 415 else
416 416 part = bdev->d_kind.biosdisk.partition;
417 417 bootdev = MAKEBOOTDEV(dev_maj[bdev->d_type],
418 418 bdev->d_kind.biosdisk.slice + 1,
419 419 bdev->d_unit, part);
420 420 bootinfo.bi_bios_dev = bd_unit2bios(bdev->d_unit);
421 421 }
422 422 setenv("currdev", root, 1);
423 423 free(root);
424 424 return (0);
425 425 }
426 426
427 427 static void
428 428 fs_list(char *arg)
429 429 {
430 430 int fd;
431 431 struct dirent *d;
432 432 char line[80];
433 433
434 434 fd = open(arg, O_RDONLY);
435 435 if (fd < 0)
436 436 return;
437 437 pager_open();
438 438 while ((d = readdirfd(fd)) != NULL) {
439 439 sprintf(line, "%s\n", d->d_name);
440 440 if (pager_output(line))
441 441 break;
442 442 }
443 443 pager_close();
444 444 close(fd);
445 445 }
446 446
447 447 static int
448 448 parse_cmd(void)
449 449 {
450 450 char *arg = cmd;
451 451 char *ep, *p, *q;
452 452 const char *cp;
453 453 char line[80];
454 454 int c, i, j;
455 455
456 456 while ((c = *arg++)) {
457 457 if (c == ' ' || c == '\t' || c == '\n')
458 458 continue;
459 459 for (p = arg; *p && *p != '\n' && *p != ' ' && *p != '\t'; p++);
460 460 ep = p;
461 461 if (*p)
462 462 *p++ = 0;
463 463 if (c == '-') {
464 464 while ((c = *arg++)) {
465 465 if (c == 'P') {
466 466 if (*(uint8_t *)PTOV(0x496) & 0x10) {
467 467 cp = "yes";
468 468 } else {
469 469 opts |= OPT_SET(RBX_DUAL) | OPT_SET(RBX_SERIAL);
470 470 cp = "no";
471 471 }
472 472 printf("Keyboard: %s\n", cp);
473 473 continue;
474 474 } else if (c == 'S') {
475 475 j = 0;
476 476 while ((unsigned int)(i = *arg++ - '0') <= 9)
477 477 j = j * 10 + i;
478 478 if (j > 0 && i == -'0') {
479 479 comspeed = j;
480 480 break;
481 481 }
482 482 /* Fall through to error below ('S' not in optstr[]). */
483 483 }
484 484 for (i = 0; c != optstr[i]; i++)
485 485 if (i == NOPT - 1)
486 486 return -1;
487 487 opts ^= OPT_SET(flags[i]);
488 488 }
489 489 ioctrl = OPT_CHECK(RBX_DUAL) ? (IO_SERIAL|IO_KEYBOARD) :
490 490 OPT_CHECK(RBX_SERIAL) ? IO_SERIAL : IO_KEYBOARD;
491 491 if (ioctrl & IO_SERIAL) {
492 492 if (sio_init(115200 / comspeed) != 0)
493 493 ioctrl &= ~IO_SERIAL;
494 494 }
495 495 } if (c == '?') {
496 496 printf("\n");
497 497 fs_list(arg);
498 498 zfs_list(arg);
499 499 return -1;
500 500 } else {
501 501 arg--;
502 502
503 503 /*
504 504 * Report pool status if the comment is 'status'. Lets
505 505 * hope no-one wants to load /status as a kernel.
506 506 */
507 507 if (!strcmp(arg, "status")) {
508 508 pager_open();
509 509 for (i = 0; devsw[i] != NULL; i++) {
510 510 if (devsw[i]->dv_print != NULL) {
511 511 if (devsw[i]->dv_print(1))
512 512 break;
513 513 } else {
514 514 sprintf(line, "%s: (unknown)\n", devsw[i]->dv_name);
515 515 if (pager_output(line))
516 516 break;
517 517 }
518 518 }
519 519 pager_close();
520 520 return -1;
521 521 }
522 522
523 523 /*
524 524 * If there is a colon, switch pools.
525 525 */
526 526 if (strncmp(arg, "zfs:", 4) == 0)
527 527 q = strchr(arg + 4, ':');
528 528 else
529 529 q = strchr(arg, ':');
530 530 if (q) {
531 531 *q++ = '\0';
532 532 if (mount_root(arg) != 0)
533 533 return -1;
534 534 arg = q;
535 535 }
536 536 if ((i = ep - arg)) {
537 537 if ((size_t)i >= sizeof(kname))
538 538 return -1;
539 539 memcpy(kname, arg, i + 1);
540 540 }
541 541 }
542 542 arg = p;
543 543 }
544 544 return 0;
545 545 }
546 546
547 547 /*
548 548 * probe arguments for partition iterator (see below)
549 549 */
550 550 struct probe_args {
551 551 int fd;
552 552 char *devname;
553 553 u_int secsz;
554 554 uint64_t offset;
555 555 };
556 556
557 557 /*
558 558 * simple wrapper around read() to avoid using device specific
559 559 * strategy() directly.
560 560 */
561 561 static int
562 562 parttblread(void *arg, void *buf, size_t blocks, uint64_t offset)
563 563 {
564 564 struct probe_args *ppa = arg;
565 565 size_t size = ppa->secsz * blocks;
566 566
567 567 lseek(ppa->fd, offset * ppa->secsz, SEEK_SET);
568 568 if (read(ppa->fd, buf, size) == size)
569 569 return (0);
570 570 return (EIO);
571 571 }
572 572
573 573 /*
574 574 * scan partition entries to find boot partition starting at start_sector.
575 575 * in case of MBR partition type PART_SOLARIS2, read VTOC and recurse.
576 576 */
577 577 static int
578 578 probe_partition(void *arg, const char *partname,
579 579 const struct ptable_entry *part)
580 580 {
581 581 struct probe_args pa, *ppa = arg;
582 582 struct ptable *table;
583 583 uint64_t *pool_guid_ptr = NULL;
584 584 uint64_t pool_guid = 0;
585 585 char devname[32];
586 586 int len, ret = 0;
587 587
588 588 len = strlen(ppa->devname);
589 589 if (len > sizeof (devname))
590 590 len = sizeof (devname);
591 591
592 592 strncpy(devname, ppa->devname, len - 1);
593 593 devname[len - 1] = '\0';
594 594 snprintf(devname, sizeof (devname), "%s%s:", devname, partname);
595 595
596 596 /* filter out partitions *not* used by zfs */
597 597 switch (part->type) {
598 598 case PART_RESERVED: /* efi reserverd */
599 599 case PART_VTOC_BOOT: /* vtoc boot area */
600 600 case PART_VTOC_SWAP:
601 601 return (ret);
602 602 default:
603 603 break;
604 604 }
605 605
|
↓ open down ↓ |
396 lines elided |
↑ open up ↑ |
606 606 if (part->type == PART_SOLARIS2) {
607 607 pa.offset = part->start;
608 608 pa.fd = open(devname, O_RDONLY);
609 609 if (pa.fd == -1)
610 610 return (ret);
611 611 pa.devname = devname;
612 612 pa.secsz = ppa->secsz;
613 613 table = ptable_open(&pa, part->end - part->start + 1,
614 614 ppa->secsz, parttblread);
615 615 if (table != NULL) {
616 - if (ptable_gettype(table) == PTABLE_VTOC8) {
616 + enum ptable_type pt = ptable_gettype(table);
617 +
618 + if (pt == PTABLE_VTOC8 || pt == PTABLE_VTOC) {
617 619 ret = ptable_iterate(table, &pa,
618 620 probe_partition);
619 621 ptable_close(table);
620 622 close(pa.fd);
621 623 return (ret);
622 624 }
623 625 ptable_close(table);
624 626 }
625 627 close(pa.fd);
626 628 }
627 629
628 630 if (ppa->offset + part->start == start_sector) {
629 631 /* Ask zfs_probe_dev to provide guid. */
630 632 pool_guid_ptr = &pool_guid;
631 633 /* Set up boot device name for non-zfs case. */
632 634 strncpy(boot_devname, devname, sizeof (boot_devname));
633 635 }
634 636
635 637 ret = zfs_probe_dev(devname, pool_guid_ptr);
636 638 if (pool_guid != 0 && bdev == NULL) {
637 639 bdev = malloc(sizeof (struct i386_devdesc));
638 640 bzero(bdev, sizeof (struct i386_devdesc));
639 641 bdev->d_type = DEVT_ZFS;
640 642 bdev->d_dev = &zfs_dev;
641 643 bdev->d_kind.zfs.pool_guid = pool_guid;
642 644
643 645 /*
644 646 * We can not set up zfs boot device name yet, as the
645 647 * zfs dv_init() is not completed. We will set boot_devname
646 648 * in main, after devsw setup.
647 649 */
648 650 }
649 651
650 652 return (0);
651 653 }
652 654
653 655 /*
654 656 * open partition table on disk and scan partition entries to find
655 657 * boot partition starting at start_sector (recorded by installboot).
656 658 */
657 659 static int
658 660 probe_disk(char *devname)
659 661 {
660 662 struct ptable *table;
661 663 struct probe_args pa;
662 664 uint64_t mediasz;
663 665 int ret;
664 666
665 667 pa.offset = 0;
666 668 pa.devname = devname;
667 669 pa.fd = open(devname, O_RDONLY);
668 670 if (pa.fd == -1) {
669 671 return (ENXIO);
670 672 }
671 673
672 674 ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz);
673 675 if (ret == 0)
674 676 ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz);
675 677 if (ret == 0) {
676 678 table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz,
677 679 parttblread);
678 680 if (table != NULL) {
679 681 ret = ptable_iterate(table, &pa, probe_partition);
680 682 ptable_close(table);
681 683 }
682 684 }
683 685 close(pa.fd);
684 686 return (ret);
685 687 }
686 688
687 689 /*
688 690 * Probe all disks to discover ZFS pools. The idea is to walk all possible
689 691 * disk devices, however, we also need to identify possible boot pool.
690 692 * For boot pool detection we have boot disk passed us from BIOS, recorded
691 693 * in bootinfo.bi_bios_dev, and start_sector LBA recorded by installboot.
692 694 *
693 695 * To detect boot pool, we can not use generic zfs_probe_dev() on boot disk,
694 696 * but we need to walk partitions, as we have no way to pass start_sector
695 697 * to zfs_probe_dev(). Note we do need to detect the partition correcponding
696 698 * to non-zfs case, so here we can set boot_devname for both cases.
697 699 */
698 700 static void
699 701 i386_zfs_probe(void)
700 702 {
701 703 char devname[32];
702 704 int boot_unit, unit;
703 705
|
↓ open down ↓ |
77 lines elided |
↑ open up ↑ |
704 706 /* Translate bios dev to our unit number. */
705 707 boot_unit = bd_bios2unit(bootinfo.bi_bios_dev);
706 708
707 709 /*
708 710 * Open all the disks we can find and see if we can reconstruct
709 711 * ZFS pools from them.
710 712 */
711 713 for (unit = 0; unit < MAXBDDEV; unit++) {
712 714 if (bd_unit2bios(unit) == -1)
713 715 break;
716 + if (bd_unit2bios(unit) < 0x80)
717 + continue;
714 718
715 719 sprintf(devname, "disk%d:", unit);
716 720 /* If this is not boot disk, use generic probe. */
717 721 if (unit != boot_unit)
718 722 zfs_probe_dev(devname, NULL);
719 723 else
720 724 probe_disk(devname);
721 725 }
722 726 }
723 727
724 728 uint64_t
725 729 ldi_get_size(void *priv)
726 730 {
727 731 int fd = (uintptr_t) priv;
728 732 uint64_t size;
729 733
730 734 ioctl(fd, DIOCGMEDIASIZE, &size);
731 735 return (size);
732 736 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX