aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2018-09-21 09:35:03 +0200
committerGerd Hoffmann <kraxel@redhat.com>2018-10-05 13:28:27 +0200
commit14221cd86eadba82255fdc55ed174d401c7a0a04 (patch)
tree7dc392debe12c18dd1649b63cb02bc4e1a41fc27
parentbf8e4f902c3608f9e76bba3710812e51560a2ccc (diff)
downloadseabios-14221cd86eadba82255fdc55ed174d401c7a0a04.zip
seabios-14221cd86eadba82255fdc55ed174d401c7a0a04.tar.gz
seabios-14221cd86eadba82255fdc55ed174d401c7a0a04.tar.bz2
pretty boot menu entry for cdrom drives
Show the volume label of bootable cdroms. Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
-rw-r--r--src/boot.c10
-rw-r--r--src/cdrom.c46
-rw-r--r--src/util.h1
3 files changed, 57 insertions, 0 deletions
diff --git a/src/boot.c b/src/boot.c
index ff705fd..9f82f3c 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -395,6 +395,16 @@ boot_add_hd(struct drive_s *drive, const char *desc, int prio)
void
boot_add_cd(struct drive_s *drive, const char *desc, int prio)
{
+ if (GET_GLOBAL(PlatformRunningOn) & PF_QEMU) {
+ // We want short boot times. But on physical hardware even
+ // the test unit ready can take several seconds. So do media
+ // access on qemu only, where we know it will be fast.
+ char *extra = cdrom_media_info(drive);
+ if (extra) {
+ desc = znprintf(MAXDESCSIZE, "%s (%s)", desc, extra);
+ free(extra);
+ }
+ }
bootentry_add(IPL_TYPE_CDROM, defPrio(prio, DefaultCDPrio)
, (u32)drive, desc);
}
diff --git a/src/cdrom.c b/src/cdrom.c
index 828fb3b..577d69d 100644
--- a/src/cdrom.c
+++ b/src/cdrom.c
@@ -274,3 +274,49 @@ cdrom_boot(struct drive_s *drive)
return 0;
}
+
+// check if media is present and the drive is bootable.
+// in case it is return the volume label.
+char*
+cdrom_media_info(struct drive_s *drive)
+{
+ ASSERT32FLAT();
+
+ struct disk_op_s dop;
+ memset(&dop, 0, sizeof(dop));
+ dop.drive_fl = drive;
+
+ int ret = scsi_is_ready(&dop);
+ if (ret)
+ return NULL;
+
+ // Read the Boot Record Volume Descriptor
+ u8 buffer[CDROM_SECTOR_SIZE];
+ dop.command = CMD_READ;
+ dop.lba = 0x11;
+ dop.count = 1;
+ dop.buf_fl = buffer;
+ ret = process_op(&dop);
+ if (ret)
+ return NULL;
+
+ // Is it bootable?
+ if (buffer[0])
+ return NULL;
+ if (strcmp((char*)&buffer[1], "CD001\001EL TORITO SPECIFICATION") != 0)
+ return NULL;
+
+ // Read the Primary Volume Descriptor
+ dop.command = CMD_READ;
+ dop.lba = 0x10;
+ dop.count = 1;
+ dop.buf_fl = buffer;
+ ret = process_op(&dop);
+ if (ret)
+ return NULL;
+
+ // Read volume id, trim trailing spaces
+ char *volume = znprintf(30, "%s", buffer + 40);
+ nullTrailingSpace(volume);
+ return volume;
+}
diff --git a/src/util.h b/src/util.h
index 7a23b51..6dd080f 100644
--- a/src/util.h
+++ b/src/util.h
@@ -50,6 +50,7 @@ struct disk_op_s;
int cdemu_process_op(struct disk_op_s *op);
void cdrom_prepboot(void);
int cdrom_boot(struct drive_s *drive_g);
+char *cdrom_media_info(struct drive_s *drive_g);
// clock.c
void clock_setup(void);