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@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");