4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2017 Toomas Soome <tsoome@me.com>
32 #include <sys/types.h>
40 #include <sys/multiboot.h>
44 direct_or_multi_t bam_direct
= BAM_DIRECT_NOT_SET
;
45 hv_t bam_is_hv
= BAM_HV_UNKNOWN
;
46 findroot_t bam_is_findroot
= BAM_FINDROOT_PRESENT
;
49 get_boot_cap(const char *osroot
)
57 multiboot_header_t
*mbh
;
60 const char *fcn
= "get_boot_cap()";
63 * The install media can support both 64 and 32 bit boot
64 * by using boot archive as ramdisk image. However, to save
65 * the memory, the ramdisk may only have either 32 or 64
66 * bit kernel files. To avoid error message about missing unix,
67 * we should try both variants here and only complain if neither
68 * is found. Since the 64-bit systems are more common, we start
72 (void) snprintf(fname
, PATH_MAX
, "%s/%s", osroot
,
73 "platform/kernel/unix");
74 fd
= open(fname
, O_RDONLY
);
77 INJECT_ERROR1("GET_CAP_UNIX_OPEN", fd
= -1);
79 bam_error(_("failed to open file: %s: %s\n"), fname
,
85 * Verify that this is a sane unix at least 8192 bytes in length
87 if (fstat(fd
, &sb
) == -1 || sb
.st_size
< 8192) {
89 bam_error(_("invalid or corrupted binary: %s\n"), fname
);
96 image
= mmap(NULL
, 8192, PROT_READ
, MAP_SHARED
, fd
, 0);
98 INJECT_ERROR1("GET_CAP_MMAP", image
= MAP_FAILED
);
99 if (image
== MAP_FAILED
) {
100 bam_error(_("failed to mmap file: %s: %s\n"), fname
,
105 ident
= (uchar_t
*)image
;
106 if (ident
[EI_MAG0
] != ELFMAG0
|| ident
[EI_MAG1
] != ELFMAG1
||
107 ident
[EI_MAG2
] != ELFMAG2
|| ident
[EI_MAG3
] != ELFMAG3
) {
108 bam_error(_("%s is not an ELF file.\n"), fname
);
111 if (ident
[EI_CLASS
] != class) {
112 bam_error(_("%s is wrong ELF class 0x%x\n"), fname
,
118 * The GRUB multiboot header must be 32-bit aligned and completely
119 * contained in the 1st 8K of the file. If the unix binary has
120 * a multiboot header, then it is a 'dboot' kernel. Otherwise,
121 * this kernel must be booted via multiboot -- we call this a
122 * 'multiboot' kernel.
124 bam_direct
= BAM_DIRECT_MULTIBOOT
;
125 for (m
= 0; m
< 8192 - sizeof (multiboot_header_t
); m
+= 4) {
126 mbh
= (void *)(image
+ m
);
127 if (mbh
->magic
== MB_HEADER_MAGIC
) {
128 BAM_DPRINTF(("%s: is DBOOT unix\n", fcn
));
129 bam_direct
= BAM_DIRECT_DBOOT
;
133 (void) munmap(image
, 8192);
136 INJECT_ERROR1("GET_CAP_MULTIBOOT", bam_direct
= BAM_DIRECT_MULTIBOOT
);
137 if (bam_direct
== BAM_DIRECT_DBOOT
) {
138 if (bam_is_hv
== BAM_HV_PRESENT
) {
139 BAM_DPRINTF(("%s: is xVM system\n", fcn
));
141 BAM_DPRINTF(("%s: is *NOT* xVM system\n", fcn
));
144 BAM_DPRINTF(("%s: is MULTIBOOT unix\n", fcn
));
147 BAM_DPRINTF(("%s: returning SUCCESS\n", fcn
));
148 return (BAM_SUCCESS
);