From 14221cd86eadba82255fdc55ed174d401c7a0a04 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 21 Sep 2018 09:35:03 +0200 Subject: pretty boot menu entry for cdrom drives Show the volume label of bootable cdroms. Signed-off-by: Gerd Hoffmann --- src/boot.c | 10 ++++++++++ src/cdrom.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/util.h | 1 + 3 files changed, 57 insertions(+) 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); -- cgit v1.2.1