aboutsummaryrefslogtreecommitdiff
path: root/src/boot.c
diff options
context:
space:
mode:
authorSam Eiderman <shmuel.eiderman@oracle.com>2019-06-12 12:37:00 +0300
committerGerd Hoffmann <kraxel@redhat.com>2019-11-06 10:56:00 +0100
commit7c66a439c07536b525ff9d5ce230775975e9c072 (patch)
tree1c6f05c10e4c2b123321144a6199ba83d250eaa9 /src/boot.c
parentc1ab7d7ed5306641784a9ed8972db5151a49a1a1 (diff)
downloadseabios-hppa-7c66a439c07536b525ff9d5ce230775975e9c072.zip
seabios-hppa-7c66a439c07536b525ff9d5ce230775975e9c072.tar.gz
seabios-hppa-7c66a439c07536b525ff9d5ce230775975e9c072.tar.bz2
geometry: Read LCHS from fw_cfg
Read boot device information from fw_cfg. Boot device information will contain logical geometry (LCHS) values, but it is implemented in a manner which allows extension. By receiving LCHS values directly from QEMU through fw_cfg we will be able to support logical geometries which can not be inferred by SeaBIOS itself. (For instance: A 8GB virtio-blk hard drive which was originally created as an IDE and must report LCHS of */32/63 for its operating system to function will always break under SeaBIOS since a LARGE/LBA translation will be used, causing the number of reported logical heads to be > 32.) The only LCHS paravirtual interface available at the moment is for IDE disks (rtc_read() in get_translation()) and it's limited to a maximum of 4 disks (this code existed in SeaBIOS's translation function before SCSI and VirtIO were even introduced). This is why we create a new interface which allows passing LCHS information per hdd. As mentioned, this interface may be easily extended to support more information per hdd. Boot device information is serialized in the following way: * struct_size (u32) * device path (sz string) * device information (struct_size) ... * device path (sz string) * device information (struct_size) Device path is a null terminated string in the "Open Firmware" device path format, the same path as used in bootorder. Reviewed-by: Karl Heubaum <karl.heubaum@oracle.com> Reviewed-by: Arbel Moshe <arbel.moshe@oracle.com> Signed-off-by: Sam Eiderman <shmuel.eiderman@oracle.com> Message-Id: <20190612093704.47175-2-shmuel.eiderman@oracle.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'src/boot.c')
-rw-r--r--src/boot.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/boot.c b/src/boot.c
index 5acf94f..461de86 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -24,6 +24,92 @@
/****************************************************************
+ * Boot device parameters
+ ****************************************************************/
+
+typedef struct BootDeviceSerialized {
+ u32 lcyls;
+ u32 lheads;
+ u32 lsecs;
+} PACKED BootDeviceSerialized;
+
+typedef struct BootDevice {
+ char *name;
+ u32 lcyls;
+ u32 lheads;
+ u32 lsecs;
+} BootDevice;
+
+static BootDevice *BootDevices VARVERIFY32INIT;
+static int BootDeviceCount;
+
+static void
+loadBootDevices(void)
+{
+ BootDeviceCount = 0;
+ int fsize;
+ char *f = romfile_loadfile("bootdevices", &fsize);
+ if (!f)
+ return;
+
+ if (fsize < sizeof(u32))
+ return;
+
+ u32 struct_size = *((u32 *)f);
+ if (struct_size < sizeof(BootDeviceSerialized))
+ return;
+
+ fsize -= sizeof(u32);
+ f += sizeof(u32);
+
+ int i;
+ int str_found = 0;
+
+ for (i = 0; i < fsize; i++) {
+ if (f[i] != '\0')
+ str_found = 1;
+ else if (f[i] == '\0' && str_found) {
+ str_found = 0;
+ i++;
+ if (i + struct_size > fsize)
+ break;
+ i += struct_size - 1;
+ BootDeviceCount++;
+ } else
+ break;
+ }
+
+ BootDevices = malloc_tmphigh(BootDeviceCount * sizeof(BootDevice));
+ if (!BootDevices) {
+ warn_noalloc();
+ free(f);
+ BootDeviceCount = 0;
+ return;
+ }
+
+ dprintf(1, "boot devices:\n");
+
+ BootDeviceSerialized *blk;
+ BootDevice *d;
+
+ for (i = 0; i < BootDeviceCount; i++) {
+ d = &BootDevices[i];
+ d->name = f;
+ f += strlen(f) + 1;
+
+ blk = (BootDeviceSerialized *)f;
+ d->lcyls = blk->lcyls;
+ d->lheads = blk->lheads;
+ d->lsecs = blk->lsecs;
+ f += struct_size;
+
+ dprintf(1, "%s: (%u, %u, %u)\n",
+ d->name, d->lcyls, d->lheads, d->lsecs);
+ }
+}
+
+
+/****************************************************************
* Boot priority ordering
****************************************************************/
@@ -288,6 +374,7 @@ boot_init(void)
BootRetryTime = romfile_loadint("etc/boot-fail-wait", 60*1000);
loadBootOrder();
+ loadBootDevices();
}