aboutsummaryrefslogtreecommitdiffstats
path: root/com32/hdt
diff options
context:
space:
mode:
authorPierre-Alexandre Meyer <pierre@mouraf.org>2009-04-26 14:35:56 -0700
committerPierre-Alexandre Meyer <pierre@mouraf.org>2009-04-26 14:35:56 -0700
commit9c5868d154656e3832822dd24dd9701fe55eb2a4 (patch)
tree71d9da7b5f08f3544703653f958b126a93ca0945 /com32/hdt
parentd0a0e562d9554cb38650f64be6e9dab9c29d99de (diff)
parent7bd5d73a1b559935dae9f6b29703d71856554f3e (diff)
downloadsyslinux.git-9c5868d154656e3832822dd24dd9701fe55eb2a4.tar.gz
syslinux.git-9c5868d154656e3832822dd24dd9701fe55eb2a4.tar.xz
syslinux.git-9c5868d154656e3832822dd24dd9701fe55eb2a4.zip
Merge branch 'disklib' into for-erwan
Conflicts: com32/hdt/hdt-common.c Signed-off-by: Pierre-Alexandre Meyer <pierre@mouraf.org>
Diffstat (limited to 'com32/hdt')
-rw-r--r--com32/hdt/hdt-ata.c247
-rw-r--r--com32/hdt/hdt-ata.h50
-rw-r--r--com32/hdt/hdt-cli-disk.c163
-rw-r--r--com32/hdt/hdt-cli-hdt.c4
-rw-r--r--com32/hdt/hdt-cli.c8
-rw-r--r--com32/hdt/hdt-cli.h6
-rw-r--r--com32/hdt/hdt-common.c38
-rw-r--r--com32/hdt/hdt-common.h15
-rw-r--r--com32/hdt/hdt-menu-disk.c221
-rw-r--r--com32/hdt/hdt-menu.c2
-rw-r--r--com32/hdt/hdt-menu.h4
-rw-r--r--com32/hdt/hdt-util.c71
-rw-r--r--com32/hdt/hdt-util.h33
13 files changed, 470 insertions, 392 deletions
diff --git a/com32/hdt/hdt-ata.c b/com32/hdt/hdt-ata.c
index e0d6015c..9ba17ba8 100644
--- a/com32/hdt/hdt-ata.c
+++ b/com32/hdt/hdt-ata.c
@@ -30,252 +30,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <console.h>
-#include <getkey.h>
+#include <disk/geom.h>
+#include <disk/util.h>
#include "com32io.h"
#include "hdt-common.h"
#include "hdt-ata.h"
-
-#ifdef ATA
-/**
- * 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;
-
- //WARN_ON(!(len & 1));
-
- ata_id_string(id, s, ofs, len - 1);
-
- p = s + strnlen(s, len - 1);
- while (p > s && p[-1] == ' ')
- p--;
- *p = '\0';
-}
-#endif
-
-/**
- * Call int 13h, but with retry on failure. Especially floppies need this.
- */
-int int13_retry(const com32sys_t * inreg, com32sys_t * outreg)
-{
- int retry = 6; /* 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 */
- }
-
- return -1; /* Error */
-}
-
-/* Display CPU registers for debugging purposes */
-void printregs(const com32sys_t * r)
-{
- printf("eflags = %08x ds = %04x es = %04x fs = %04x gs = %04x\n"
- "eax = %08x ebx = %08x ecx = %08x edx = %08x\n"
- "ebp = %08x esi = %08x edi = %08x esp = %08x\n",
- r->eflags.l, r->ds, r->es, r->fs, r->gs,
- r->eax.l, r->ebx.l, r->ecx.l, r->edx.l,
- r->ebp.l, r->esi.l, r->edi.l, r->_unused_esp.l);
-}
-
-/* Try to get information for a given disk */
-int get_disk_params(int disk, struct diskinfo *disk_info)
-{
- static com32sys_t getparm, parm, getebios, ebios, inreg, outreg;
- struct device_parameter dp;
-#ifdef ATA
- struct ata_identify_device aid;
-#endif
-
- memset(&(disk_info[disk]), 0, sizeof(struct diskinfo));
-
- disk_info[disk].disk = disk;
- disk_info[disk].ebios = disk_info[disk].cbios = 0;
-
- /* Sending int 13h func 41h to query EBIOS information */
- memset(&getebios, 0, sizeof(com32sys_t));
- memset(&ebios, 0, sizeof(com32sys_t));
-
- /* Get EBIOS support */
- getebios.eax.w[0] = 0x4100;
- getebios.ebx.w[0] = 0x55aa;
- getebios.edx.b[0] = disk;
- getebios.eflags.b[0] = 0x3; /* CF set */
-
- __intcall(0x13, &getebios, &ebios);
-
- /* Detecting EDD support */
- if (!(ebios.eflags.l & EFLAGS_CF) &&
- ebios.ebx.w[0] == 0xaa55 && (ebios.ecx.b[0] & 1)) {
- disk_info[disk].ebios = 1;
- switch (ebios.eax.b[1]) {
- case 32:
- strlcpy(disk_info[disk].edd_version, "1.0", 3);
- break;
- case 33:
- strlcpy(disk_info[disk].edd_version, "1.1", 3);
- break;
- case 48:
- strlcpy(disk_info[disk].edd_version, "3.0", 3);
- break;
- default:
- strlcpy(disk_info[disk].edd_version, "0", 1);
- break;
- }
- }
- /* Get disk parameters -- really only useful for
- * hard disks, but if we have a partitioned floppy
- * it's actually our best chance...
- */
- memset(&getparm, 0, sizeof(com32sys_t));
- memset(&parm, 0, sizeof(com32sys_t));
- getparm.eax.b[1] = 0x08;
- getparm.edx.b[0] = disk;
-
- __intcall(0x13, &getparm, &parm);
-
- if (parm.eflags.l & EFLAGS_CF)
- return disk_info[disk].ebios ? 0 : -1;
-
- disk_info[disk].heads = parm.edx.b[1] + 1;
- disk_info[disk].sectors_per_track = parm.ecx.b[0] & 0x3f;
- if (disk_info[disk].sectors_per_track == 0) {
- disk_info[disk].sectors_per_track = 1;
- } else {
- disk_info[disk].cbios = 1; /* Valid geometry */
- }
-
- /* 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 (disk_info[disk].cbios != 1) return 0;
-
-/* FIXME: memset to 0 make it fails
- * memset(__com32.cs_bounce, 0, sizeof(struct device_pairameter)); */
- memset(&dp, 0, sizeof(struct device_parameter));
- memset(&inreg, 0, sizeof(com32sys_t));
-
- /* Requesting Extended Read Drive Parameters via int13h func 48h */
- inreg.esi.w[0] = OFFS(__com32.cs_bounce);
- inreg.ds = SEG(__com32.cs_bounce);
- inreg.eax.w[0] = 0x4800;
- inreg.edx.b[0] = disk;
-
- __intcall(0x13, &inreg, &outreg);
-
- /* Saving bounce buffer before anything corrupt it */
- memcpy(&dp, __com32.cs_bounce, sizeof(struct device_parameter));
-
- if (outreg.eflags.l & EFLAGS_CF) {
- more_printf("Disk 0x%X doesn't supports EDD 3.0\n", disk);
- return -1;
- }
-
- /* Copying result to the disk_info structure
- * host_bus_type, interface_type, sectors & cylinders */
- snprintf(disk_info[disk].host_bus_type,
- sizeof disk_info[disk].host_bus_type, "%c%c%c%c",
- dp.host_bus_type[0], dp.host_bus_type[1], dp.host_bus_type[2],
- dp.host_bus_type[3]);
- snprintf(disk_info[disk].interface_type,
- sizeof disk_info[disk].interface_type, "%c%c%c%c%c%c%c%c",
- dp.interface_type[0], dp.interface_type[1],
- dp.interface_type[2], dp.interface_type[3],
- dp.interface_type[4], dp.interface_type[5],
- dp.interface_type[6], dp.interface_type[7]);
- disk_info[disk].sectors = dp.sectors;
- disk_info[disk].cylinders = dp.cylinders;
-
- /*FIXME: we have to find a way to grab the model & fw
- * We do put dummy data until we found a solution */
- snprintf(disk_info[disk].aid.model, sizeof disk_info[disk].aid.model,
- "0x%X", disk);
- snprintf(disk_info[disk].aid.fw_rev, sizeof disk_info[disk].aid.fw_rev,
- "%s", "N/A");
- snprintf(disk_info[disk].aid.serial_no,
- sizeof disk_info[disk].aid.serial_no, "%s", "N/A");
-
- /* Useless stuff before I figure how to send ata packets */
-#ifdef ATA
- memset(__com32.cs_bounce, 0, sizeof(struct device_parameter));
- memset(&aid, 0, sizeof(struct ata_identify_device));
- memset(&inreg, 0, sizeof inreg);
- inreg.ebx.w[0] = OFFS(__com32.cs_bounce + 1024);
- inreg.es = SEG(__com32.cs_bounce + 1024);
- inreg.eax.w[0] = 0x2500;
- inreg.edx.b[0] = disk;
-
- __intcall(0x13, &inreg, &outreg);
-
- memcpy(&aid, __com32.cs_bounce, sizeof(struct ata_identify_device));
-
- if (outreg.eflags.l & EFLAGS_CF) {
- more_printf("Disk 0x%X: Failed to Identify Device\n", disk);
- //FIXME
- return 0;
- }
-// ata_id_c_string(aid, disk_info[disk].fwrev, ATA_ID_FW_REV, sizeof(disk_info[disk].fwrev));
-// ata_id_c_string(aid, disk_info[disk].model, ATA_ID_PROD, sizeof(disk_info[disk].model));
-
- char buff[sizeof(struct ata_identify_device)];
- memcpy(buff, &aid, sizeof(struct ata_identify_device));
- for (int j = 0; j < sizeof(struct ata_identify_device); j++)
- more_printf("model=|%c|\n", buff[j]);
- more_printf("Disk 0x%X : %s %s %s\n", disk, aid.model, aid.fw_rev,
- aid.serial_no);
-#endif
-
- return 0;
-}
diff --git a/com32/hdt/hdt-ata.h b/com32/hdt/hdt-ata.h
index fee4d598..a9550837 100644
--- a/com32/hdt/hdt-ata.h
+++ b/com32/hdt/hdt-ata.h
@@ -30,6 +30,7 @@
#define DEFINE_HDT_ATA_H
#include <com32io.h>
+#include <disk/geom.h>
#include "hdt.h"
struct ata_identify_device {
@@ -50,58 +51,13 @@ struct ata_identify_device {
unsigned short words088_255[168];
} ATTR_PACKED;
-struct diskinfo {
- int disk;
- int ebios; /* EBIOS supported on this disk */
- int cbios; /* CHS geometry is valid */
- int heads;
- int sectors_per_track;
- int sectors;
- int cylinders;
- char edd_version[4];
+struct ata_driveinfo {
struct ata_identify_device aid; /* IDENTIFY xxx DEVICE data */
char host_bus_type[5];
char interface_type[9];
char interface_port;
} ATTR_PACKED;
-/*
- * Get a disk block and return a malloc'd buffer.
- * Uses the disk number and information from disk_info.
- */
-struct ebios_dapa {
- uint16_t len;
- uint16_t count;
- uint16_t off;
- uint16_t seg;
- uint64_t lba;
-};
-
-// BYTE=8
-// WORD=16
-// DWORD=32
-// QWORD=64
-struct device_parameter {
- uint16_t len;
- uint16_t info;
- uint32_t cylinders;
- uint32_t heads;
- uint32_t sectors_per_track;
- uint64_t sectors;
- uint16_t bytes_per_sector;
- uint32_t dpte_pointer;
- uint16_t device_path_information;
- uint8_t device_path_lenght;
- uint8_t device_path_reserved;
- uint16_t device_path_reserved_2;
- uint8_t host_bus_type[4];
- uint8_t interface_type[8];
- uint64_t interace_path;
- uint64_t device_path[2];
- uint8_t reserved;
- uint8_t cheksum;
-} ATTR_PACKED;
-
/* Useless stuff until I manage how to send ata packets */
#ifdef ATA
enum {
@@ -114,9 +70,7 @@ void ata_id_c_string(const uint16_t * id, unsigned char *s, unsigned int ofs,
unsigned int len);
void ata_id_string(const uint16_t * id, unsigned char *s, unsigned int ofs,
unsigned int len);
-int int13_retry(const com32sys_t * inreg, com32sys_t * outreg);
void printregs(const com32sys_t * r);
#endif
-int get_disk_params(int disk, struct diskinfo *disk_info);
#endif
diff --git a/com32/hdt/hdt-cli-disk.c b/com32/hdt/hdt-cli-disk.c
new file mode 100644
index 00000000..506efba7
--- /dev/null
+++ b/com32/hdt/hdt-cli-disk.c
@@ -0,0 +1,163 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <disk/error.h>
+#include <disk/swsusp.h>
+#include <disk/msdos.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+#include "hdt-util.h"
+
+/**
+ * show_partition_information - print information about a partition
+ * @ptab: part_entry describing the partition
+ * @i: Partition number (UI purposes only)
+ * @ptab_root: part_entry describing the root partition (extended only)
+ * @drive_info: driveinfo struct describing the drive on which the partition
+ * is
+ *
+ * Note on offsets (from hpa, see chain.c32):
+ *
+ * To make things extra confusing: data partition offsets are relative to where
+ * the data partition record is stored, whereas extended partition offsets
+ * are relative to the beginning of the extended partition all the way back
+ * at the MBR... but still not absolute!
+ **/
+static void show_partition_information(struct driveinfo *drive_info,
+ struct part_entry *ptab,
+ struct part_entry *ptab_root,
+ int offset_root, int data_partitions_seen,
+ int ebr_seen)
+{
+ char size[8];
+ char *parttype;
+ int error = 0;
+ char *error_buffer;
+ unsigned int start, end;
+
+ int i = 1 + ebr_seen * 4 + data_partitions_seen;
+
+ start = ptab->start_lba + ptab_root->start_lba + offset_root;
+ end = (ptab->start_lba + ptab_root->start_lba) + ptab->length + offset_root;
+
+ if (ptab->length > 0)
+ sectors_to_size(ptab->length, size);
+ else
+ memset(size, 0, sizeof size);
+
+ get_label(ptab->ostype, &parttype);
+ more_printf(" %2d %s %11d %11d %s %02X %s",
+ i, (ptab->active_flag == 0x80) ? "x" : " ",
+ start,
+ end,
+ size,
+ ptab->ostype, parttype);
+
+ /* Extra info */
+ if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab, &error)) {
+ more_printf("%s", " (Swsusp sig. detected)");
+ } else if (error) {
+ get_error(error, &error_buffer);
+ more_printf("%s\n", error_buffer);
+ free(error_buffer);
+ }
+
+ more_printf("\n");
+
+ free(parttype);
+}
+
+void main_show_disk(int argc __unused, char **argv __unused,
+ struct s_hardware *hardware)
+{
+ int i = -1;
+ int error;
+ char *error_buffer;
+
+ detect_disks(hardware);
+
+ for (int drive = 0x80; drive < 0xff; drive++) {
+ i++;
+ if (!hardware->disk_info[i].cbios)
+ continue; /* Invalid geometry */
+ struct driveinfo *d = &hardware->disk_info[i];
+ char disk_size[8];
+
+ if ((int) d->edd_params.sectors > 0)
+ sectors_to_size((int) d->edd_params.sectors, disk_size);
+ else
+ memset(disk_size, 0, sizeof disk_size);
+
+ more_printf("DISK 0x%X:\n", d->disk);
+ more_printf(" C/H/S: %d cylinders, %d heads, %d sectors/track\n",
+ d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
+ d->legacy_sectors_per_track);
+ more_printf(" EDD: Version: %X\n", d->edd_version);
+ more_printf(" Size: %s, %d bytes/sector, %d sectors/track\n",
+ disk_size,
+ (int) d->edd_params.bytes_per_sector,
+ (int) d->edd_params.sectors_per_track);
+ more_printf(" Host bus: %s, Interface type: %s\n\n",
+ remove_spaces(d->edd_params.host_bus_type),
+ remove_spaces(d->edd_params.interface_type));
+
+ more_printf(" # B Start End Size Id Type\n");
+ error = 0;
+ if (parse_partition_table(d, &show_partition_information, &error)) {
+ if (error) {
+ more_printf("I/O error: ");
+ get_error(error, &error_buffer);
+ more_printf("%s\n", error_buffer);
+ free(error_buffer);
+ } else
+ more_printf("An unknown error occured.\n");
+ continue;
+ }
+ }
+}
+
+struct cli_module_descr disk_show_modules = {
+ .modules = NULL,
+ .default_callback = main_show_disk,
+};
+
+struct cli_mode_descr disk_mode = {
+ .mode = DISK_MODE,
+ .name = CLI_DISK,
+ .default_modules = NULL,
+ .show_modules = &disk_show_modules,
+ .set_modules = NULL,
+};
diff --git a/com32/hdt/hdt-cli-hdt.c b/com32/hdt/hdt-cli-hdt.c
index 46f3669a..4f96b2da 100644
--- a/com32/hdt/hdt-cli-hdt.c
+++ b/com32/hdt/hdt-cli-hdt.c
@@ -285,6 +285,10 @@ struct cli_callback_descr list_hdt_show_modules[] = {
.exec = main_show_cpu,
},
{
+ .name = CLI_DISK,
+ .exec = main_show_disk,
+ },
+ {
.name = CLI_PXE,
.exec = main_show_pxe,
},
diff --git a/com32/hdt/hdt-cli.c b/com32/hdt/hdt-cli.c
index 871fd76c..324c74ae 100644
--- a/com32/hdt/hdt-cli.c
+++ b/com32/hdt/hdt-cli.c
@@ -43,6 +43,7 @@ struct cli_mode_descr *list_modes[] = {
&cpu_mode,
&pci_mode,
&vesa_mode,
+ &disk_mode,
&vpd_mode,
NULL,
};
@@ -179,6 +180,12 @@ void set_mode(cli_mode_t mode, struct s_hardware* hardware)
snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
CLI_DMI);
break;
+ case DISK_MODE:
+ detect_disks(hardware);
+ hdt_cli.mode = mode;
+ snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
+ CLI_DISK);
+ break;
case VPD_MODE:
detect_vpd(hardware);
if (!hardware->is_vpd_valid) {
@@ -189,7 +196,6 @@ void set_mode(cli_mode_t mode, struct s_hardware* hardware)
snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ",
CLI_VPD);
break;
-
default:
/* Invalid mode */
printf("Unknown mode, please choose among:\n");
diff --git a/com32/hdt/hdt-cli.h b/com32/hdt/hdt-cli.h
index 516d2fc8..6f90e453 100644
--- a/com32/hdt/hdt-cli.h
+++ b/com32/hdt/hdt-cli.h
@@ -64,6 +64,7 @@
#define CLI_COMMANDS "commands"
#define CLI_DMI "dmi"
#define CLI_CPU "cpu"
+#define CLI_DISK "disk"
#define CLI_SHOW_LIST "list"
#define CLI_IRQ "irq"
#define CLI_MODES "modes"
@@ -80,6 +81,7 @@ typedef enum {
KERNEL_MODE,
SYSLINUX_MODE,
VESA_MODE,
+ DISK_MODE,
VPD_MODE,
} cli_mode_t;
@@ -138,6 +140,7 @@ struct cli_mode_descr kernel_mode;
struct cli_mode_descr cpu_mode;
struct cli_mode_descr pci_mode;
struct cli_mode_descr vesa_mode;
+struct cli_mode_descr disk_mode;
struct cli_mode_descr vpd_mode;
/* cli helpers */
@@ -173,6 +176,9 @@ void cli_detect_pci(struct s_hardware *hardware);
// CPU STUFF
void main_show_cpu(int argc, char **argv, struct s_hardware *hardware);
+// DISK STUFF
+void main_show_disk(int argc, char **argv, struct s_hardware *hardware);
+
// PXE STUFF
void main_show_pxe(int argc, char **argv, struct s_hardware *hardware);
diff --git a/com32/hdt/hdt-common.c b/com32/hdt/hdt-common.c
index 8cda7f06..0331bd19 100644
--- a/com32/hdt/hdt-common.c
+++ b/com32/hdt/hdt-common.c
@@ -34,6 +34,7 @@
#include "../lib/sys/vesa/vesa.h"
#include "hdt-common.h"
#include "lib-ansi.h"
+#include <disk/util.h>
/* ISOlinux requires a 8.3 format */
void convert_isolinux_filename(char *filename, struct s_hardware *hardware) {
@@ -241,18 +242,31 @@ int detect_vesa(struct s_hardware *hardware) {
/* Try to detect disks from port 0x80 to 0xff */
void detect_disks(struct s_hardware *hardware)
{
- hardware->disk_detection = true;
- for (int drive = 0x80; drive < 0xff; drive++) {
- if (get_disk_params(drive, hardware->disk_info) != 0)
- continue;
- struct diskinfo *d = &hardware->disk_info[drive];
- hardware->disks_count++;
- printf
- (" DISK 0x%X: %s : %s %s: sectors=%d, s/t=%d head=%d : EDD=%s\n",
- drive, d->aid.model, d->host_bus_type, d->interface_type,
- d->sectors, d->sectors_per_track, d->heads,
- d->edd_version);
- }
+ int i = -1;
+ int err;
+ char *error_msg;
+
+ if (hardware->disk_detection)
+ return;
+
+ hardware->disk_detection = true;
+ for (int drive = 0x80; drive < 0xff; drive++) {
+ i++;
+ hardware->disk_info[i].disk = drive;
+ err = get_drive_parameters(&hardware->disk_info[i]);
+
+ /* Do not print output when drive does not exists */
+ if (err == -1)
+ continue;
+
+ if (err) {
+ get_error(err, &error_msg);
+ more_printf("Error 0x%Xh while reading disk 0x%X:\n\t%s\n",
+ err, drive, error_msg);
+ free(error_msg);
+ }
+ hardware->disks_count++;
+ }
}
int detect_pxe(struct s_hardware *hardware)
diff --git a/com32/hdt/hdt-common.h b/com32/hdt/hdt-common.h
index 7e3dc7d8..9fd8a565 100644
--- a/com32/hdt/hdt-common.h
+++ b/com32/hdt/hdt-common.h
@@ -32,6 +32,8 @@
#include <syslinux/pxe.h>
#include "sys/pci.h"
+#include <disk/geom.h>
+
#include "cpuid.h"
#include "dmi/dmi.h"
#include "hdt-ata.h"
@@ -55,6 +57,17 @@ extern int display_line_nb;
display_line_nb++; \
} while (0);
+/* Display CPU registers for debugging purposes */
+static inline void printregs(const com32sys_t * r)
+{
+ printf("eflags = %08x ds = %04x es = %04x fs = %04x gs = %04x\n"
+ "eax = %08x ebx = %08x ecx = %08x edx = %08x\n"
+ "ebp = %08x esi = %08x edi = %08x esp = %08x\n",
+ r->eflags.l, r->ds, r->es, r->fs, r->gs,
+ r->eax.l, r->ebx.l, r->ecx.l, r->edx.l,
+ r->ebp.l, r->esi.l, r->edi.l, r->_unused_esp.l);
+}
+
struct s_pxe {
uint16_t vendor_id;
uint16_t product_id;
@@ -97,7 +110,7 @@ struct s_hardware {
s_cpu cpu; /* CPU information */
s_vpd vpd; /* VPD information */
struct pci_domain *pci_domain; /* PCI Devices */
- struct diskinfo disk_info[256]; /* Disk Information */
+ struct driveinfo disk_info[256]; /* Disk Information */
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 02f12f75..2283cafa 100644
--- a/com32/hdt/hdt-menu-disk.c
+++ b/com32/hdt/hdt-menu-disk.c
@@ -26,133 +26,190 @@
* -----------------------------------------------------------------------
*/
+#include <stdlib.h>
+#include <disk/geom.h>
+#include <disk/read.h>
+#include <disk/partition.h>
+#include <disk/error.h>
+
#include "hdt-menu.h"
+#include "hdt-util.h"
+
+static void compute_partition_info(int partnb,
+ struct part_entry *ptab,
+ char menu_title_ref[],
+ char menu_title[])
+{
+ char buffer[56];
+ char statbuffer[STATLEN];
+ int previous_size, size;
+ char previous_unit[3], unit[3]; // GB
+ char size_iec[8]; // GiB
+ sectors_to_size_dec(previous_unit, &previous_size, unit, &size, ptab->length);
+ sectors_to_size(ptab->length, size_iec);
+
+ add_named_menu(menu_title_ref, menu_title, -1);
+ set_menu_pos(5, 17);
+
+ snprintf(buffer, sizeof buffer, "Partition # : %d",
+ partnb);
+ snprintf(statbuffer, sizeof statbuffer, "Partition #: %d",
+ partnb);
+ 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",
+ (ptab->active_flag == 0x80) ? "Yes" : "No");
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+ snprintf(buffer, sizeof buffer, "Start : %d",
+ ptab->start_lba);
+ snprintf(statbuffer, sizeof statbuffer, "Start: %d",
+ ptab->start_lba);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+ snprintf(buffer, sizeof buffer, "End : %d",
+ ptab->start_lba + ptab->length);
+ snprintf(statbuffer, sizeof statbuffer, "End: %d",
+ ptab->start_lba + ptab->length);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+ snprintf(buffer, sizeof buffer, "Length : %s/%d %s (%d)",
+ size_iec, size, unit, ptab->length);
+ snprintf(statbuffer, sizeof statbuffer, "Length: %s/%d %s (%d)",
+ size_iec, size, unit, ptab->length);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+ snprintf(buffer, sizeof buffer, "Id : %X",
+ ptab->ostype);
+ snprintf(statbuffer, sizeof statbuffer, "Id: %X",
+ ptab->ostype);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+ char *parttype;
+ get_label(ptab->ostype, &parttype);
+ snprintf(buffer, sizeof buffer, "Type : %s",
+ parttype);
+ snprintf(statbuffer, sizeof statbuffer, "Type: %s",
+ parttype);
+ add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+ free(parttype);
+}
/* Compute the disk submenu */
-int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
- struct diskinfo *d, int disk_number)
+static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
+ struct driveinfo *d, int disk_number)
{
char buffer[MENULEN + 1];
char statbuffer[STATLEN + 1];
+ char *mbr = NULL;
- /* No need to add no existing devices */
- if (strlen(d[disk_number].aid.model) <= 0)
- return -1;
-
- snprintf(buffer, sizeof buffer, " Disk <%d> ", nb_sub_disk_menu);
+ snprintf(buffer, sizeof buffer, " Disk <0x%X> ", d[disk_number].disk);
menu[nb_sub_disk_menu].menu = add_menu(buffer, -1);
menu[nb_sub_disk_menu].items_count = 0;
- snprintf(buffer, sizeof buffer, "Model : %s",
- d[disk_number].aid.model);
- snprintf(statbuffer, sizeof statbuffer, "Model: %s",
- d[disk_number].aid.model);
- add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
- menu[nb_sub_disk_menu].items_count++;
-
- /* Compute device size */
- char previous_unit[3], unit[3]; //GB
- int previous_size, size = d[disk_number].sectors / 2; // Converting to bytes
- strlcpy(unit, "KB", 2);
- strlcpy(previous_unit, unit, 2);
- previous_size = size;
- if (size > 1000) {
- size = size / 1000;
- strlcpy(unit, "MB", 2);
- if (size > 1000) {
- previous_size = size;
- size = size / 1000;
- strlcpy(previous_unit, unit, 2);
- strlcpy(unit, "GB", 2);
- if (size > 1000) {
- previous_size = size;
- size = size / 1000;
- strlcpy(previous_unit, unit, 2);
- strlcpy(unit, "TB", 2);
- }
- }
- }
+ int previous_size, size;
+ char previous_unit[3], unit[3]; // GB
+ char size_iec[8]; // GiB
+ sectors_to_size_dec(previous_unit, &previous_size, unit, &size, d[disk_number].edd_params.sectors);
+ sectors_to_size(d[disk_number].edd_params.sectors, size_iec);
- snprintf(buffer, sizeof buffer, "Size : %d %s (%d %s)", size,
+ snprintf(buffer, sizeof buffer, "Size : %s/%d %s (%d %s)", size_iec,
+ size, unit, previous_size, previous_unit);
+ snprintf(statbuffer, sizeof statbuffer, "Size: %s/%d %s (%d %s)", size_iec, size,
unit, previous_size, previous_unit);
- snprintf(statbuffer, sizeof statbuffer, "Size: %d %s (%d %s)", size,
- unit, previous_size, previous_unit);
- add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
- menu[nb_sub_disk_menu].items_count++;
-
- snprintf(buffer, sizeof buffer, "Firmware Rev.: %s",
- d[disk_number].aid.fw_rev);
- snprintf(statbuffer, sizeof statbuffer, "Firmware Revision: %s",
- d[disk_number].aid.fw_rev);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "Serial Number: %s",
- d[disk_number].aid.serial_no);
- snprintf(statbuffer, sizeof statbuffer, "Serial Number: %s",
- d[disk_number].aid.serial_no);
- add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
- menu[nb_sub_disk_menu].items_count++;
-
- snprintf(buffer, sizeof buffer, "Interface : %s",
- d[disk_number].interface_type);
+ snprintf(buffer, sizeof buffer, "Interface : %s",
+ d[disk_number].edd_params.interface_type);
snprintf(statbuffer, sizeof statbuffer, "Interface: %s",
- d[disk_number].interface_type);
+ d[disk_number].edd_params.interface_type);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "Host Bus : %s",
- d[disk_number].host_bus_type);
+ snprintf(buffer, sizeof buffer, "Host Bus : %s",
+ d[disk_number].edd_params.host_bus_type);
snprintf(statbuffer, sizeof statbuffer, "Host Bus Type: %s",
- d[disk_number].host_bus_type);
+ d[disk_number].edd_params.host_bus_type);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "Sectors : %d",
- d[disk_number].sectors);
+ snprintf(buffer, sizeof buffer, "Sectors : %d",
+ (int) d[disk_number].edd_params.sectors);
snprintf(statbuffer, sizeof statbuffer, "Sectors: %d",
- d[disk_number].sectors);
+ (int) d[disk_number].edd_params.sectors);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "Heads : %d",
- d[disk_number].heads);
+ snprintf(buffer, sizeof buffer, "Heads : %d",
+ d[disk_number].legacy_max_head + 1);
snprintf(statbuffer, sizeof statbuffer, "Heads: %d",
- d[disk_number].heads);
+ d[disk_number].legacy_max_head + 1);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "Cylinders : %d",
- d[disk_number].cylinders);
+ snprintf(buffer, sizeof buffer, "Cylinders : %d",
+ d[disk_number].legacy_max_cylinder + 1);
snprintf(statbuffer, sizeof statbuffer, "Cylinders: %d",
- d[disk_number].cylinders);
+ d[disk_number].legacy_max_cylinder + 1);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "Sectors/Track: %d",
- d[disk_number].sectors_per_track);
+ snprintf(buffer, sizeof buffer, "Sectors/Track : %d",
+ d[disk_number].legacy_sectors_per_track);
snprintf(statbuffer, sizeof statbuffer, "Sectors per Track: %d",
- d[disk_number].sectors_per_track);
+ d[disk_number].legacy_sectors_per_track);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "Port : 0x%X", disk_number);
- snprintf(statbuffer, sizeof statbuffer, "Port: 0x%X", disk_number);
+ snprintf(buffer, sizeof buffer, "Drive number : 0x%X", d[disk_number].disk);
+ snprintf(statbuffer, sizeof statbuffer, "Drive number: 0x%X", d[disk_number].disk);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
- snprintf(buffer, sizeof buffer, "EDD Version : %s",
+ snprintf(buffer, sizeof buffer, "EDD Version : %X",
d[disk_number].edd_version);
- snprintf(statbuffer, sizeof statbuffer, "EDD Version: %s",
+ snprintf(statbuffer, sizeof statbuffer, "EDD Version: %X",
d[disk_number].edd_version);
add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
menu[nb_sub_disk_menu].items_count++;
+ add_sep();
+
+ /* Compute disk partitions menus */
+ mbr = read_mbr(d[disk_number].disk, NULL);
+ if (mbr) {
+ struct part_entry *ptab = (struct part_entry *)(mbr + PARTITION_TABLES_OFFSET);
+ char menu_title[MENULEN + 1];
+ char menu_title_ref[MENULEN + 1];
+ /* The calls to add_item need to be done first to draw the main submenu first */
+ int submenu_done = 0;
+submenu_disk:
+ for (int i = 0; i < 4; i++) {
+ if (ptab[i].ostype) {
+ snprintf(menu_title_ref, sizeof menu_title_ref, "disk_%x_part_%d", d[disk_number].disk, i);
+ snprintf(menu_title, sizeof menu_title, "Disk <%X>, Partition %d", d[disk_number].disk, i);
+ if (!submenu_done)
+ add_item(menu_title, "Partition information (start, end, length, type, ...)",
+ OPT_SUBMENU, menu_title_ref, 0);
+ else
+ compute_partition_info(i, &ptab[i], menu_title_ref, menu_title);
+ }
+ /* Now, draw the sub sub menus */
+ if (i == 3 && !submenu_done) {
+ submenu_done = 1;
+ goto submenu_disk;
+ }
+ }
+ }
+
return 0;
}
/* Compute the Disks menu */
-void compute_disks(struct s_hdt_menu *menu, struct diskinfo *disk_info, struct s_hardware *hardware)
+void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct s_hardware *hardware)
{
char buffer[MENULEN + 1];
int nb_sub_disk_menu = 0;
@@ -161,17 +218,19 @@ void compute_disks(struct s_hdt_menu *menu, struct diskinfo *disk_info, struct s
menu->disk_menu.items_count = 0;
if (hardware->disks_count == 0) return;
- for (int i = 0; i < 0xff; i++) {
- if (compute_disk_module
+ for (int i = 0; i < hardware->disks_count; i++) {
+ 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) == 0)
- nb_sub_disk_menu++;
+ i);
+ nb_sub_disk_menu++;
}
menu->disk_menu.menu = add_menu(" Disks ", -1);
for (int i = 0; i < nb_sub_disk_menu; i++) {
- snprintf(buffer, sizeof buffer, " Disk <%d> ", i);
+ snprintf(buffer, sizeof buffer, " Disk <%d> ", i+1);
add_item(buffer, "Disk", OPT_SUBMENU, NULL,
menu->disk_sub_menu[i].menu);
menu->disk_menu.items_count++;
diff --git a/com32/hdt/hdt-menu.c b/com32/hdt/hdt-menu.c
index 18158ae3..5cfe8eda 100644
--- a/com32/hdt/hdt-menu.c
+++ b/com32/hdt/hdt-menu.c
@@ -293,7 +293,7 @@ void detect_hardware(struct s_hardware *hardware)
printf("CPU: Detecting\n");
cpu_detect(hardware);
- printf("DISKS: Detecting\n");
+ printf("DISKS: Detecting");
detect_disks(hardware);
printf("DMI: Detecting Table\n");
diff --git a/com32/hdt/hdt-menu.h b/com32/hdt/hdt-menu.h
index 70fdb385..1cd2c129 100644
--- a/com32/hdt/hdt-menu.h
+++ b/com32/hdt/hdt-menu.h
@@ -91,9 +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
-int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
- struct diskinfo *d, int disk_number);
-void compute_disks(struct s_hdt_menu *menu, struct diskinfo *disk_info, struct s_hardware *hardware);
+void compute_disks(struct s_hdt_menu *menu, struct driveinfo *disk_info, struct s_hardware *hardware);
// DMI Stuff
void compute_motherboard(struct s_my_menu *menu, s_dmi * dmi);
diff --git a/com32/hdt/hdt-util.c b/com32/hdt/hdt-util.c
new file mode 100644
index 00000000..5bc566af
--- /dev/null
+++ b/com32/hdt/hdt-util.c
@@ -0,0 +1,71 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+void sectors_to_size(int sectors, char *buffer)
+{
+ int b = (sectors / 2);
+ int mib = b >> 10;
+ int gib = mib >> 10;
+ int tib = gib >> 10;
+
+ if (tib > 0)
+ sprintf(buffer, "%3d TiB", tib);
+ else if (gib > 0)
+ sprintf(buffer, "%3d GiB", gib);
+ else if (mib > 0)
+ sprintf(buffer, "%3d MiB", mib);
+ else
+ sprintf(buffer, "%d b", b);
+}
+
+void sectors_to_size_dec(char *previous_unit, int *previous_size, char *unit, int *size, int sectors)
+{
+ *size = sectors / 2; // Converting to bytes
+ strlcpy(unit, "KB", 2);
+ strlcpy(previous_unit, unit, 2);
+ *previous_size = *size;
+ if (*size > 1000) {
+ *size = *size / 1000;
+ strlcpy(unit, "MB", 2);
+ if (*size > 1000) {
+ *previous_size = *size;
+ *size = *size / 1000;
+ strlcpy(previous_unit, unit, 2);
+ strlcpy(unit, "GB", 2);
+ if (*size > 1000) {
+ *previous_size = *size;
+ *size = *size / 1000;
+ strlcpy(previous_unit, unit, 2);
+ strlcpy(unit, "TB", 2);
+ }
+ }
+ }
+}
diff --git a/com32/hdt/hdt-util.h b/com32/hdt/hdt-util.h
new file mode 100644
index 00000000..8c1d6de5
--- /dev/null
+++ b/com32/hdt/hdt-util.h
@@ -0,0 +1,33 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall
+ * be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_UTIL_H
+#define DEFINE_HDT_UTIL_H
+void sectors_to_size(int, char *);
+void sectors_to_size_dec(char *, int *, char *, int *, int);
+#endif