summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Alexandre Meyer <pierre@mouraf.org>2009-09-07 16:12:59 -0700
committerPierre-Alexandre Meyer <pierre@mouraf.org>2009-09-07 16:22:36 -0700
commite9069caefc1460ec7f4d058796005474c125fc61 (patch)
tree25cd847439fb004798251a63fa8886073134009f
parentc93e27af183de1cdf591706448d42887d0fbc0eb (diff)
parent03b2384b6e9f54d9697e87d2a19c321e6fd96ed5 (diff)
downloadsyslinux-e9069caefc1460ec7f4d058796005474c125fc61.tar.gz
Merge branch 'bootloader-detection' into hdt-next
Conflicts: com32/hdt/hdt-cli-disk.c com32/hdt/hdt-common.h com32/hdt/hdt-menu-disk.c Signed-off-by: Pierre-Alexandre Meyer <pierre@mouraf.org>
-rw-r--r--com32/gplinclude/disk/bootloaders.h18
-rw-r--r--com32/gplinclude/disk/mbrs.h18
-rw-r--r--com32/gpllib/disk/bootloaders.c46
-rw-r--r--com32/gpllib/disk/mbrs.c82
-rw-r--r--com32/hdt/hdt-cli-disk.c36
-rw-r--r--com32/hdt/hdt-common.c4
-rw-r--r--com32/hdt/hdt-common.h9
-rw-r--r--com32/hdt/hdt-menu-disk.c30
-rw-r--r--com32/hdt/hdt-menu.c2
-rw-r--r--com32/hdt/hdt-menu.h2
10 files changed, 232 insertions, 15 deletions
diff --git a/com32/gplinclude/disk/bootloaders.h b/com32/gplinclude/disk/bootloaders.h
new file mode 100644
index 00000000..6aec9b3d
--- /dev/null
+++ b/com32/gplinclude/disk/bootloaders.h
@@ -0,0 +1,18 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef __BOOTLOADERS_H_
+#define __BOOTLOADERS_H_
+
+#include <stdint.h>
+#include <disk/geom.h>
+#include <disk/partition.h>
+
+int get_bootloader_string(const struct driveinfo *, const struct part_entry *, char*, const int);
+#endif /* __BOOTLOADERS_H_ */
diff --git a/com32/gplinclude/disk/mbrs.h b/com32/gplinclude/disk/mbrs.h
new file mode 100644
index 00000000..ad104ff7
--- /dev/null
+++ b/com32/gplinclude/disk/mbrs.h
@@ -0,0 +1,18 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef __MBRS_H_
+#define __MBRS_H_
+
+#include <stdint.h>
+#include <disk/geom.h>
+
+void get_mbr_string(const uint32_t, void *, const int);
+uint32_t get_mbr_id(const struct driveinfo *);
+#endif /* __MBRS_H_ */
diff --git a/com32/gpllib/disk/bootloaders.c b/com32/gpllib/disk/bootloaders.c
new file mode 100644
index 00000000..4b3962ae
--- /dev/null
+++ b/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(const 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))
+ strncpy(buffer, "SYSLINUX", buffer_size - 1);
+ else if (!strncmp(boot_sector + 3, "EXTLINUX", 8))
+ strncpy(buffer, "EXTLINUX", buffer_size - 1);
+ else if (!strncmp(boot_sector + 3, "MSWIN4.1", 8))
+ strncpy(buffer, "MSWIN4.1", buffer_size - 1);
+ else
+ return -1;
+ /* Add more... */
+
+ buffer[buffer_size - 1] = '\0';
+ return 0;
+ }
+}
diff --git a/com32/gpllib/disk/mbrs.c b/com32/gpllib/disk/mbrs.c
new file mode 100644
index 00000000..b5e271b7
--- /dev/null
+++ b/com32/gpllib/disk/mbrs.c
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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:
+ strncpy(buffer, "No bootloader", buffer_size - 1); break;
+ case 0x0ebe: strncpy(buffer, "ThinkPad", buffer_size - 1); break;
+ case 0x31c0: strncpy(buffer, "Acer 3", buffer_size - 1); break;
+ case 0x33c0: strncpy(buffer, "Windows", buffer_size - 1); break;
+ case 0x33ff: strncpy(buffer, "HP/Gateway", buffer_size - 1); break;
+ case 0xb800: strncpy(buffer, "Plop", buffer_size - 1); break;
+ case 0xea1e: strncpy(buffer, "Truecrypt Boot Loader", buffer_size - 1); break;
+ case 0xeb04: strncpy(buffer, "Solaris", buffer_size - 1); break;
+ case 0xeb48: strncpy(buffer, "Grub", buffer_size - 1); break;
+ case 0xeb4c: strncpy(buffer, "Grub2", buffer_size - 1); break;
+ case 0xeb5e: strncpy(buffer, "Grub4Dos", buffer_size - 1); break;
+ case 0xfa31:
+ /* We need more than 2 bytes */
+ if ((label >> 8) & 0xff == 0xc9)
+ strncpy(buffer, "Master Boot LoaDeR", buffer_size - 1);
+ else if ((label >> 8) & 0xff == 0xc0)
+ strncpy(buffer, "Syslinux", buffer_size - 1);
+ else
+ strncpy(buffer, "Unknown mbr", buffer_size - 1); break;
+ break;
+ case 0xfaeb: strncpy(buffer, "Lilo", buffer_size - 1); break;
+ case 0xfc31: strncpy(buffer, "Testdisk", buffer_size - 1); break;
+ case 0xfc33: strncpy(buffer, "Gag", buffer_size - 1); break;
+ case 0xfceb: strncpy(buffer, "BootIT NG", buffer_size - 1); break;
+ default: strncpy(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/com32/hdt/hdt-cli-disk.c b/com32/hdt/hdt-cli-disk.c
index bcd4400c..48f19012 100644
--- a/com32/hdt/hdt-cli-disk.c
+++ b/com32/hdt/hdt-cli-disk.c
@@ -56,6 +56,7 @@ static void show_partition_information(struct driveinfo *drive_info,
int nb_partitions_seen)
{
char size[9];
+ char bootloader_name[9];
char *parttype;
unsigned int start, end;
@@ -70,10 +71,10 @@ static void show_partition_information(struct driveinfo *drive_info,
memset(size, 0, sizeof size);
if (i == 1)
- more_printf(" # B Start End Size Id Type\n");
+ more_printf(" # B Start End Size Id Type\n");
get_label(ptab->ostype, &parttype);
- more_printf(" %2d %s %11d %11d %s %02X %s",
+ more_printf("%2d %s %11d %11d %s %02X %s",
i, (ptab->active_flag == 0x80) ? "x" : " ",
start,
end,
@@ -84,6 +85,9 @@ static void show_partition_information(struct driveinfo *drive_info,
if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab))
more_printf("%s", " (Swsusp sig. detected)");
+ if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0)
+ more_printf("%-46s %s %s", " ", "Bootloader:", bootloader_name);
+
more_printf("\n");
free(parttype);
@@ -107,11 +111,14 @@ void main_show_disk(int argc, char **argv,
int i = drive - 0x80;
struct driveinfo *d = &hardware->disk_info[i];
char disk_size[9];
+ char mbr_name[50];
detect_disks(hardware);
if (!hardware->disk_info[i].cbios)
return; /* Invalid geometry */
+ get_mbr_string(hardware->mbr_ids[i], &mbr_name, 50);
+
if ((int) d->edd_params.sectors > 0)
sectors_to_size((int) d->edd_params.sectors, disk_size);
else
@@ -119,14 +126,17 @@ void main_show_disk(int argc, char **argv,
more_printf("DISK 0x%X:\n"
" C/H/S: %d cylinders, %d heads, %d sectors/track\n"
- " EDD: Version: %X\n"
+ " EDD: Version: %X\n"
" Size: %s, %d bytes/sector, %d sectors/track\n"
- " Host bus: %s, Interface type: %s\n\n",
+ " Host bus: %s, Interface type: %s\n"
+ " MBR: %s (id 0x%X)\n\n",
d->disk,
d->legacy_max_cylinder + 1, d->legacy_max_head + 1, d->legacy_sectors_per_track,
d->edd_version,
disk_size, (int) d->edd_params.bytes_per_sector, (int) d->edd_params.sectors_per_track,
- remove_spaces((char *) d->edd_params.host_bus_type), remove_spaces((char*) d->edd_params.interface_type));
+ remove_spaces((char *) d->edd_params.host_bus_type), remove_spaces((char*) d->edd_params.interface_type),
+ mbr_name, hardware->mbr_ids[i]);
+ display_line_nb += 6;
if (parse_partition_table(d, &show_partition_information)) {
if (errno_disk) {
@@ -147,11 +157,19 @@ void main_show_disks(int argc __unused, char **argv __unused,
reset_more_printf();
detect_disks(hardware);
+ int first_one = 0;
for (int drive = 0x80; drive < 0xff; drive++) {
- char buf[5] = "";
- sprintf(buf, "0x%x", drive);
- char *argv[1] = { buf };
- main_show_disk(1, argv, hardware);
+ if (hardware->disk_info[drive - 0x80].cbios) {
+ if (!first_one) {
+ first_one = 1;
+ } else {
+ pause_printf();
+ }
+ char buf[5] = "";
+ sprintf(buf, "0x%x", drive);
+ char *argv[1] = { buf };
+ main_show_disk(1, argv, hardware);
+ }
}
}
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index 80305a3e..11887c39 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -35,6 +35,7 @@
#include "hdt-common.h"
#include "lib-ansi.h"
#include <disk/util.h>
+#include <disk/mbrs.h>
/* ISOlinux requires a 8.3 format */
void convert_isolinux_filename(char *filename, struct s_hardware *hardware) {
@@ -269,6 +270,9 @@ void detect_disks(struct s_hardware *hardware)
if (err == -1 || !hardware->disk_info[i].cbios)
continue;
+ /* Detect MBR */
+ hardware->mbr_ids[i] = get_mbr_id(&hardware->disk_info[i]);
+
hardware->disks_count++;
}
}
diff --git a/com32/hdt/hdt-common.h b/com32/hdt/hdt-common.h
index e326cb12..ef9382b7 100644
--- a/com32/hdt/hdt-common.h
+++ b/com32/hdt/hdt-common.h
@@ -32,9 +32,11 @@
#include <syslinux/pxe.h>
#include "sys/pci.h"
+#include <disk/bootloaders.h>
#include <disk/errno_disk.h>
#include <disk/error.h>
#include <disk/geom.h>
+#include <disk/mbrs.h>
#include <disk/msdos.h>
#include <disk/partition.h>
#include <disk/swsusp.h>
@@ -56,6 +58,12 @@
extern int display_line_nb;
+#define pause_printf() do {\
+ printf("--More--");\
+ get_key(stdin, 0);\
+ printf("\n");\
+} while (0);
+
#define more_printf(...) do {\
if (display_line_nb == 20) {\
printf("\nPress any key to continue");\
@@ -120,6 +128,7 @@ struct s_hardware {
s_vpd vpd; /* VPD information */
struct pci_domain *pci_domain; /* PCI Devices */
struct driveinfo disk_info[256]; /* Disk Information */
+ uint32_t mbr_ids[256]; /* MBR ids */
int disks_count; /* Number of detected disks */
struct s_pxe pxe;
struct s_vesa vesa;
diff --git a/com32/hdt/hdt-menu-disk.c b/com32/hdt/hdt-menu-disk.c
index 668b7cb4..2f3571b9 100644
--- a/com32/hdt/hdt-menu-disk.c
+++ b/com32/hdt/hdt-menu-disk.c
@@ -74,6 +74,7 @@ static void compute_partition_information(struct driveinfo *drive_info,
int nb_partitions_seen)
{
char size[9];
+ char bootloader_name[9];
char *parttype;
unsigned int start, end;
char buffer[SUBMENULEN+1];
@@ -113,6 +114,14 @@ static void compute_partition_information(struct driveinfo *drive_info,
parttype);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0) {
+ snprintf(buffer, sizeof buffer, "Bootloader : %s",
+ bootloader_name);
+ snprintf(statbuffer, sizeof statbuffer, "Bootloader: %s",
+ bootloader_name);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ }
+
snprintf(buffer, sizeof buffer, "Bootable : %s",
(ptab->active_flag == 0x80) ? "Yes" : "No");
snprintf(statbuffer, sizeof statbuffer, "Bootable: %s",
@@ -150,10 +159,12 @@ static void compute_partition_information(struct driveinfo *drive_info,
/* Compute the disk submenu */
static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
- struct driveinfo *d, int disk_number)
+ const struct s_hardware *hardware, int disk_number)
{
char buffer[MENULEN + 1];
char statbuffer[STATLEN + 1];
+ char mbr_name[50];
+ struct driveinfo *d = (struct driveinfo*) hardware->disk_info;
snprintf(buffer, sizeof buffer, " Disk <0x%X> (EDD %X)", d[disk_number].disk,
d[disk_number].edd_version);
@@ -200,6 +211,17 @@ static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
+ get_mbr_string(hardware->mbr_ids[disk_number], &mbr_name, 50);
+
+ snprintf(buffer, sizeof buffer, "MBR : %s (0x%X)",
+ remove_spaces(mbr_name),
+ hardware->mbr_ids[disk_number]);
+ snprintf(statbuffer, sizeof statbuffer, "MBR: %s (id 0x%X)",
+ remove_spaces(mbr_name),
+ hardware->mbr_ids[disk_number]);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ menu[nb_sub_disk_menu].items_count++;
+
dn=disk_number;
parse_partition_table(&d[disk_number], &show_partition_information);
@@ -212,7 +234,7 @@ static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
}
/* Compute the Disks menu */
-void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct s_hardware *hardware)
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware)
{
char buffer[MENULEN + 1];
int nb_sub_disk_menu = 0;
@@ -225,8 +247,8 @@ void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct
if (!hardware->disk_info[i].cbios)
continue; /* Invalid geometry */
compute_disk_module
- ((struct s_my_menu*) &(menu->disk_sub_menu), nb_sub_disk_menu, disk_info,
- i);
+ ((struct s_my_menu*) &(menu->disk_sub_menu), nb_sub_disk_menu,
+ hardware, i);
nb_sub_disk_menu++;
}
diff --git a/com32/hdt/hdt-menu.c b/com32/hdt/hdt-menu.c
index c37fd41b..53afefc9 100644
--- a/com32/hdt/hdt-menu.c
+++ b/com32/hdt/hdt-menu.c
@@ -154,7 +154,7 @@ void compute_submenus(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
compute_processor(&(hdt_menu->cpu_menu), hardware);
compute_vpd(&(hdt_menu->vpd_menu), hardware);
- compute_disks(hdt_menu, hardware->disk_info, hardware);
+ compute_disks(hdt_menu, hardware);
#ifdef WITH_PCI
compute_PCI(hdt_menu, hardware);
diff --git a/com32/hdt/hdt-menu.h b/com32/hdt/hdt-menu.h
index 1cd2c129..6ac688f7 100644
--- a/com32/hdt/hdt-menu.h
+++ b/com32/hdt/hdt-menu.h
@@ -91,7 +91,7 @@ int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
void compute_kernel(struct s_my_menu *menu, struct s_hardware *hardware);
// Disk Stuff
-void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct s_hardware *hardware);
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware);
// DMI Stuff
void compute_motherboard(struct s_my_menu *menu, s_dmi * dmi);