From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1LsfNM-000712-Pr for mharc-grub-devel@gnu.org; Sat, 11 Apr 2009 11:44:12 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LsfNL-00070S-7o for grub-devel@gnu.org; Sat, 11 Apr 2009 11:44:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LsfNG-0006yQ-Mg for grub-devel@gnu.org; Sat, 11 Apr 2009 11:44:10 -0400 Received: from [199.232.76.173] (port=57705 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LsfNG-0006y7-Ah for grub-devel@gnu.org; Sat, 11 Apr 2009 11:44:06 -0400 Received: from mail-bw0-f167.google.com ([209.85.218.167]:33126) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LsfNF-0006ON-Di for grub-devel@gnu.org; Sat, 11 Apr 2009 11:44:05 -0400 Received: by bwz11 with SMTP id 11so1618956bwz.42 for ; Sat, 11 Apr 2009 08:44:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:references:in-reply-to :content-type; bh=hiw9iGlEPm/FKGGsIVnMfhwpgND6QBXBpKGMMx+fHjU=; b=HkWT2kAoE1kiB+CK6PNFuKGDH3SHSZpgSYlG+qK+vgT6E7/bCjZlMCBTTTfbwZsL5z 8whn2r0WmL4toKK7+KaofXCoebKX9uLQkvLj/Uc8CcPp56bkEUUhCYo/n86PrXrnDn+Y F8wpZeRiFWMwdAWYEpF1jzRytXd25xVTWqP8g= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type; b=dgUMZ8xi/vb/894Kpxv7dIlFVUyTqot9YyuAOFh1Do+Bf2a7K2qDrEAAll+JfvQQ07 N+OsT7QN3yhOD2RdrbEEMQJbHVIeugcbziwfH0ew8DQg9pzDdi5mcaC5mUmE5iyakCt6 nHocMk7mEoGI3YUBQxUduaIvR6xHPRk71ZqtQ= Received: by 10.86.92.9 with SMTP id p9mr3487194fgb.15.1239464643608; Sat, 11 Apr 2009 08:44:03 -0700 (PDT) Received: from ?192.168.1.25? (122-34.1-85.cust.bluewin.ch [85.1.34.122]) by mx.google.com with ESMTPS id 12sm3990476fgg.27.2009.04.11.08.44.02 (version=SSLv3 cipher=RC4-MD5); Sat, 11 Apr 2009 08:44:03 -0700 (PDT) Message-ID: <49E0BAC7.2030503@gmail.com> Date: Sat, 11 Apr 2009 17:44:07 +0200 From: phcoder User-Agent: Thunderbird 2.0.0.21 (X11/20090318) MIME-Version: 1.0 To: The development of GRUB 2 References: <49DFDAB7.1080009@gmail.com> <200904111916.06107.okuji@enbug.org> In-Reply-To: <200904111916.06107.okuji@enbug.org> Content-Type: multipart/mixed; boundary="------------010406040402080906040208" X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: Re: [PATCH] Preboot support X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Apr 2009 15:44:11 -0000 This is a multi-part message in MIME format. --------------010406040402080906040208 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit > - Using an int value for the priority is quetionable. Very often, this style > of priority system leads to chaos, because everyone picks up arbitrary > numbers randomly. I prefer to define enums with a careful analysis. I will think about it. But the analysis is difficult because we don't know in advance all the possible use cases of this feature > > Regards, > Okuji > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel -- Regards Vladimir 'phcoder' Serbinenko --------------010406040402080906040208 Content-Type: text/x-diff; name="preboot.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="preboot.patch" diff --git a/ChangeLog b/ChangeLog index 401a374..a6dd8f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-04-06 Vladimir Serbinenko + + Preboot hooks support + + * commands/boot.c (struct grub_preboot_t): new declaration + (preboots_head): new variable + (preboots_tail): likewise + (grub_loader_add_preboot): new function + (grub_loader_remove_preboot): likewise + (grub_loader_set): launch preboot hooks + * include/grub/loader.h (grub_loader_add_preboot): new declaration + (grub_loader_remove_preboot): likewise + 2009-03-22 Vladimir Serbinenko Move loader out of the kernel diff --git a/commands/boot.c b/commands/boot.c index 1cc98eb..ef4913b 100644 --- a/commands/boot.c +++ b/commands/boot.c @@ -22,12 +22,24 @@ #include #include #include +#include static grub_err_t (*grub_loader_boot_func) (void); static grub_err_t (*grub_loader_unload_func) (void); static int grub_loader_noreturn; +struct grub_preboot_t +{ + grub_err_t (*preboot_func) (int); + grub_err_t (*preboot_rest_func) (void); + int prio; + struct grub_preboot_t *next; + struct grub_preboot_t *prev; +}; + static int grub_loader_loaded; +static struct grub_preboot_t *preboots_head = 0, + *preboots_tail = 0; int grub_loader_is_loaded (void) @@ -35,6 +47,68 @@ grub_loader_is_loaded (void) return grub_loader_loaded; } +/* Register a preboot hook. */ +void * +grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noreturn), + grub_err_t (*preboot_rest_func) (void), + int prio) +{ + struct grub_preboot_t *cur, *new_preboot; + + if (! preboot_func && ! preboot_rest_func) + return 0; + + new_preboot = (struct grub_preboot_t *) + grub_malloc (sizeof (struct grub_preboot_t)); + if (! new_preboot) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added"); + return 0; + } + + new_preboot->preboot_func = preboot_func; + new_preboot->preboot_rest_func = preboot_rest_func; + new_preboot->prio = prio; + + for (cur = preboots_head; cur && cur->prio > prio; cur = cur->next); + + if (cur) + { + new_preboot->next = cur; + new_preboot->prev = cur->prev; + cur->prev = new_preboot; + } + else + { + new_preboot->next = 0; + new_preboot->prev = preboots_tail; + preboots_tail = new_preboot; + } + if (new_preboot->prev) + new_preboot->prev->next = new_preboot; + else + preboots_head = new_preboot; + + return new_preboot; +} + +void +grub_loader_remove_preboot (void *hnd) +{ + struct grub_preboot_t *preb = hnd; + + if (preb->next) + preb->next->prev = preb->prev; + else + preboots_tail = preb->prev; + if (preb->prev) + preb->prev->next = preb->next; + else + preboots_head = preb->next; + + grub_free (preb); +} + void grub_loader_set (grub_err_t (*boot) (void), grub_err_t (*unload) (void), @@ -65,13 +139,32 @@ grub_loader_unset(void) grub_err_t grub_loader_boot (void) { + grub_err_t err = GRUB_ERR_NONE; + struct grub_preboot_t *cur; + if (! grub_loader_loaded) return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel"); if (grub_loader_noreturn) grub_machine_fini (); + + for (cur = preboots_head; cur; cur = cur->next) + if (err = cur->preboot_func (grub_loader_noreturn)) + { + for (cur = cur->prev; cur; cur = cur->prev) + cur->preboot_rest_func (); + return err; + } - return (grub_loader_boot_func) (); + err = (grub_loader_boot_func) (); + + for (cur = preboots_tail; cur; cur = cur->prev) + if (! err) + err = cur->preboot_rest_func (); + else + cur->preboot_rest_func (); + + return err; } /* boot */ diff --git a/include/grub/loader.h b/include/grub/loader.h index 185d297..72d1894 100644 --- a/include/grub/loader.h +++ b/include/grub/loader.h @@ -41,4 +41,12 @@ void grub_loader_unset (void); depending on the setting by grub_loader_set. */ grub_err_t grub_loader_boot (void); +/* Register a preboot hook. */ +void *grub_loader_register_preboot_hook (grub_err_t (*preboot_func) (int noret), + grub_err_t (*preboot_rest_func) (void), + int prio); + +/* Unregister given preboot hook. */ +void grub_loader_unregister_preboot_hook (void *hnd); + #endif /* ! GRUB_LOADER_HEADER */ --------------010406040402080906040208--