From patchwork Wed Dec 26 00:55:40 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amos Kong X-Patchwork-Id: 208135 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B75352C00AC for ; Wed, 26 Dec 2012 11:56:01 +1100 (EST) Received: from localhost ([::1]:43180 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TnfHr-0000TN-6G for incoming@patchwork.ozlabs.org; Tue, 25 Dec 2012 19:55:59 -0500 Received: from eggs.gnu.org ([208.118.235.92]:37697) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TnfHk-0000TI-8G for qemu-devel@nongnu.org; Tue, 25 Dec 2012 19:55:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TnfHi-0008JA-PT for qemu-devel@nongnu.org; Tue, 25 Dec 2012 19:55:52 -0500 Received: from mx1.redhat.com ([209.132.183.28]:49170) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TnfHi-0008J5-IK for qemu-devel@nongnu.org; Tue, 25 Dec 2012 19:55:50 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qBQ0tlt0002968 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 25 Dec 2012 19:55:47 -0500 Received: from dhcp-8-167.nay.redhat.com ([10.66.7.126]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id qBQ0thau010950; Tue, 25 Dec 2012 19:55:44 -0500 From: Amos Kong To: seabios@seabios.org, kevin@koconnor.net Date: Wed, 26 Dec 2012 08:55:40 +0800 Message-Id: <1356483340-12962-1-git-send-email-akong@redhat.com> In-Reply-To: <20121225103701.GA6688@t430s.redhat.com> References: <20121225103701.GA6688@t430s.redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: alex.williamson@redhat.com, Amos Kong , dallan@redhat.com, qemu-devel@nongnu.org, gleb@redhat.com Subject: [Qemu-devel] [SeaBIOS PATCH v2] boot: support strict boot and make it configurable X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- 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");