1 /* ----------------------------------------------------------------------- *
3 * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
4 * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
5 * Copyright 2010 Shao Miller
6 * Copyright 2010-2012 Michal Soltys
8 * Permission is hereby granted, free of charge, to any person
9 * obtaining a copy of this software and associated documentation
10 * files (the "Software"), to deal in the Software without
11 * restriction, including without limitation the rights to use,
12 * copy, modify, merge, publish, distribute, sublicense, and/or
13 * sell copies of the Software, and to permit persons to whom
14 * the Software is furnished to do so, subject to the following
17 * The above copyright notice and this permission notice shall
18 * be included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
22 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
25 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27 * OTHER DEALINGS IN THE SOFTWARE.
29 * ----------------------------------------------------------------------- */
39 #include <syslinux/disk.h>
40 #include <syslinux/pmapi.h>
43 static const char *bpbtypes
[] = {
63 cnt
= read(0, &junk
, 1);
64 } while (cnt
> 0 || (cnt
< 0 && errno
== EAGAIN
));
69 cnt
= read(0, &junk
, 1);
70 } while (!cnt
|| (cnt
< 0 && errno
== EAGAIN
));
73 int guid_is0(const struct guid
*guid
)
85 * cnul - "strict" mode, never returning higher value than obtained from cbios
86 * cadd - if the disk is larger than reported geometry /and/ if the geometry has
87 * less cylinders than 1024 - it means that the total size is somewhere
88 * between cs and cs+1; in this particular case, we bump the cs to be able
89 * to return matching chs triplet
90 * cmax - assume we can use any cylinder value
92 * by default cadd seems most reasonable, giving consistent results with e.g.
95 void lba2chs(disk_chs
*dst
, const struct disk_info
*di
, uint64_t lba
, int mode
)
101 * Not much reason here, but if we have no valid CHS geometry, we assume
102 * "typical" ones to have something to return.
108 if (mode
== L2C_CADD
) {
109 if (cs
< 1024 && di
->lbacnt
> cs
*hs
*ss
)
111 } else if (mode
== L2C_CMAX
)
114 if (di
->disk
& 0x80) {
125 if (lba
>= cs
*hs
*ss
) {
137 (*dst
)[1] = s
| ((c
& 0x300) >> 2);
141 uint32_t get_file_lba(const char *filename
)
143 struct com32_filedata fd
;
152 /* Put the filename in the bounce buffer */
153 strlcpy(buf
, filename
, size
);
155 if (open_file(buf
, O_RDONLY
, &fd
) <= 0) {
156 goto fail
; /* Filename not found */
159 /* Since the first member is the LBA, we simply cast */
160 lba
= *((uint32_t *) MK_PTR(0, fd
.handle
));
162 /* Call comapi_close() to free the structure */
163 close_file(fd
.handle
);
170 /* drive offset detection */
171 int drvoff_detect(int type
)
173 if (bpbV40
<= type
&& type
<= bpbVNT
) {
175 } else if (type
== bpbV70
) {
177 } else if (type
== bpbEXF
) {
185 * heuristics could certainly be improved
187 int bpb_detect(const uint8_t *sec
, const char *tag
)
189 int a
, b
, c
, jmp
= -1, rev
= 0;
191 /* exFAT mess first (media descriptor is 0 here) */
192 if (!memcmp(sec
+ 0x03, "EXFAT ", 8)) {
197 /* media descriptor check */
198 if ((sec
[0x15] & 0xF0) != 0xF0)
201 if (sec
[0] == 0xEB) /* jump short */
202 jmp
= 2 + *(int8_t *)(sec
+ 1);
203 else if (sec
[0] == 0xE9) /* jump near */
204 jmp
= 3 + *(int16_t *)(sec
+ 1);
206 if (jmp
< 0) /* no boot code at all ? */
210 if (jmp
< 0x18 || jmp
> 0x1F0)
214 if (jmp
>= 0x18 && jmp
< 0x1E)
216 else if (jmp
>= 0x1E && jmp
< 0x20)
218 else if (jmp
>= 0x20 && jmp
< 0x24)
220 else if (jmp
>= 0x24 && jmp
< 0x46)
223 /* TODO: some better V2 - V3.4 checks ? */
230 * 3.0 == 2.0 + 0x18 - 0x1D
231 * 3.2 == 3.0 + 0x1E - 0x1F
232 * 3.4 ==!2.0 + 0x18 - 0x23
233 * 4.0 == 3.4 + 0x24 - 0x45
234 * NT ==~3.4 + 0x24 - 0x53
235 * 7.0 == 3.4 + 0x24 - 0x59
239 a
= memcmp(sec
+ 0x03, "NTFS", 4);
240 b
= memcmp(sec
+ 0x36, "FAT", 3);
241 c
= memcmp(sec
+ 0x52, "FAT", 3); /* ext. DOS 7+ bs */
243 if ((sec
[0x26] & 0xFE) == 0x28 && !b
) {
245 } else if (sec
[0x26] == 0x80 && !a
) {
247 } else if ((sec
[0x42] & 0xFE) == 0x28 && !c
) {
252 printf("BPB detection (%s): %s\n", tag
, bpbtypes
[rev
]);
256 /* vim: set ts=8 sts=4 sw=4 noet: */