1 /* ----------------------------------------------------------------------- *
3 * Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
4 * Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin
5 * Copyright 2011 Paulo Alcantara <pcacjr@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
10 * Boston MA 02111-1307, USA; either version 2 of the License, or
11 * (at your option) any later version; incorporated herein by reference.
13 * ----------------------------------------------------------------------- */
20 #if defined(__386__) || defined(__i386__) || defined(__x86_64__)
21 # define X86_MEM 1 /* Littleendian and unaligned safe */
27 * Access functions for littleendian numbers, possibly misaligned.
29 static inline uint8_t get_8(const uint8_t * p)
34 static inline uint16_t get_16(const uint16_t * p)
37 /* Littleendian and unaligned-capable */
40 const uint8_t *pp = (const uint8_t *)p;
41 return pp[0] + ((uint16_t)pp[1] << 8);
45 static inline uint32_t get_32(const uint32_t * p)
48 /* Littleendian and unaligned-capable */
51 const uint16_t *pp = (const uint16_t *)p;
52 return get_16(pp[0]) + (uint32_t)get_16(pp[1]);
56 static inline uint64_t get_64(const uint64_t * p)
59 /* Littleendian and unaligned-capable */
62 const uint32_t *pp = (const uint32_t *)p;
63 return get_32(pp[0]) + (uint64_t)get_32(pp[1]);
67 static inline void set_8(uint8_t *p, uint8_t v)
72 static inline void set_16(uint16_t *p, uint16_t v)
75 /* Littleendian and unaligned-capable */
78 uint8_t *pp = (uint8_t *) p;
80 pp[1] = ((v >> 8) & 0xff);
84 static inline void set_32(uint32_t *p, uint32_t v)
87 /* Littleendian and unaligned-capable */
90 uint8_t *pp = (uint8_t *) p;
92 pp[1] = ((v >> 8) & 0xff);
93 pp[2] = ((v >> 16) & 0xff);
94 pp[3] = ((v >> 24) & 0xff);
98 static inline void set_64(uint64_t *p, uint64_t v)
101 /* Littleendian and unaligned-capable */
104 uint32_t *pp = (uint32_t *) p;
106 set_32(pp[1], v >> 32);
111 * Special handling for the MS-DOS derivative: syslinux_ldlinux
112 * is a "far" object...
116 static inline __attribute__ ((const))
120 asm("movw %%ds,%0":"=rm"(v));
124 static inline void *set_fs(const void *p)
128 seg = ds() + ((size_t) p >> 4);
129 asm volatile ("movw %0,%%fs"::"rm" (seg));
130 return (void *)((size_t) p & 0xf);
133 uint8_t get_8_sl(const uint8_t * p);
134 uint16_t get_16_sl(const uint16_t * p);
135 uint32_t get_32_sl(const uint32_t * p);
136 uint64_t get_64_sl(const uint64_t * p);
137 void set_8_sl(uint8_t * p, uint8_t v);
138 void set_16_sl(uint16_t * p, uint16_t v);
139 void set_32_sl(uint32_t * p, uint32_t v);
140 void set_64_sl(uint64_t * p, uint64_t v);
141 void memcpy_to_sl(void *dst, const void *src, size_t len);
142 void memcpy_from_sl(void *dst, const void *src, size_t len);
146 /* Sane system ... */
147 #define get_8_sl(x) get_8(x)
148 #define get_16_sl(x) get_16(x)
149 #define get_32_sl(x) get_32(x)
150 #define get_64_sl(x) get_64(x)
151 #define set_8_sl(x,y) set_8(x,y)
152 #define set_16_sl(x,y) set_16(x,y)
153 #define set_32_sl(x,y) set_32(x,y)
154 #define set_64_sl(x,y) set_64(x,y)
155 #define memcpy_to_sl(d,s,l) memcpy(d,s,l)
156 #define memcpy_from_sl(d,s,l) memcpy(d,s,l)
160 #define LDLINUX_MAGIC 0x3eb202fe
161 #define BS_MAGIC_VER (0x1b << 9)
163 /* Patch area for disk-based installers */
165 uint32_t magic; /* LDLINUX_MAGIC */
166 uint32_t instance; /* Per-version value */
167 uint16_t data_sectors;
168 uint16_t adv_sectors;
171 uint16_t maxtransfer;
172 uint16_t epaoffset; /* Pointer to the extended patch area */
175 struct ext_patch_area {
176 uint16_t advptroffset; /* ADV pointers */
177 uint16_t diroffset; /* Current directory field */
178 uint16_t dirlen; /* Length of current directory field */
179 uint16_t subvoloffset; /* Subvolume field */
180 uint16_t subvollen; /* Length of subvolume field */
181 uint16_t secptroffset; /* Sector extent pointers */
182 uint16_t secptrcnt; /* Number of sector extent pointers */
184 uint16_t sect1ptr0; /* Boot sector offset of sector 1 ptr LSW */
185 uint16_t sect1ptr1; /* Boot sector offset of sector 1 ptr MSW */
186 uint16_t raidpatch; /* Boot sector RAID mode patch pointer */
190 struct syslinux_extent {
193 } __attribute__((packed));
195 /* FAT bootsector format, also used by other disk-based derivatives */
196 struct fat_boot_sector {
199 uint16_t bsBytesPerSec;
200 uint8_t bsSecPerClust;
201 uint16_t bsResSectors;
203 uint16_t bsRootDirEnts;
207 uint16_t bsSecPerTrack;
209 uint32_t bsHiddenSecs;
210 uint32_t bsHugeSectors;
216 uint8_t BootSignature;
218 char VolumeLabel[11];
221 } __attribute__ ((packed)) bs16;
229 uint8_t Reserved0[12];
232 uint8_t BootSignature;
234 char VolumeLabel[11];
237 } __attribute__ ((packed)) bs32;
238 } __attribute__ ((packed));
241 uint16_t bsForwardPtr;
242 uint16_t bsSignature;
243 } __attribute__ ((packed));
245 /* NTFS bootsector format */
246 struct ntfs_boot_sector {
249 uint16_t bsBytesPerSec;
250 uint8_t bsSecPerClust;
251 uint16_t bsResSectors;
252 uint8_t bsZeroed_0[3];
261 uint64_t bsTotalSectors;
262 uint64_t bsMFTLogicalClustNr;
263 uint64_t bsMFTMirrLogicalClustNr;
264 uint8_t bsClustPerMFTrecord;
265 uint8_t bsUnused_4[3];
266 uint8_t bsClustPerIdxBuf;
267 uint8_t bsUnused_5[3];
268 uint64_t bsVolSerialNr;
274 uint16_t bsForwardPtr;
275 uint16_t bsSignature;
276 } __attribute__((packed));
278 #define FAT_bsHead bsJump
279 #define FAT_bsHeadLen offsetof(struct fat_boot_sector, bsBytesPerSec)
280 #define FAT_bsCode bs32.Code /* The common safe choice */
281 #define FAT_bsCodeLen (offsetof(struct fat_boot_sector, bsSignature) - \
282 offsetof(struct fat_boot_sector, FAT_bsCode))
284 #define NTFS_bsHead bsJump
285 #define NTFS_bsHeadLen offsetof(struct ntfs_boot_sector, bsOemName)
286 #define NTFS_bsCode Code
287 #define NTFS_bsCodeLen (offsetof(struct ntfs_boot_sector, bsSignature) - \
288 offsetof(struct ntfs_boot_sector, NTFS_bsCode))
290 /* Check if there are specific zero fields in an NTFS boot sector */
291 static inline int ntfs_check_zero_fields(const struct ntfs_boot_sector *sb)
293 return !sb->bsResSectors && (!sb->bsZeroed_0[0] && !sb->bsZeroed_0[1] &&
294 !sb->bsZeroed_0[2]) && !sb->bsZeroed_1 && !sb->bsZeroed_2 &&
298 static inline int ntfs_check_sb_fields(const struct ntfs_boot_sector *sb)
300 return ntfs_check_zero_fields(sb) &&
301 (!memcmp(sb->bsOemName, "NTFS ", 8) ||
302 !memcmp(sb->bsOemName, "MSWIN4.0", 8) ||
303 !memcmp(sb->bsOemName, "MSWIN4.1", 8));
306 static inline int fat_check_sb_fields(const struct fat_boot_sector *sb)
308 return sb->bsResSectors && sb->bsFATs &&
309 (!memcmp(sb->bs16.FileSysType, "FAT12 ", 8) ||
310 !memcmp(sb->bs16.FileSysType, "FAT16 ", 8) ||
311 !memcmp(sb->bs16.FileSysType, "FAT ", 8) ||
312 !memcmp(sb->bs32.FileSysType, "FAT32 ", 8));
315 #endif /* SYSLXINT_H */