[SeaBIOS] [SeaBIOS PATCH v2] boot: support strict boot and make it configurable
Amos Kong
akong at redhat.com
Wed Dec 26 01:55:40 CET 2012
Current seabios will try to boot from selected devices first,
if they are all failed, seabios will also try to boot from
un-selected devices.
For example:
@ qemu-kvm -boot order=n,menu=on ...
Guest will boot from network first, if it's failed, guest will try to
boot from other un-selected devices (floppy, cdrom, disk) one by one.
We need to make it configurable, seabios user can config it by a rom
file('etc/boot-strict'). 'strict boot' means only boot from user
selected devices.
I added some comments in this patch to explain why we can judge if
device is selected or not by DEFAULT_PRIO(9999). I also added 'selected'
flag in struct bootentry_s and struct bev_s to make it clearer.
If this patch is accepted, I will add a boot option (-boot strict=on)
for qemu.
Signed-off-by: Amos Kong <akong at redhat.com>
---
src/boot.c | 31 ++++++++++++++++++++++++-------
1 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/src/boot.c b/src/boot.c
index c67cc7f..99ac791 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -92,6 +92,7 @@ find_prio(const char *glob)
int i;
for (i = 0; i < BootorderCount; i++)
if (glob_prefix(glob, Bootorder[i]))
+ // device exists in the Bootorder list loaded from rom file
return i+1;
return -1;
}
@@ -249,12 +250,14 @@ boot_setup(void)
CheckFloppySig = 0;
u32 bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2)
| ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4));
+ // reset device priority to default DEFAULT_PRIO(9999)
DefaultFloppyPrio = DefaultCDPrio = DefaultHDPrio
= DefaultBEVPrio = DEFAULT_PRIO;
int i;
for (i=101; i<104; i++) {
u32 val = bootorder & 0x0f;
bootorder >>= 4;
+ // priority of devices selected in bootorder will be changed
switch (val) {
case 1: DefaultFloppyPrio = i; break;
case 2: DefaultHDPrio = i; break;
@@ -280,6 +283,7 @@ struct bootentry_s {
struct drive_s *drive;
};
int priority;
+ int selected;
const char *description;
struct bootentry_s *next;
};
@@ -304,6 +308,9 @@ bootentry_add(int type, int prio, u32 data, const char *desc)
}
be->type = type;
be->priority = prio;
+ // set 'selected' flag according to the priority
+ if (prio != DEFAULT_PRIO)
+ be->selected = 1;
be->data = data;
be->description = desc ?: "?";
dprintf(3, "Registering bootable: %s (type:%d prio:%d data:%x)\n"
@@ -332,6 +339,8 @@ bootentry_add(int type, int prio, u32 data, const char *desc)
}
// Return the given priority if it's set - defaultprio otherwise.
+// This function is called by boot_add_*(), it will only pass
+// DEFAULT_PRIO(9999) for unselected devices as the boot-entry priority.
static inline int defPrio(int priority, int defaultprio) {
return (priority < 0) ? defaultprio : priority;
}
@@ -454,13 +463,14 @@ interactive_bootmenu(void)
struct bev_s {
int type;
u32 vector;
+ int selected;
};
static struct bev_s BEV[20];
static int BEVCount;
static int HaveHDBoot, HaveFDBoot;
static void
-add_bev(int type, u32 vector)
+add_bev(int type, u32 vector, int selected)
{
if (type == IPL_TYPE_HARDDISK && HaveHDBoot++)
return;
@@ -471,6 +481,7 @@ add_bev(int type, u32 vector)
struct bev_s *bev = &BEV[BEVCount++];
bev->type = type;
bev->vector = vector;
+ bev->selected = selected;
}
// Prepare for boot - show menu and run bcvs.
@@ -494,29 +505,29 @@ boot_prep(void)
switch (pos->type) {
case IPL_TYPE_BCV:
call_bcv(pos->vector.seg, pos->vector.offset);
- add_bev(IPL_TYPE_HARDDISK, 0);
+ add_bev(IPL_TYPE_HARDDISK, 0, pos->selected);
break;
case IPL_TYPE_FLOPPY:
map_floppy_drive(pos->drive);
- add_bev(IPL_TYPE_FLOPPY, 0);
+ add_bev(IPL_TYPE_FLOPPY, 0, pos->selected);
break;
case IPL_TYPE_HARDDISK:
map_hd_drive(pos->drive);
- add_bev(IPL_TYPE_HARDDISK, 0);
+ add_bev(IPL_TYPE_HARDDISK, 0, pos->selected);
break;
case IPL_TYPE_CDROM:
map_cd_drive(pos->drive);
// NO BREAK
default:
- add_bev(pos->type, pos->data);
+ add_bev(pos->type, pos->data, pos->selected);
break;
}
pos = pos->next;
}
// If nothing added a floppy/hd boot - add it manually.
- add_bev(IPL_TYPE_FLOPPY, 0);
- add_bev(IPL_TYPE_HARDDISK, 0);
+ add_bev(IPL_TYPE_FLOPPY, 0, 0);
+ add_bev(IPL_TYPE_HARDDISK, 0, 0);
}
@@ -654,6 +665,12 @@ do_boot(int seq_nr)
// Boot the given BEV type.
struct bev_s *ie = &BEV[seq_nr];
+
+ int strict = romfile_loadint("etc/boot-strict", 0);
+ // do strict boot, only boot from user selected devices
+ if (strict && !ie->selected)
+ boot_fail();
+
switch (ie->type) {
case IPL_TYPE_FLOPPY:
printf("Booting from Floppy...\n");
--
1.7.1
More information about the SeaBIOS
mailing list