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 2016 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
)
56 multiboot_header_t
*mbh
;
59 const char *fcn
= "get_boot_cap()";
62 /* there is no non dboot sparc new-boot */
63 bam_direct
= BAM_DIRECT_DBOOT
;
64 BAM_DPRINTF(("%s: is sparc - always DBOOT\n", fcn
));
68 (void) snprintf(fname
, PATH_MAX
, "%s/%s", osroot
,
69 "platform/i86pc/kernel/unix");
70 fd
= open(fname
, O_RDONLY
);
72 INJECT_ERROR1("GET_CAP_UNIX_OPEN", fd
= -1);
74 bam_error(_("failed to open file: %s: %s\n"), fname
,
80 * Verify that this is a sane unix at least 8192 bytes in length
82 if (fstat(fd
, &sb
) == -1 || sb
.st_size
< 8192) {
84 bam_error(_("invalid or corrupted binary: %s\n"), fname
);
91 image
= mmap(NULL
, 8192, PROT_READ
, MAP_SHARED
, fd
, 0);
93 INJECT_ERROR1("GET_CAP_MMAP", image
= MAP_FAILED
);
94 if (image
== MAP_FAILED
) {
95 bam_error(_("failed to mmap file: %s: %s\n"), fname
,
100 ident
= (uchar_t
*)image
;
101 if (ident
[EI_MAG0
] != ELFMAG0
|| ident
[EI_MAG1
] != ELFMAG1
||
102 ident
[EI_MAG2
] != ELFMAG2
|| ident
[EI_MAG3
] != ELFMAG3
) {
103 bam_error(_("%s is not an ELF file.\n"), fname
);
106 if (ident
[EI_CLASS
] != ELFCLASS32
) {
107 bam_error(_("%s is wrong ELF class 0x%x\n"), fname
,
113 * The GRUB multiboot header must be 32-bit aligned and completely
114 * contained in the 1st 8K of the file. If the unix binary has
115 * a multiboot header, then it is a 'dboot' kernel. Otherwise,
116 * this kernel must be booted via multiboot -- we call this a
117 * 'multiboot' kernel.
119 bam_direct
= BAM_DIRECT_MULTIBOOT
;
120 for (m
= 0; m
< 8192 - sizeof (multiboot_header_t
); m
+= 4) {
121 mbh
= (void *)(image
+ m
);
122 if (mbh
->magic
== MB_HEADER_MAGIC
) {
123 BAM_DPRINTF(("%s: is DBOOT unix\n", fcn
));
124 bam_direct
= BAM_DIRECT_DBOOT
;
128 (void) munmap(image
, 8192);
131 INJECT_ERROR1("GET_CAP_MULTIBOOT", bam_direct
= BAM_DIRECT_MULTIBOOT
);
132 if (bam_direct
== BAM_DIRECT_DBOOT
) {
133 if (bam_is_hv
== BAM_HV_PRESENT
) {
134 BAM_DPRINTF(("%s: is xVM system\n", fcn
));
136 BAM_DPRINTF(("%s: is *NOT* xVM system\n", fcn
));
139 BAM_DPRINTF(("%s: is MULTIBOOT unix\n", fcn
));
142 BAM_DPRINTF(("%s: returning SUCCESS\n", fcn
));
143 return (BAM_SUCCESS
);