Enhance boot menu to allow user to select which CD drive to boot from.
authorKevin O'Connor <kevin@koconnor.net>
Mon, 16 Feb 2009 15:51:24 +0000 (10:51 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Mon, 16 Feb 2009 15:51:24 +0000 (10:51 -0500)
src/boot.c
src/boot.h
src/cdrom.c
src/disk.h

index 404b043cd189ef6313988494f0e495720b5037dd..6b4e9851966be094286b6f3de66ed4bd3ba785b1 100644 (file)
@@ -48,7 +48,6 @@ boot_setup()
     }
 
     IPL.bevcount = ie - IPL.bev;
-    IPL.bcv_override = -1;
     SET_EBDA(boot_sequence, 0xffff);
     if (CONFIG_COREBOOT) {
         // XXX - hardcode defaults for coreboot.
@@ -148,7 +147,7 @@ menu_show_harddisk(struct ipl_entry_s *ie, int menupos)
         switch (ie->type) {
         case IPL_TYPE_HARDDISK:
             printf("%d. ata%d-%d %s\n", menupos + i
-                   , ie->vector / 2, ie->vector %2, ie->description);
+                   , ie->vector / 2, ie->vector % 2, ie->description);
             break;
         default:
             menu_show_default(ie, menupos+i);
@@ -162,9 +161,13 @@ menu_show_harddisk(struct ipl_entry_s *ie, int menupos)
 static int
 menu_show_cdrom(struct ipl_entry_s *ie, int menupos)
 {
-    if (!ATA.cdcount)
-        return 0;
-    return menu_show_default(ie, menupos);
+    int i;
+    for (i = 0; i < ATA.cdcount; i++) {
+        int driveid = ATA.idmap[1][i];
+        printf("%d. CD-Rom [ata%d-%d %s]\n", menupos + i
+               , driveid / 2, driveid % 2, ATA.devices[driveid].model);
+    }
+    return ATA.cdcount;
 }
 
 // Show IPL option menu.
@@ -229,9 +232,16 @@ interactive_bootmenu()
             bev++;
         }
 
-        // A harddrive request enables a BCV order.
-        if (IPL.bev[bev].type == IPL_TYPE_HARDDISK)
+        switch (IPL.bev[bev].type) {
+        case IPL_TYPE_HARDDISK:
+            // A harddrive request enables a BCV order.
             IPL.bcv_override = choice-1;
+            break;
+        case IPL_TYPE_CDROM:
+            // Select cdrom to boot from.
+            IPL.cdrom_override = choice-1;
+            break;
+        }
 
         // Add user choice to the boot order.
         IPL.bootorder = (IPL.bootorder << 4) | (bev+1);
@@ -266,7 +276,7 @@ boot_prep()
 
     // Run BCVs
     int override = IPL.bcv_override;
-    if (override >= 0)
+    if (override < IPL.bcvcount)
         run_bcv(&IPL.bcv[override]);
     int i;
     for (i=0; i<IPL.bcvcount; i++)
@@ -337,7 +347,7 @@ boot_cdrom()
 {
     if (! CONFIG_CDROM_BOOT)
         return;
-    int status = cdrom_boot();
+    int status = cdrom_boot(IPL.cdrom_override);
     if (status) {
         printf("Boot failed: Could not read from CDROM (code %04x)\n", status);
         return;
index a63e09b98844e97c9c5c4772cf22614e93b88425..f251096b70ac4f68cb2a1796d2690a6857428163 100644 (file)
@@ -18,7 +18,7 @@ struct ipl_s {
     struct ipl_entry_s bev[8];
     struct ipl_entry_s bcv[8];
     int bevcount, bcvcount;
-    int bcv_override;
+    int bcv_override, cdrom_override;
     u32 bootorder;
     int checkfloppysig;
 };
index ece77a064660d7b747efa0c1b9613a3fd5b3af7b..f518a377636dc39c1e2b173fde03093bd04a989e 100644 (file)
@@ -389,21 +389,6 @@ atapi_is_ready(u16 device)
     return 0;
 }
 
-static int
-atapi_is_cdrom(u8 device)
-{
-    if (device >= CONFIG_MAX_ATA_DEVICES)
-        return 0;
-
-    if (GET_GLOBAL(ATA.devices[device].type) != ATA_TYPE_ATAPI)
-        return 0;
-
-    if (GET_GLOBAL(ATA.devices[device].device) != ATA_DEVICE_CDROM)
-        return 0;
-
-    return 1;
-}
-
 // Compare a string on the stack to one in the code segment.
 static int
 streq_cs(u8 *s1, char *cs_s2)
@@ -420,25 +405,23 @@ streq_cs(u8 *s1, char *cs_s2)
 }
 
 int
-cdrom_boot()
+cdrom_boot(int cdid)
 {
-    // Find out the first cdrom
-    u8 device;
-    for (device=0; device<CONFIG_MAX_ATA_DEVICES; device++)
-        if (atapi_is_cdrom(device))
-            break;
-    if (device >= CONFIG_MAX_ATA_DEVICES)
-        // cdrom not found
+    // Verify device is a cdrom.
+    if (cdid >= ATA.cdcount)
+        return 1;
+    int driveid = GET_GLOBAL(ATA.idmap[1][cdid]);
+    if (GET_GLOBAL(ATA.devices[driveid].device) != ATA_DEVICE_CDROM)
         return 2;
 
-    int ret = atapi_is_ready(device);
+    int ret = atapi_is_ready(driveid);
     if (ret)
         dprintf(1, "atapi_is_ready returned %d\n", ret);
 
     // Read the Boot Record Volume Descriptor
     u8 buffer[2048];
     struct disk_op_s dop;
-    dop.driveid = device;
+    dop.driveid = driveid;
     dop.lba = 0x11;
     dop.count = 1;
     dop.buf_fl = MAKE_FLATPTR(GET_SEG(SS), buffer);
@@ -479,8 +462,8 @@ cdrom_boot()
     u8 media = buffer[0x21];
     SET_EBDA2(ebda_seg, cdemu.media, media);
 
-    SET_EBDA2(ebda_seg, cdemu.controller_index, device/2);
-    SET_EBDA2(ebda_seg, cdemu.device_spec, device%2);
+    SET_EBDA2(ebda_seg, cdemu.controller_index, driveid/2);
+    SET_EBDA2(ebda_seg, cdemu.device_spec, driveid%2);
 
     u16 boot_segment = *(u16*)&buffer[0x22];
     if (!boot_segment)
@@ -504,11 +487,7 @@ cdrom_boot()
 
     if (media == 0) {
         // No emulation requested - return success.
-
-        // FIXME ElTorito Hardcoded. cdrom is hardcoded as device 0xE0.
-        // Win2000 cd boot needs to know it booted from cd
-        SET_EBDA2(ebda_seg, cdemu.emulated_drive, 0xE0);
-
+        SET_EBDA2(ebda_seg, cdemu.emulated_drive, 0xE0 + cdid);
         return 0;
     }
 
index 2774cde7d546be43dc549acae6bbc3b9735dd755..3661d27f7abd0059ce41555e5c1517ec286764b7 100644 (file)
@@ -230,6 +230,6 @@ void disk_13XX(struct bregs *regs, u8 device);
 void cdrom_13(struct bregs *regs, u8 device);
 void cdemu_13(struct bregs *regs);
 void cdemu_134b(struct bregs *regs);
-int cdrom_boot();
+int cdrom_boot(int cdid);
 
 #endif // disk.h