summaryrefslogtreecommitdiffstats
path: root/contrib/syslinux-4.02/com32/gpllib/disk
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/syslinux-4.02/com32/gpllib/disk')
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/ata.c62
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/bootloaders.c46
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/errno_disk.c12
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/error.c23
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/geom.c271
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/labels.c654
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/mbrs.c127
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/msdos.c162
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/read.c135
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/swsusp.c27
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/util.c45
-rw-r--r--contrib/syslinux-4.02/com32/gpllib/disk/write.c126
12 files changed, 1690 insertions, 0 deletions
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/ata.c b/contrib/syslinux-4.02/com32/gpllib/disk/ata.c
new file mode 100644
index 0000000..78f669e
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/ata.c
@@ -0,0 +1,62 @@
+#include <inttypes.h>
+#include <string.h>
+
+/**
+ * ata_id_string - Convert IDENTIFY DEVICE page into string
+ * @id: IDENTIFY DEVICE results we will examine
+ * @s: string into which data is output
+ * @ofs: offset into identify device page
+ * @len: length of string to return. must be an even number.
+ *
+ * The strings in the IDENTIFY DEVICE page are broken up into
+ * 16-bit chunks. Run through the string, and output each
+ * 8-bit chunk linearly, regardless of platform.
+ *
+ * LOCKING:
+ * caller.
+ */
+void ata_id_string(const uint16_t * id, unsigned char *s,
+ unsigned int ofs, unsigned int len)
+{
+ unsigned int c;
+
+ while (len > 0) {
+ c = id[ofs] >> 8;
+ *s = c;
+ s++;
+
+ c = id[ofs] & 0xff;
+ *s = c;
+ s++;
+
+ ofs++;
+ len -= 2;
+ }
+}
+
+/**
+ * ata_id_c_string - Convert IDENTIFY DEVICE page into C string
+ * @id: IDENTIFY DEVICE results we will examine
+ * @s: string into which data is output
+ * @ofs: offset into identify device page
+ * @len: length of string to return. must be an odd number.
+ *
+ * This function is identical to ata_id_string except that it
+ * trims trailing spaces and terminates the resulting string with
+ * null. @len must be actual maximum length (even number) + 1.
+ *
+ * LOCKING:
+ * caller.
+ */
+void ata_id_c_string(const uint16_t * id, unsigned char *s,
+ unsigned int ofs, unsigned int len)
+{
+ unsigned char *p;
+
+ ata_id_string(id, s, ofs, len - 1);
+
+ p = s + strnlen((const char *)s, len - 1);
+ while (p > s && p[-1] == ' ')
+ p--;
+ *p = '\0';
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/bootloaders.c b/contrib/syslinux-4.02/com32/gpllib/disk/bootloaders.c
new file mode 100644
index 0000000..e034011
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/bootloaders.c
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/bootloaders.h>
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * get_bootloader_string - return a string describing the boot code in a
+ * bootsector
+ * @d: driveinfo struct describing the drive
+ * @p: partition to scan (usually the active one)
+ * @buffer: pre-allocated buffer
+ * @buffer_size: @buffer size
+ **/
+int get_bootloader_string(struct driveinfo *d, const struct part_entry *p,
+ char *buffer, const int buffer_size)
+{
+ char boot_sector[SECTOR * sizeof(char)];
+
+ if (read_sectors(d, &boot_sector, p->start_lba, 1) == -1)
+ return -1;
+ else {
+ if (!strncmp(boot_sector + 3, "SYSLINUX", 8))
+ strlcpy(buffer, "SYSLINUX", buffer_size - 1);
+ else if (!strncmp(boot_sector + 3, "EXTLINUX", 8))
+ strlcpy(buffer, "EXTLINUX", buffer_size - 1);
+ else if (!strncmp(boot_sector + 3, "MSWIN4.1", 8))
+ strlcpy(buffer, "MSWIN4.1", buffer_size - 1);
+ else
+ return -1;
+ /* Add more... */
+
+ buffer[buffer_size - 1] = '\0';
+ return 0;
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/errno_disk.c b/contrib/syslinux-4.02/com32/gpllib/disk/errno_disk.c
new file mode 100644
index 0000000..8a68802
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/errno_disk.c
@@ -0,0 +1,12 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/errno_disk.h>
+
+int errno_disk;
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/error.c b/contrib/syslinux-4.02/com32/gpllib/disk/error.c
new file mode 100644
index 0000000..fe4722e
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/error.c
@@ -0,0 +1,23 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <disk/errno_disk.h>
+
+/**
+ * get_error - decode a disk error status
+ * @s: Preallocated buffer
+ *
+ * Fill @buffer_ptr with the last errno_disk
+ **/
+void get_error(const char *s)
+{
+ fprintf(stderr, "%s: error %d\n", s, errno_disk);
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/geom.c b/contrib/syslinux-4.02/com32/gpllib/disk/geom.c
new file mode 100644
index 0000000..9e673ed
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/geom.c
@@ -0,0 +1,271 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * Some parts borrowed from chain.c32:
+ *
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <string.h>
+#include <stdio.h>
+#include <disk/geom.h>
+
+#include <stdio.h>
+
+/**
+ * lba_to_chs - split given lba into cylinders/heads/sectors
+ **/
+void lba_to_chs(const struct driveinfo *drive_info, const int lba,
+ unsigned int *cylinder, unsigned int *head,
+ unsigned int *sector)
+{
+ unsigned int track;
+
+ /* Use EDD, if valid */
+ if (drive_info->edd_params.sectors_per_track > 0 &&
+ drive_info->edd_params.heads > 0) {
+ *cylinder = (lba % drive_info->edd_params.sectors_per_track) + 1;
+ track = lba / drive_info->edd_params.sectors_per_track;
+ *head = track % drive_info->edd_params.heads;
+ *sector = track / drive_info->edd_params.heads;
+ } else if (drive_info->cbios) {
+ *cylinder = (lba % drive_info->legacy_sectors_per_track) + 1;
+ track = lba / drive_info->legacy_sectors_per_track;
+ *head = track % (drive_info->legacy_max_head + 1);
+ *sector = track / (drive_info->legacy_max_head + 1);
+ }
+}
+
+/**
+ * detect_extensions - detect if we can use extensions
+ *
+ * INT 13 - IBM/MS INT 13 Extensions - INSTALLATION CHECK
+ * AH = 41h
+ * BX = 55AAh
+ * DL = drive (80h-FFh)
+ *
+ * Return: CF set on error (extensions not supported)
+ * AH = 01h (invalid function)
+ * CF clear if successful
+ * BX = AA55h if installed
+ * AH = major version of extensions
+ * 01h = 1.x
+ * 20h = 2.0 / EDD-1.0
+ * 21h = 2.1 / EDD-1.1
+ * 30h = EDD-3.0
+ * AL = internal use
+ * CX = API subset support bitmap (see #00271)
+ * DH = extension version (v2.0+ ??? -- not present in 1.x)
+ *
+ * Note: the Phoenix Enhanced Disk Drive Specification v1.0 uses version 2.0 of
+ * the INT 13 Extensions API
+ *
+ * Bitfields for IBM/MS INT 13 Extensions API support bitmap:
+ * Bit(s) Description (Table 00271)
+ * 0 extended disk access functions (AH=42h-44h,47h,48h) supported
+ * 1 removable drive controller functions (AH=45h,46h,48h,49h,INT 15/AH=52h)
+ * supported
+ * 2 enhanced disk drive (EDD) functions (AH=48h,AH=4Eh) supported
+ * extended drive parameter table is valid (see #00273,#00278)
+ * 3-15 reserved (0)
+ **/
+static int detect_extensions(struct driveinfo *drive_info)
+{
+ com32sys_t getebios, ebios;
+
+ memset(&getebios, 0, sizeof getebios);
+ memset(&ebios, 0, sizeof ebios);
+
+ getebios.eflags.b[0] = 0x3; /* CF set */
+ getebios.ebx.w[0] = 0x55aa;
+ getebios.edx.b[0] = drive_info->disk;
+ getebios.eax.b[1] = 0x41;
+
+ __intcall(0x13, &getebios, &ebios);
+
+ if (!(ebios.eflags.l & EFLAGS_CF) && ebios.ebx.w[0] == 0xaa55) {
+ drive_info->ebios = 1;
+ drive_info->edd_version = ebios.eax.b[1];
+ drive_info->edd_functionality_subset = ebios.ecx.w[0];
+ return 0;
+ } else
+ return -1; /* Drive does not exist? */
+}
+
+/**
+ * get_drive_parameters_with_extensions - retrieve disk parameters via AH=48h
+ *
+ * INT 13 - IBM/MS INT 13 Extensions - GET DRIVE PARAMETERS
+ * AH = 48h
+ * DL = drive (80h-FFh)
+ * DS:SI -> buffer for drive parameters
+ * Return: CF clear if successful
+ * AH = 00h
+ * DS:SI buffer filled
+ * CF set on error
+ * AH = error code (see #00234)
+ * BUG: several different Compaq BIOSes incorrectly report high-numbered
+ * drives (such as 90h, B0h, D0h, and F0h) as present, giving them the
+ * same geometry as drive 80h; as a workaround, scan through disk
+ * numbers, stopping as soon as the number of valid drives encountered
+ * equals the value in 0040h:0075h
+ **/
+static int get_drive_parameters_with_extensions(struct driveinfo *drive_info)
+{
+ com32sys_t inreg, outreg;
+ struct edd_device_parameters *dp = __com32.cs_bounce;
+
+ memset(&inreg, 0, sizeof inreg);
+
+ /*
+ * The caller shall set this value to the maximum Result Buffer
+ * length, in bytes. If the length of this buffer is less than 30
+ * bytes, this function shall not return the pointer to Drive Parameter
+ * Table (DPT) extension. If the buffer length is 30 or greater on
+ * entry, it shall be set to 30 on exit. If the buffer length is
+ * between 26 and 29, it shall be set to 26 on exit.
+ * If the buffer length is less than 26 on entry an error shall be
+ * returned.
+ */
+ dp->len = sizeof(struct edd_device_parameters);
+
+ inreg.esi.w[0] = OFFS(dp);
+ inreg.ds = SEG(dp);
+ inreg.edx.b[0] = drive_info->disk;
+ inreg.eax.b[1] = 0x48;
+
+ __intcall(0x13, &inreg, &outreg);
+
+ /* CF set on error */
+ if (outreg.eflags.l & EFLAGS_CF)
+ return outreg.eax.b[1];
+
+ memcpy(&drive_info->edd_params, dp, sizeof drive_info->edd_params);
+
+ return 0;
+}
+
+/**
+ * get_drive_parameters_without_extensions - retrieve drive parameters via AH=08h
+ *
+ * INT 13 - DISK - GET DRIVE PARAMETERS (PC,XT286,CONV,PS,ESDI,SCSI)
+ * AH = 08h
+ * DL = drive (bit 7 set for hard disk)
+ *
+ * Return: CF set on error
+ * AH = status (07h) (see #00234)
+ * CF clear if successful
+ * AH = 00h
+ * AL = 00h on at least some BIOSes
+ * BL = drive type (AT/PS2 floppies only) (see #00242)
+ * CH = low eight bits of maximum cylinder number
+ * CL = maximum sector number (bits 5-0)
+ * high two bits of maximum cylinder number (bits 7-6)
+ * DH = maximum head number
+ * DL = number of drives
+ * ES:DI -> drive parameter table (floppies only)
+ *
+ * Notes:
+ * - may return successful even though specified drive is greater than the
+ * number of attached drives of that type (floppy/hard); check DL to
+ * ensure validity
+ * - for systems predating the IBM AT, this call is only valid for hard
+ * disks, as it is implemented by the hard disk BIOS rather than the
+ * ROM BIOS
+ * - Toshiba laptops with HardRAM return DL=02h when called with DL=80h,
+ * but fail on DL=81h. The BIOS data at 40h:75h correctly reports 01h.
+ * may indicate only two drives present even if more are attached; to
+ * ensure a correct count, one can use AH=15h to scan through possible
+ * drives
+ * - for BIOSes which reserve the last cylinder for testing purposes, the
+ * cylinder count is automatically decremented
+ * on PS/1s with IBM ROM DOS 4, nonexistent drives return CF clear,
+ * BX=CX=0000h, and ES:DI = 0000h:0000h
+ * - the PC-Tools PCFORMAT program requires that AL=00h before it will
+ * proceed with the formatting
+ *
+ * BUG: several different Compaq BIOSes incorrectly report high-numbered
+ * drives (such as 90h, B0h, D0h, and F0h) as present, giving them the
+ * same geometry as drive 80h; as a workaround, scan through disk
+ * numbers, stopping as soon as the number of valid drives encountered
+ * equals the value in 0040h:0075h
+ *
+ * SeeAlso: AH=06h"Adaptec",AH=13h"SyQuest",AH=48h,AH=15h,INT 1E
+ * SeeAlso: INT 41"HARD DISK 0"
+ **/
+static int get_drive_parameters_without_extensions(struct driveinfo *drive_info)
+{
+ com32sys_t getparm, parm;
+
+ memset(&getparm, 0, sizeof getparm);
+ memset(&parm, 0, sizeof parm);
+
+ /* Ralf Brown recommends setting ES:DI to 0:0 */
+ getparm.esi.w[0] = 0;
+ getparm.ds = 0;
+ getparm.edx.b[0] = drive_info->disk;
+ getparm.eax.b[1] = 0x08;
+
+ __intcall(0x13, &getparm, &parm);
+
+ /* CF set on error */
+ if (parm.eflags.l & EFLAGS_CF)
+ return parm.eax.b[1];
+
+ /* DL contains the maximum drive number (it starts at 0) */
+ drive_info->legacy_max_drive = parm.edx.b[0];
+
+ // XXX broken
+ /* Drive specified greater than the bumber of attached drives */
+ //if (drive_info->disk > drive_info->drives)
+ // return -1;
+
+ drive_info->legacy_type = parm.ebx.b[0];
+
+ /* DH contains the maximum head number (it starts at 0) */
+ drive_info->legacy_max_head = parm.edx.b[1];
+
+ /* Maximum sector number (bits 5-0) per track */
+ drive_info->legacy_sectors_per_track = parm.ecx.b[0] & 0x3f;
+
+ /*
+ * Maximum cylinder number:
+ * CH = low eight bits of maximum cylinder number
+ * CL = high two bits of maximum cylinder number (bits 7-6)
+ */
+ drive_info->legacy_max_cylinder = parm.ecx.b[1] +
+ ((parm.ecx.b[0] & 0xc0) << 2);
+
+ if (drive_info->legacy_sectors_per_track > 0)
+ drive_info->cbios = 1; /* Valid geometry */
+
+ return 0;
+}
+
+/**
+ * get_drive_parameters - retrieve drive parameters
+ * @drive_info: driveinfo structure to fill
+ **/
+int get_drive_parameters(struct driveinfo *drive_info)
+{
+ int return_code;
+
+ if (detect_extensions(drive_info))
+ return -1;
+
+ return_code = get_drive_parameters_without_extensions(drive_info);
+
+ /* If geometry isn't valid, no need to try to get more info about the drive */
+ /* Looks like in can confuse some optical drives */
+ if (drive_info->ebios && drive_info->cbios)
+ get_drive_parameters_with_extensions(drive_info);
+
+ return return_code;
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/labels.c b/contrib/syslinux-4.02/com32/gpllib/disk/labels.c
new file mode 100644
index 0000000..ad3d33b
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/labels.c
@@ -0,0 +1,654 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+
+void get_label(int label, char **buffer_label)
+{
+ int buffer_size = (80 * sizeof(char));
+ char *buffer = malloc(buffer_size);
+ *buffer_label = buffer;
+
+ switch (label) {
+ case 0x01:
+ strlcpy(buffer, "DOS 12-bit fat", buffer_size);
+ break;
+ case 0x02:
+ strlcpy(buffer, "XENIX root", buffer_size);
+ break;
+ case 0x03:
+ strlcpy(buffer, "XENIX /usr", buffer_size);
+ break;
+ case 0x04:
+ strlcpy(buffer, "DOS 3.0+ 16-bit FAT (up to 32M)", buffer_size);
+ break;
+ case 0x05:
+ strlcpy(buffer, "DOS 3.3+ Extended Partition", buffer_size);
+ break;
+ case 0x06:
+ strlcpy(buffer, "DOS 3.31+ 16-bit FAT (over 32M)", buffer_size);
+ break;
+ case 0x07:
+ strlcpy(buffer, "OS/2 IFS (e.g., HPFS)", buffer_size);
+ break;
+ //case 0x07: strlcpy(buffer, "Advanced Unix", buffer_size); break;
+ //case 0x07: strlcpy(buffer, "Windows NT NTFS", buffer_size); break;
+ //case 0x07: strlcpy(buffer, "QNX2.x (pre-1988)", buffer_size); break;
+ case 0x08:
+ strlcpy(buffer, "OS/2 (v1.0-1.3 only)", buffer_size);
+ break;
+ //case 0x08: strlcpy(buffer, "AIX boot partition", buffer_size); break;
+ //case 0x08: strlcpy(buffer, "SplitDrive", buffer_size); break;
+ //case 0x08: strlcpy(buffer, "DELL partition spanning multiple drives", buffer_size); break;
+ //case 0x08: strlcpy(buffer, "Commodore DOS", buffer_size); break;
+ //case 0x08: strlcpy(buffer, "QNX 1.x and 2.x ("qny")", buffer_size); break;
+ case 0x09:
+ strlcpy(buffer, "AIX data partition", buffer_size);
+ break;
+ //case 0x09: strlcpy(buffer, "Coherent filesystem", buffer_size); break;
+ //case 0x09: strlcpy(buffer, "QNX 1.x and 2.x ("qnz")", buffer_size); break;
+ case 0x0a:
+ strlcpy(buffer, "OS/2 Boot Manager", buffer_size);
+ break;
+ //case 0x0a: strlcpy(buffer, "Coherent swap partition", buffer_size); break;
+ //case 0x0a: strlcpy(buffer, "OPUS", buffer_size); break;
+ case 0x0b:
+ strlcpy(buffer, "WIN95 OSR2 32-bit FAT", buffer_size);
+ break;
+ case 0x0c:
+ strlcpy(buffer, "WIN95 OSR2 32-bit FAT, LBA-mapped", buffer_size);
+ break;
+ case 0x0e:
+ strlcpy(buffer, "WIN95: DOS 16-bit FAT, LBA-mapped", buffer_size);
+ break;
+ case 0x0f:
+ strlcpy(buffer, "WIN95: Extended partition, LBA-mapped", buffer_size);
+ break;
+ case 0x10:
+ strlcpy(buffer, "OPUS (?)", buffer_size);
+ break;
+ case 0x11:
+ strlcpy(buffer, "Hidden DOS 12-bit FAT", buffer_size);
+ break;
+ case 0x12:
+ strlcpy(buffer, "Compaq config partition", buffer_size);
+ break;
+ case 0x14:
+ strlcpy(buffer, "Hidden DOS 16-bit FAT <32M", buffer_size);
+ break;
+ case 0x16:
+ strlcpy(buffer, "Hidden DOS 16-bit FAT >=32M", buffer_size);
+ break;
+ case 0x17:
+ strlcpy(buffer, "Hidden IFS (e.g., HPFS)", buffer_size);
+ break;
+ case 0x18:
+ strlcpy(buffer, "AST SmartSleep Partition", buffer_size);
+ break;
+ case 0x19:
+ strlcpy(buffer, "Unused (Claimed for Willowtech Photon COS)",
+ buffer_size);
+ break;
+ case 0x1b:
+ strlcpy(buffer, "Hidden WIN95 OSR2 32-bit FAT", buffer_size);
+ break;
+ case 0x1c:
+ strlcpy(buffer, "Hidden WIN95 OSR2 32-bit FAT, LBA-mapped",
+ buffer_size);
+ break;
+ case 0x1e:
+ strlcpy(buffer, "Hidden WIN95 16-bit FAT, LBA-mapped", buffer_size);
+ break;
+ case 0x20:
+ strlcpy(buffer, "Unused", buffer_size);
+ break;
+ case 0x21:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ //case 0x21: strlcpy(buffer, "Unused", buffer_size); break;
+ case 0x22:
+ strlcpy(buffer, "Unused", buffer_size);
+ break;
+ case 0x23:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x24:
+ strlcpy(buffer, "NEC DOS 3.x", buffer_size);
+ break;
+ case 0x26:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x31:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x32:
+ strlcpy(buffer, "NOS", buffer_size);
+ break;
+ case 0x33:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x34:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x35:
+ strlcpy(buffer, "JFS on OS/2 or eCS", buffer_size);
+ break;
+ case 0x36:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x38:
+ strlcpy(buffer, "THEOS ver 3.2 2gb partition", buffer_size);
+ break;
+ case 0x39:
+ strlcpy(buffer, "Plan 9 partition", buffer_size);
+ break;
+ //case 0x39: strlcpy(buffer, "THEOS ver 4 spanned partition", buffer_size); break;
+ case 0x3a:
+ strlcpy(buffer, "THEOS ver 4 4gb partition", buffer_size);
+ break;
+ case 0x3b:
+ strlcpy(buffer, "THEOS ver 4 extended partition", buffer_size);
+ break;
+ case 0x3c:
+ strlcpy(buffer, "PartitionMagic recovery partition", buffer_size);
+ break;
+ case 0x3d:
+ strlcpy(buffer, "Hidden NetWare", buffer_size);
+ break;
+ case 0x40:
+ strlcpy(buffer, "Venix 80286", buffer_size);
+ break;
+ case 0x41:
+ strlcpy(buffer, "Linux/MINIX (sharing disk with DRDOS)", buffer_size);
+ break;
+ //case 0x41: strlcpy(buffer, "Personal RISC Boot", buffer_size); break;
+ //case 0x41: strlcpy(buffer, "PPC PReP (Power PC Reference Platform) Boot", buffer_size); break;
+ case 0x42:
+ strlcpy(buffer, "Linux swap (sharing disk with DRDOS)", buffer_size);
+ break;
+ //case 0x42: strlcpy(buffer, "SFS (Secure Filesystem)", buffer_size); break;
+ //case 0x42: strlcpy(buffer, "Windows 2000 marker", buffer_size); break;
+ case 0x43:
+ strlcpy(buffer, "Linux native (sharing disk with DRDOS)", buffer_size);
+ break;
+ case 0x44:
+ strlcpy(buffer, "GoBack partition", buffer_size);
+ break;
+ case 0x45:
+ strlcpy(buffer, "Boot-US boot manager", buffer_size);
+ break;
+ //case 0x45: strlcpy(buffer, "Priam", buffer_size); break;
+ //case 0x45: strlcpy(buffer, "EUMEL/Elan", buffer_size); break;
+ case 0x46:
+ strlcpy(buffer, "EUMEL/Elan", buffer_size);
+ break;
+ case 0x47:
+ strlcpy(buffer, "EUMEL/Elan", buffer_size);
+ break;
+ case 0x48:
+ strlcpy(buffer, "EUMEL/Elan", buffer_size);
+ break;
+ case 0x4a:
+ strlcpy(buffer, "AdaOS Aquila (Default)", buffer_size);
+ break;
+ //case 0x4a: strlcpy(buffer, "ALFS/THIN lightweight filesystem for DOS", buffer_size); break;
+ case 0x4c:
+ strlcpy(buffer, "Oberon partition", buffer_size);
+ break;
+ case 0x4d:
+ strlcpy(buffer, "QNX4.x", buffer_size);
+ break;
+ case 0x4e:
+ strlcpy(buffer, "QNX4.x 2nd part", buffer_size);
+ break;
+ case 0x4f:
+ strlcpy(buffer, "QNX4.x 3rd part", buffer_size);
+ break;
+ //case 0x4f: strlcpy(buffer, "Oberon partition", buffer_size); break;
+ case 0x50:
+ strlcpy(buffer, "OnTrack Disk Manager (older versions) RO",
+ buffer_size);
+ break;
+ //case 0x50: strlcpy(buffer, "Lynx RTOS", buffer_size); break;
+ //case 0x50: strlcpy(buffer, "Native Oberon (alt)", buffer_size); break;
+ case 0x51:
+ strlcpy(buffer, "OnTrack Disk Manager RW (DM6 Aux1)", buffer_size);
+ break;
+ //case 0x51: strlcpy(buffer, "Novell", buffer_size); break;
+ case 0x52:
+ strlcpy(buffer, "CP/M", buffer_size);
+ break;
+ //case 0x52: strlcpy(buffer, "Microport SysV/AT", buffer_size); break;
+ case 0x53:
+ strlcpy(buffer, "Disk Manager 6.0 Aux3", buffer_size);
+ break;
+ case 0x54:
+ strlcpy(buffer, "Disk Manager 6.0 Dynamic Drive Overlay", buffer_size);
+ break;
+ case 0x55:
+ strlcpy(buffer, "EZ-Drive", buffer_size);
+ break;
+ case 0x56:
+ strlcpy(buffer, "Golden Bow VFeature Partitioned Volume.", buffer_size);
+ break;
+ //case 0x56: strlcpy(buffer, "DM converted to EZ-BIOS", buffer_size); break;
+ case 0x57:
+ strlcpy(buffer, "DrivePro", buffer_size);
+ break;
+ //case 0x57: strlcpy(buffer, "VNDI Partition", buffer_size); break;
+ case 0x5c:
+ strlcpy(buffer, "Priam EDisk", buffer_size);
+ break;
+ case 0x61:
+ strlcpy(buffer, "SpeedStor", buffer_size);
+ break;
+ case 0x63:
+ strlcpy(buffer,
+ "Unix System V (SCO, ISC Unix, UnixWare, ...), Mach, GNU Hurd",
+ buffer_size);
+ break;
+ case 0x64:
+ strlcpy(buffer, "PC-ARMOUR protected partition", buffer_size);
+ break;
+ //case 0x64: strlcpy(buffer, "Novell Netware 286, 2.xx", buffer_size); break;
+ case 0x65:
+ strlcpy(buffer, "Novell Netware 386, 3.xx or 4.xx", buffer_size);
+ break;
+ case 0x66:
+ strlcpy(buffer, "Novell Netware SMS Partition", buffer_size);
+ break;
+ case 0x67:
+ strlcpy(buffer, "Novell", buffer_size);
+ break;
+ case 0x68:
+ strlcpy(buffer, "Novell", buffer_size);
+ break;
+ case 0x69:
+ strlcpy(buffer, "Novell Netware 5+, Novell Netware NSS Partition",
+ buffer_size);
+ break;
+ case 0x70:
+ strlcpy(buffer, "DiskSecure Multi-Boot", buffer_size);
+ break;
+ case 0x71:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x73:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x74:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ //case 0x74: strlcpy(buffer, "Scramdisk partition", buffer_size); break;
+ case 0x75:
+ strlcpy(buffer, "IBM PC/IX", buffer_size);
+ break;
+ case 0x76:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0x77:
+ strlcpy(buffer, "M2FS/M2CS partition", buffer_size);
+ break;
+ //case 0x77: strlcpy(buffer, "VNDI Partition", buffer_size); break;
+ case 0x78:
+ strlcpy(buffer, "XOSL FS", buffer_size);
+ break;
+ case 0x7E:
+ strlcpy(buffer, " ", buffer_size);
+ break;
+ case 0x80:
+ strlcpy(buffer, "MINIX until 1.4a", buffer_size);
+ break;
+ case 0x81:
+ strlcpy(buffer, "MINIX since 1.4b, early Linux", buffer_size);
+ break;
+ //case 0x81: strlcpy(buffer, "Mitac disk manager", buffer_size); break;
+ //case 0x82: strlcpy(buffer, "Prime", buffer_size); break;
+ //case 0x82: strlcpy(buffer, "Solaris x86", buffer_size); break;
+ case 0x82:
+ strlcpy(buffer, "Linux swap", buffer_size);
+ break;
+ case 0x83:
+ strlcpy(buffer, "Linux native (usually ext2fs)", buffer_size);
+ break;
+ case 0x84:
+ strlcpy(buffer, "OS/2 hidden C: drive", buffer_size);
+ break;
+ //case 0x84: strlcpy(buffer, "Hibernation partition", buffer_size); break;
+ case 0x85:
+ strlcpy(buffer, "Linux extended partition", buffer_size);
+ break;
+ //case 0x86: strlcpy(buffer, "Old Linux RAID partition superblock", buffer_size); break;
+ case 0x86:
+ strlcpy(buffer, "NTFS volume set", buffer_size);
+ break;
+ case 0x87:
+ strlcpy(buffer, "NTFS volume set", buffer_size);
+ break;
+ case 0x8a:
+ strlcpy(buffer, "Linux Kernel Partition (used by AiR-BOOT)",
+ buffer_size);
+ break;
+ case 0x8b:
+ strlcpy(buffer, "Legacy Fault Tolerant FAT32 volume", buffer_size);
+ break;
+ case 0x8c:
+ strlcpy(buffer,
+ "Legacy Fault Tolerant FAT32 volume using BIOS extd INT 13h",
+ buffer_size);
+ break;
+ case 0x8d:
+ strlcpy(buffer, "Free FDISK hidden Primary DOS FAT12 partitition",
+ buffer_size);
+ break;
+ case 0x8e:
+ strlcpy(buffer, "Linux Logical Volume Manager partition", buffer_size);
+ break;
+ case 0x90:
+ strlcpy(buffer, "Free FDISK hidden Primary DOS FAT16 partitition",
+ buffer_size);
+ break;
+ case 0x91:
+ strlcpy(buffer, "Free FDISK hidden DOS extended partitition",
+ buffer_size);
+ break;
+ case 0x92:
+ strlcpy(buffer, "Free FDISK hidden Primary DOS large FAT16 partitition",
+ buffer_size);
+ break;
+ case 0x93:
+ strlcpy(buffer, "Hidden Linux native partition", buffer_size);
+ break;
+ //case 0x93: strlcpy(buffer, "Amoeba", buffer_size); break;
+ case 0x94:
+ strlcpy(buffer, "Amoeba bad block table", buffer_size);
+ break;
+ case 0x95:
+ strlcpy(buffer, "MIT EXOPC native partitions", buffer_size);
+ break;
+ case 0x97:
+ strlcpy(buffer, "Free FDISK hidden Primary DOS FAT32 partitition",
+ buffer_size);
+ break;
+ case 0x98:
+ strlcpy(buffer, "Free FDISK hidden Primary DOS FAT32 partitition (LBA)",
+ buffer_size);
+ break;
+ case 0x99:
+ strlcpy(buffer, "DCE376 logical drive", buffer_size);
+ break;
+ case 0x9a:
+ strlcpy(buffer, "Free FDISK hidden Primary DOS FAT16 partitition (LBA)",
+ buffer_size);
+ break;
+ case 0x9b:
+ strlcpy(buffer, "Free FDISK hidden DOS extended partitition (LBA)",
+ buffer_size);
+ break;
+ case 0x9f:
+ strlcpy(buffer, "BSD/OS", buffer_size);
+ break;
+ case 0xa0:
+ strlcpy(buffer, "Laptop hibernation partition", buffer_size);
+ break;
+ case 0xa1:
+ strlcpy(buffer, "Laptop hibernation partition", buffer_size);
+ break;
+ //case 0xa1: strlcpy(buffer, "HP Volume Expansion (SpeedStor variant)", buffer_size); break;
+ case 0xa3:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0xa4:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0xa5:
+ strlcpy(buffer, "BSD/386, 386BSD, NetBSD, FreeBSD", buffer_size);
+ break;
+ case 0xa6:
+ strlcpy(buffer, "OpenBSD", buffer_size);
+ break;
+ case 0xa7:
+ strlcpy(buffer, "NEXTSTEP", buffer_size);
+ break;
+ case 0xa8:
+ strlcpy(buffer, "Mac OS-X", buffer_size);
+ break;
+ case 0xa9:
+ strlcpy(buffer, "NetBSD", buffer_size);
+ break;
+ case 0xaa:
+ strlcpy(buffer, "Olivetti Fat 12 1.44Mb Service Partition",
+ buffer_size);
+ break;
+ case 0xab:
+ strlcpy(buffer, "Mac OS-X Boot partition", buffer_size);
+ break;
+ //case 0xab: strlcpy(buffer, "GO! partition", buffer_size); break;
+ case 0xae:
+ strlcpy(buffer, "ShagOS filesystem", buffer_size);
+ break;
+ case 0xaf:
+ strlcpy(buffer, "ShagOS swap partition", buffer_size);
+ break;
+ case 0xb0:
+ strlcpy(buffer, "BootStar Dummy", buffer_size);
+ break;
+ case 0xb1:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0xb3:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0xb4:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0xb6:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0xb7:
+ strlcpy(buffer, "BSDI BSD/386 filesystem", buffer_size);
+ break;
+ case 0xb8:
+ strlcpy(buffer, "BSDI BSD/386 swap partition", buffer_size);
+ break;
+ case 0xbb:
+ strlcpy(buffer, "Boot Wizard hidden", buffer_size);
+ break;
+ case 0xbe:
+ strlcpy(buffer, "Solaris 8 boot partition", buffer_size);
+ break;
+ case 0xc0:
+ strlcpy(buffer, "CTOS", buffer_size);
+ break;
+ //case 0xc0: strlcpy(buffer, "REAL/32 secure small partition", buffer_size); break;
+ //case 0xc0: strlcpy(buffer, "NTFT Partition", buffer_size); break;
+ case 0xc1:
+ strlcpy(buffer, "DRDOS/secured (FAT-12)", buffer_size);
+ break;
+ case 0xc2:
+ strlcpy(buffer, "Reserved for DR-DOS 7+", buffer_size);
+ break;
+ //case 0xc2: strlcpy(buffer, "Hidden Linux", buffer_size); break;
+ case 0xc3:
+ strlcpy(buffer, "Hidden Linux swap", buffer_size);
+ break;
+ case 0xc4:
+ strlcpy(buffer, "DRDOS/secured (FAT-16, < 32M)", buffer_size);
+ break;
+ case 0xc5:
+ strlcpy(buffer, "DRDOS/secured (extended)", buffer_size);
+ break;
+ case 0xc6:
+ strlcpy(buffer, "DRDOS/secured (FAT-16, >= 32M)", buffer_size);
+ break;
+ //case 0xc6: strlcpy(buffer, "Windows NT corrupted FAT16 volume/stripe set", buffer_size); break;
+ case 0xc7:
+ strlcpy(buffer, "Windows NT corrupted NTFS volume/stripe set",
+ buffer_size);
+ break;
+ //case 0xc7: strlcpy(buffer, "Syrinx boot", buffer_size); break;
+ case 0xc8:
+ strlcpy(buffer, "(See also ID c2.)", buffer_size);
+ break;
+ case 0xc9:
+ strlcpy(buffer, "(See also ID c2.)", buffer_size);
+ break;
+ case 0xca:
+ strlcpy(buffer, "(See also ID c2.)", buffer_size);
+ break;
+ case 0xcb:
+ strlcpy(buffer, "reserved for DRDOS/secured (FAT32)", buffer_size);
+ break;
+ case 0xcc:
+ strlcpy(buffer, "reserved for DRDOS/secured (FAT32, LBA)", buffer_size);
+ break;
+ case 0xcd:
+ strlcpy(buffer, "CTOS Memdump?", buffer_size);
+ break;
+ case 0xce:
+ strlcpy(buffer, "reserved for DRDOS/secured (FAT16, LBA)", buffer_size);
+ break;
+ case 0xd0:
+ strlcpy(buffer, "REAL/32 secure big partition", buffer_size);
+ break;
+ case 0xd1:
+ strlcpy(buffer, "Old Multiuser DOS secured FAT12", buffer_size);
+ break;
+ case 0xd4:
+ strlcpy(buffer, "Old Multiuser DOS secured FAT16 <32M", buffer_size);
+ break;
+ case 0xd5:
+ strlcpy(buffer, "Old Multiuser DOS secured extended partition",
+ buffer_size);
+ break;
+ case 0xd6:
+ strlcpy(buffer, "Old Multiuser DOS secured FAT16 >=32M", buffer_size);
+ break;
+ case 0xd8:
+ strlcpy(buffer, "CP/M-86", buffer_size);
+ break;
+ case 0xda:
+ strlcpy(buffer, "Non-FS Data", buffer_size);
+ break;
+ case 0xdb:
+ strlcpy(buffer,
+ "Digital Research CP/M, Concurrent CP/M, Concurrent DOS",
+ buffer_size);
+ break;
+ //case 0xdb: strlcpy(buffer, "CTOS (Convergent Technologies OS -Unisys)", buffer_size); break;
+ //case 0xdb: strlcpy(buffer, "KDG Telemetry SCPU boot", buffer_size); break;
+ case 0xdd:
+ strlcpy(buffer, "Hidden CTOS Memdump?", buffer_size);
+ break;
+ case 0xde:
+ strlcpy(buffer, "Dell PowerEdge Server utilities (FAT fs)",
+ buffer_size);
+ break;
+ case 0xdf:
+ strlcpy(buffer, "DG/UX virtual disk manager partition", buffer_size);
+ break;
+ //case 0xdf: strlcpy(buffer, "BootIt EMBRM", buffer_size); break;
+ case 0xe0:
+ strlcpy(buffer,
+ "Reserved by STMicroelectronics for a filesystem called ST AVFS.",
+ buffer_size);
+ break;
+ case 0xe1:
+ strlcpy(buffer, "DOS access or SpeedStor 12-bit FAT extended partition",
+ buffer_size);
+ break;
+ case 0xe3:
+ strlcpy(buffer, "DOS R/O or SpeedStor", buffer_size);
+ break;
+ case 0xe4:
+ strlcpy(buffer, "SpeedStor 16-bit FAT extended partition < 1024 cyl.",
+ buffer_size);
+ break;
+ case 0xe5:
+ strlcpy(buffer,
+ "Tandy DOS with logical sectored FAT (According to Powerquest.)",
+ buffer_size);
+ break;
+ //case 0xe5: strlcpy(buffer, "Reserved", buffer_size); break;
+ case 0xe6:
+ strlcpy(buffer, "Reserved", buffer_size);
+ break;
+ case 0xeb:
+ strlcpy(buffer, "BFS (aka BeFS)", buffer_size);
+ break;
+ case 0xed:
+ strlcpy(buffer, "Reserved for Matthias Paul's Sprytix", buffer_size);
+ break;
+ case 0xee:
+ strlcpy(buffer,
+ "Indication that this legacy MBR is followed by an EFI header",
+ buffer_size);
+ break;
+ case 0xef:
+ strlcpy(buffer, "Partition that contains an EFI file system",
+ buffer_size);
+ break;
+ case 0xf0:
+ strlcpy(buffer, "Linux/PA-RISC boot loader", buffer_size);
+ break;
+ case 0xf1:
+ strlcpy(buffer, "SpeedStor", buffer_size);
+ break;
+ case 0xf2:
+ strlcpy(buffer,
+ "DOS 3.3+ secondary partition (Powerquest writes: Unisys DOS with logical sectored FAT.)",
+ buffer_size);
+ break;
+ case 0xf3:
+ strlcpy(buffer,
+ "Reserved (Powerquest writes: Storage Dimensions SpeedStor.)",
+ buffer_size);
+ break;
+ case 0xf4:
+ strlcpy(buffer, "SpeedStor large partition", buffer_size);
+ break;
+ //case 0xf4: strlcpy(buffer, "Prologue single-volume partition", buffer_size); break;
+ case 0xf5:
+ strlcpy(buffer, "Prologue multi-volume partition", buffer_size);
+ break;
+ case 0xf6:
+ strlcpy(buffer,
+ "Reserved (Powerquest writes: Storage Dimensions SpeedStor. )",
+ buffer_size);
+ break;
+ case 0xfa:
+ strlcpy(buffer, "Bochs", buffer_size);
+ break;
+ case 0xfb:
+ strlcpy(buffer, "VMware File System partition", buffer_size);
+ break;
+ case 0xfc:
+ strlcpy(buffer, "VMware Swap partition", buffer_size);
+ break;
+ case 0xfd:
+ strlcpy(buffer,
+ "Linux raid partition with autodetect using persistent superblock (Powerquest writes: Reserved for FreeDOS. )",
+ buffer_size);
+ break;
+ case 0xfe:
+ strlcpy(buffer, "SpeedStor > 1024 cyl.", buffer_size);
+ break;
+ //case 0xfe: strlcpy(buffer, "LANstep", buffer_size); break;
+ //case 0xfe: strlcpy(buffer, "IBM PS/2 IML (Initial Microcode Load) partition, located at the end of the disk.", buffer_size); break;
+ //case 0xfe: strlcpy(buffer, "Windows NT Disk Administrator hidden partition", buffer_size); break;
+ //case 0xfe: strlcpy(buffer, "Linux Logical Volume Manager partition (old)", buffer_size); break;
+ case 0xff:
+ strlcpy(buffer, "Xenix Bad Block Table ", buffer_size);
+ break;
+ default:
+ strlcpy(buffer, "Unknown", buffer_size);
+ break;
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/mbrs.c b/contrib/syslinux-4.02/com32/gpllib/disk/mbrs.c
new file mode 100644
index 0000000..41bb20c
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/mbrs.c
@@ -0,0 +1,127 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/**
+ * get_mbr_string - return a string describing the boot code
+ * @label: first four bytes of the MBR
+ * @buffer: pre-allocated buffer
+ * @buffer_size: @buffer size
+ **/
+void get_mbr_string(const uint32_t label, char *buffer, const int buffer_size)
+{
+ /* 2 bytes are usually enough to identify the MBR */
+ uint16_t s_label = label >> 16;
+
+ switch (s_label) {
+ case 0x0000:
+ case 0xfa33:
+ case 0xfab8:
+ case 0xfabe:
+ strlcpy(buffer, "No bootloader", buffer_size - 1);
+ break;
+ case 0x0ebe:
+ strlcpy(buffer, "ThinkPad", buffer_size - 1);
+ break;
+ case 0x31c0:
+ strlcpy(buffer, "Acer 3", buffer_size - 1);
+ break;
+ case 0x33c0:
+ strlcpy(buffer, "Windows", buffer_size - 1);
+ break;
+ case 0x33ff:
+ strlcpy(buffer, "HP/Gateway", buffer_size - 1);
+ break;
+ case 0xb800:
+ strlcpy(buffer, "PloP", buffer_size - 1);
+ break;
+ case 0xea05:
+ strlcpy(buffer, "XOSL", buffer_size - 1);
+ break;
+ case 0xea1e:
+ strlcpy(buffer, "Truecrypt Boot Loader", buffer_size - 1);
+ break;
+ case 0xeb04:
+ strlcpy(buffer, "Solaris", buffer_size - 1);
+ break;
+ case 0xeb48:
+ strlcpy(buffer, "Grub", buffer_size - 1);
+ break;
+ case 0xeb4c:
+ strlcpy(buffer, "Grub2 (v1.96)", buffer_size - 1);
+ break;
+ case 0xeb63:
+ strlcpy(buffer, "Grub2 (v1.97)", buffer_size - 1);
+ break;
+ case 0xeb5e:
+ /* We need more than 2 bytes */
+ if (((label >> 8) & 0xff) == 0x00)
+ strlcpy(buffer, "fbinst", buffer_size - 1);
+ else if (((label >> 8) & 0xff) == 0x80)
+ strlcpy(buffer, "Grub4Dos", buffer_size - 1);
+ else if (((label >> 8) & 0xff) == 0x90)
+ strlcpy(buffer, "WEE", buffer_size - 1);
+ else
+ strlcpy(buffer, "Unknown mbr", buffer_size - 1);
+ break;
+ case 0xfa31:
+ /* We need more than 2 bytes */
+ if (((label >> 8) & 0xff) == 0xc9)
+ strlcpy(buffer, "Master Boot LoaDeR", buffer_size - 1);
+ else if (((label >> 8) & 0xff) == 0xc0)
+ strlcpy(buffer, "Syslinux", buffer_size - 1);
+ else
+ strlcpy(buffer, "Unknown mbr", buffer_size - 1);
+ break;
+ case 0xfaeb:
+ strlcpy(buffer, "Lilo", buffer_size - 1);
+ break;
+ case 0xfc31:
+ strlcpy(buffer, "Testdisk", buffer_size - 1);
+ break;
+ case 0xfc33:
+ strlcpy(buffer, "GAG", buffer_size - 1);
+ break;
+ case 0xfceb:
+ strlcpy(buffer, "BootIT NG", buffer_size - 1);
+ break;
+ default:
+ strlcpy(buffer, "Unknown mbr", buffer_size - 1);
+ break;
+ }
+
+ buffer[buffer_size - 1] = '\0';
+}
+
+/**
+ * get_mbr_id - return the first four bytes of the MBR
+ * @d: driveinfo struct describing the drive
+ **/
+uint32_t get_mbr_id(const struct driveinfo *d)
+{
+ char mbr[SECTOR * sizeof(char)];
+
+ if (read_mbr(d->disk, &mbr) == -1)
+ return -1;
+ else {
+ uint32_t mbr_id;
+ /* Reverse the opcodes */
+ mbr_id = (*(uint8_t *) (mbr + 3));
+ mbr_id += (*(uint8_t *) (mbr + 2) << 8);
+ mbr_id += (*(uint8_t *) (mbr + 1) << 16);
+ mbr_id += (*(uint8_t *) mbr) << 24;
+ return mbr_id;
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/msdos.c b/contrib/syslinux-4.02/com32/gpllib/disk/msdos.c
new file mode 100644
index 0000000..affec43
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/msdos.c
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * Some parts borrowed from chain.c32:
+ *
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+
+#include <disk/common.h>
+#include <disk/geom.h>
+#include <disk/msdos.h>
+#include <disk/partition.h>
+#include <disk/read.h>
+
+static inline int is_extended_partition(struct part_entry *ptab)
+{
+ return (ptab->ostype == 0x05 ||
+ ptab->ostype == 0x0f || ptab->ostype == 0x85);
+}
+
+static inline int msdos_magic_present(const char *ptab)
+{
+ return (*(uint16_t *) (ptab + 0x1fe) == 0xaa55);
+}
+
+/**
+ * process_extended_partition - execute a callback for each partition contained listed in an ebr
+ * @drive_info: driveinfo struct describing the drive
+ * @partition_offset: Absolute start (lba) of the extended partition
+ * @ebr_offset: Relative start (lba) of the current ebr processed within
+ * the extended partition
+ * @callback: Callback to execute
+ * @error: Buffer for I/O errors
+ * @nb_part_seen: Number of partitions found on the disk so far
+ **/
+static int process_extended_partition(struct driveinfo *drive_info,
+ const int partition_offset,
+ const int ebr_offset,
+ p_callback callback, int nb_part_seen)
+{
+ int status = 0;
+ /* The ebr is located at the first sector of the extended partition */
+ char *ebr = malloc(SECTOR * sizeof(char));
+
+ if (read_sectors(drive_info, ebr, partition_offset + ebr_offset, 1) == -1)
+ goto abort;
+
+ /* Check msdos magic signature */
+ if (!msdos_magic_present(ebr))
+ goto abort;
+
+ struct part_entry *ptab =
+ (struct part_entry *)(ebr + PARTITION_TABLES_OFFSET);
+
+ for (int i = 0; i < 4; i++) {
+ if (status == -1)
+ goto abort;
+
+ if (!is_extended_partition(&ptab[i])) {
+ /*
+ * This EBR partition table entry points to the
+ * logical partition associated to that EBR
+ */
+ int logical_partition_start = ebr_offset + ptab[i].start_lba;
+
+ /* Last EBR in the extended partition? */
+ if (!logical_partition_start)
+ continue;
+
+ /*
+ * Check for garbage:
+ * 3rd and 4th entries in an EBR should be zero
+ * Some (malformed) partitioning software still add some
+ * data partitions there.
+ */
+ if (ptab[i].start_lba <= 0 || ptab[i].length <= 0)
+ continue;
+
+ nb_part_seen++;
+ callback(drive_info,
+ &ptab[i],
+ partition_offset + logical_partition_start, nb_part_seen);
+ } else
+ status = process_extended_partition(drive_info,
+ partition_offset,
+ ptab[i].start_lba,
+ callback, nb_part_seen);
+ }
+
+ free(ebr);
+ return 0;
+
+abort:
+ free(ebr);
+ return -1;
+}
+
+/**
+ * process_mbr - execute a callback for each partition contained in an {m,e}br
+ * @drive_info: driveinfo struct describing the drive
+ * @ptab: Pointer to the partition table
+ * @callback: Callback to execute
+ **/
+static int process_mbr(struct driveinfo *drive_info, struct part_entry *ptab,
+ p_callback callback)
+{
+ int status = 0;
+
+ for (int i = 0; i < 4; i++) {
+ if (status == -1)
+ return -1;
+
+ if (ptab[i].start_sect > 0) {
+ if (is_extended_partition(&ptab[i])) {
+ callback(drive_info, &ptab[i], ptab[i].start_lba, i + 1);
+ status =
+ process_extended_partition(drive_info, ptab[i].start_lba, 0,
+ callback, 4);
+ } else
+ callback(drive_info, &ptab[i], ptab[i].start_lba, i + 1);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * parse_partition_table - execute a callback for each partition entry
+ * @d: driveinfo struct describing the drive
+ * @callback: Callback to execute
+ *
+ * The signature of the callback should be the following:
+ *
+ * void callback(struct driveinfo *drive_info,
+ * struct part_entry *ptab,
+ * int offset_root,
+ * int nb_part_seen)
+ **/
+int parse_partition_table(struct driveinfo *d, p_callback callback)
+{
+ char *mbr = malloc(SECTOR * sizeof(char));
+
+ if (read_mbr(d->disk, mbr) == -1)
+ return -1;
+ else {
+ /* Check msdos magic signature */
+ if (!msdos_magic_present(mbr))
+ return -1;
+
+ struct part_entry *ptab =
+ (struct part_entry *)(mbr + PARTITION_TABLES_OFFSET);
+ return process_mbr(d, ptab, callback);
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/read.c b/contrib/syslinux-4.02/com32/gpllib/disk/read.c
new file mode 100644
index 0000000..7a6cc43
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/read.c
@@ -0,0 +1,135 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * Some parts borrowed from chain.c32:
+ *
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <disk/errno_disk.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <disk/util.h>
+#include <disk/common.h>
+
+/*
+ * TODO: implement file descriptors to cache metadata (geometry, ...)
+ */
+
+/**
+ * read_mbr - return a pointer to a malloced buffer containing the mbr
+ * @drive: Drive number
+ * @buf: Pre-allocated buffer for output
+ *
+ * Return the number of sectors read on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int read_mbr(int drive, void *buf)
+{
+ struct driveinfo drive_info;
+ drive_info.disk = drive;
+
+ /* MBR: lba = 0, 1 sector */
+ return read_sectors(&drive_info, buf, 0, 1);
+}
+
+/**
+ * dev_read - read from a drive
+ * @drive: Drive number
+ * @buf: Pre-allocated buffer for output
+ * @lba: Position to start reading from
+ * @sectors: Number of sectors to read
+ *
+ * High-level routine to read from a hard drive.
+ * Return the number of sectors read on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int dev_read(int drive, void *buf, unsigned int lba, int sectors)
+{
+ struct driveinfo drive_info;
+ drive_info.disk = drive;
+
+ return read_sectors(&drive_info, buf, lba, sectors);
+}
+
+/**
+ * read_sectors - read several sectors from disk
+ * @drive_info: driveinfo struct describing the disk
+ * @data: Pre-allocated buffer for output
+ * @lba: Position to read
+ * @sectors: Number of sectors to read
+ *
+ * Return the number of sectors read on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int read_sectors(struct driveinfo *drive_info, void *data,
+ const unsigned int lba, const int sectors)
+{
+ com32sys_t inreg, outreg;
+ struct ebios_dapa *dapa = __com32.cs_bounce;
+ void *buf = (char *)__com32.cs_bounce + sectors * SECTOR;
+ char *bufp = data;
+
+ if (get_drive_parameters(drive_info) == -1)
+ return -1;
+
+ memset(&inreg, 0, sizeof inreg);
+
+ if (drive_info->ebios) {
+ dapa->len = sizeof(*dapa);
+ dapa->count = sectors;
+ dapa->off = OFFS(buf);
+ dapa->seg = SEG(buf);
+ dapa->lba = lba;
+
+ inreg.esi.w[0] = OFFS(dapa);
+ inreg.ds = SEG(dapa);
+ inreg.edx.b[0] = drive_info->disk;
+ inreg.eax.b[1] = 0x42; /* Extended read */
+ } else {
+ unsigned int c, h, s;
+
+ if (!drive_info->cbios) { // XXX errno
+ /* We failed to get the geometry */
+ if (lba)
+ return -1; /* Can only read MBR */
+
+ s = 1;
+ h = 0;
+ c = 0;
+ } else
+ lba_to_chs(drive_info, lba, &s, &h, &c);
+
+ // XXX errno
+ if (s > 63 || h > 256 || c > 1023)
+ return -1;
+
+ inreg.eax.w[0] = 0x0201; /* Read one sector */
+ inreg.ecx.b[1] = c & 0xff;
+ inreg.ecx.b[0] = s + (c >> 6);
+ inreg.edx.b[1] = h;
+ inreg.edx.b[0] = drive_info->disk;
+ inreg.ebx.w[0] = OFFS(buf);
+ inreg.es = SEG(buf);
+ }
+
+ /* Perform the read */
+ if (int13_retry(&inreg, &outreg)) {
+ errno_disk = outreg.eax.b[1];
+ return -1; /* Give up */
+ }
+
+ memcpy(bufp, buf, sectors * SECTOR);
+
+ return sectors;
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/swsusp.c b/contrib/syslinux-4.02/com32/gpllib/disk/swsusp.c
new file mode 100644
index 0000000..ef782fd
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/swsusp.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#include <string.h>
+
+#include <disk/swsusp.h>
+#include <disk/read.h>
+#include <disk/geom.h>
+
+/**
+ * swsusp_check - check if a (swap) partition contains the swsusp signature
+ * @drive_info: driveinfo struct describing the disk containing the partition
+ * @ptab; Partition table of the partition
+ **/
+int swsusp_check(struct driveinfo *drive_info, struct part_entry *ptab)
+{
+ struct swsusp_header header_p;
+ int offset;
+ int found;
+
+ /* Read first page of the swap device */
+ offset = ptab->start_lba;
+ if (read_sectors(drive_info, &header_p, offset, PAGE_SIZE / SECTOR) == -1) {
+ return -1;
+ } else {
+ found = !memcmp(SWSUSP_SIG, header_p.sig, 10);
+ return found;
+ }
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/util.c b/contrib/syslinux-4.02/com32/gpllib/disk/util.c
new file mode 100644
index 0000000..59c0328
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/util.c
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * Some parts borrowed from chain.c32:
+ *
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+#include <disk/geom.h>
+
+#define MAX_NB_RETRIES 6
+
+/**
+ * int13_retry - int13h with error handling
+ * @inreg: int13h function parameters
+ * @outreg: output registers
+ *
+ * Call int 13h, but with retry on failure. Especially floppies need this.
+ **/
+int int13_retry(const com32sys_t * inreg, com32sys_t * outreg)
+{
+ int retry = MAX_NB_RETRIES; /* Number of retries */
+ com32sys_t tmpregs;
+
+ if (!outreg)
+ outreg = &tmpregs;
+
+ while (retry--) {
+ __intcall(0x13, inreg, outreg);
+ if (!(outreg->eflags.l & EFLAGS_CF))
+ return 0; /* CF=0 => OK */
+ }
+
+ /* If we get here: error */
+ return -1;
+}
diff --git a/contrib/syslinux-4.02/com32/gpllib/disk/write.c b/contrib/syslinux-4.02/com32/gpllib/disk/write.c
new file mode 100644
index 0000000..89e530d
--- /dev/null
+++ b/contrib/syslinux-4.02/com32/gpllib/disk/write.c
@@ -0,0 +1,126 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer
+ *
+ * Some parts borrowed from chain.c32:
+ *
+ * Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ * Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ * This file is part of Syslinux, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <disk/common.h>
+#include <disk/errno_disk.h>
+#include <disk/read.h>
+#include <disk/util.h>
+#include <disk/write.h>
+
+/**
+ * write_sectors - write several sectors from disk
+ * @drive_info: driveinfo struct describing the disk
+ * @lba: Position to write
+ * @data: Buffer to write
+ * @size: Size of the buffer (number of sectors)
+ *
+ * Return the number of sectors write on success or -1 on failure.
+ * errno_disk contains the error number.
+ **/
+int write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
+ const void *data, const int size)
+{
+ com32sys_t inreg, outreg;
+ struct ebios_dapa *dapa = __com32.cs_bounce;
+ void *buf = (char *)__com32.cs_bounce + size;
+
+ memcpy(buf, data, size);
+ memset(&inreg, 0, sizeof inreg);
+
+ if (drive_info->ebios) {
+ dapa->len = sizeof(*dapa);
+ dapa->count = size;
+ dapa->off = OFFS(buf);
+ dapa->seg = SEG(buf);
+ dapa->lba = lba;
+
+ inreg.esi.w[0] = OFFS(dapa);
+ inreg.ds = SEG(dapa);
+ inreg.edx.b[0] = drive_info->disk;
+ inreg.eax.w[0] = 0x4300; /* Extended write */
+ } else {
+ unsigned int c, h, s;
+
+ if (!drive_info->cbios) { // XXX errno
+ /* We failed to get the geometry */
+ if (lba)
+ return -1; /* Can only write MBR */
+
+ s = 1;
+ h = 0;
+ c = 0;
+ } else
+ lba_to_chs(drive_info, lba, &s, &h, &c);
+
+ // XXX errno
+ if (s > 63 || h > 256 || c > 1023)
+ return -1;
+
+ inreg.eax.w[0] = 0x0301; /* Write one sector */
+ inreg.ecx.b[1] = c & 0xff;
+ inreg.ecx.b[0] = s + (c >> 6);
+ inreg.edx.b[1] = h;
+ inreg.edx.b[0] = drive_info->disk;
+ inreg.ebx.w[0] = OFFS(buf);
+ inreg.es = SEG(buf);
+ }
+
+ /* Perform the write */
+ if (int13_retry(&inreg, &outreg)) {
+ errno_disk = outreg.eax.b[1];
+ return -1; /* Give up */
+ } else
+ return size;
+}
+
+/**
+ * write_verify_sectors - write several sectors from disk
+ * @drive_info: driveinfo struct describing the disk
+ * @lba: Position to write
+ * @data: Buffer to write
+ **/
+int write_verify_sector(struct driveinfo *drive_info,
+ const unsigned int lba, const void *data)
+{
+ return write_verify_sectors(drive_info, lba, data, SECTOR);
+}
+
+/**
+ * write_verify_sectors - write several sectors from disk
+ * @drive_info: driveinfo struct describing the disk
+ * @lba: Position to write
+ * @data: Buffer to write
+ * @size: Size of the buffer (number of sectors)
+ **/
+int write_verify_sectors(struct driveinfo *drive_info,
+ const unsigned int lba,
+ const void *data, const int size)
+{
+ char *rb = malloc(SECTOR * size * sizeof(char));
+ int status;
+
+ if (write_sectors(drive_info, lba, data, size) == -1)
+ return -1; /* Write failure */
+
+ if (read_sectors(drive_info, rb, lba, size) == -1)
+ return -1; /* Readback failure */
+
+ status = memcmp(data, rb, SECTOR * size);
+ free(rb);
+ return status ? -1 : 0;
+}