From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1KaamY-0006iX-9q for mharc-grub-devel@gnu.org; Tue, 02 Sep 2008 14:39:14 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KaamV-0006f9-3H for grub-devel@gnu.org; Tue, 02 Sep 2008 14:39:11 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KaamU-0006dr-4P for grub-devel@gnu.org; Tue, 02 Sep 2008 14:39:10 -0400 Received: from [199.232.76.173] (port=44496 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KaamU-0006de-0C for grub-devel@gnu.org; Tue, 02 Sep 2008 14:39:10 -0400 Received: from fg-out-1718.google.com ([72.14.220.156]:49995) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KaamT-00016K-JN for grub-devel@gnu.org; Tue, 02 Sep 2008 14:39:09 -0400 Received: by fg-out-1718.google.com with SMTP id l26so1647376fgb.30 for ; Tue, 02 Sep 2008 11:39:08 -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 :x-enigmail-version:content-type; bh=tAvAmUMdF1WqnfqHTePYBA7pUZBKnV4MC8ow89hBXjA=; b=LL2t3wd3lGzq3IIo5HL5AljlZbNw1fHbQQW/HiuEGRdocSFaqdPFdebnIAXlk6ZRml 7vPuSnXDBq1cEnurZLdyeC5YgKRp1KXiOYme2s+5w3lME8kouSLhcGn93fuX3EQ0FV5F HdiSmIpVuMg+52IquFG1ZaoelJwwVrN543rZU= 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:x-enigmail-version:content-type; b=pDV9Pr75FTdZcankFt0fFFiIXtbfMkwSWsZ+rlx4v5TEXahHkOlVVIKCJGj5wpVw1B hvEW39SpBEsLAV+n6quRl+SJKlCk88BRRdKNvh4gY5ZCt9GSOsVeWHP9c9d18y2VsMgl Al3/iBG+ZFi17FPwNUVyhMmrSWFAlG88hjk9g= Received: by 10.86.36.11 with SMTP id j11mr5898609fgj.7.1220380748679; Tue, 02 Sep 2008 11:39:08 -0700 (PDT) Received: from ?192.168.1.15? ( [83.76.170.177]) by mx.google.com with ESMTPS id 12sm7402411fgg.0.2008.09.02.11.39.05 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 02 Sep 2008 11:39:07 -0700 (PDT) Message-ID: <48BD8847.9030502@gmail.com> Date: Tue, 02 Sep 2008 20:39:03 +0200 From: phcoder User-Agent: Thunderbird 2.0.0.16 (X11/20080724) MIME-Version: 1.0 To: The development of GRUB 2 References: <48BD4C52.6040308@gmail.com> <1220367299.23879.15.camel@localhost> <48BD62BE.7090507@gmail.com> <1220373059.23879.25.camel@localhost> In-Reply-To: <1220373059.23879.25.camel@localhost> X-Enigmail-Version: 0.95.0 Content-Type: multipart/mixed; boundary="------------020307030803010004050500" X-detected-kernel: by monty-python.gnu.org: Linux 2.6 (newer, 2) Subject: Re: Sendkey patch 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: Tue, 02 Sep 2008 18:39:11 -0000 This is a multi-part message in MIME format. --------------020307030803010004050500 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Javier Martín wrote: > But you negate any performance gain when you _do_ traverse the list to > add an entry to it instead of just make it the new head as I do. > Besides, even for that, double indirection should be avoided in the > structure previous pointer because it makes things oh-so-incredibly > confusing. I was thinking about code size then about performance or easy of understanding. On my system this code results in 91 addition bytes in core image (63 if I remove grub_error). Do you have any idea how it would be possible to do an error message without description or put some generic description? > > Besides, I think the "user" (i.e. module) visible type returned by _add > and taken by _remove should be a "blank hidden type", i.e. you don't > need to declare "struct grub_preboot_t" in loader.h because the public > interface only uses _pointers_ to it, whose size is known. This is all > the C compiler requires and you avoid polluting the namespace with > internal implementation details. I recommend the following typedefs: > > typedef struct grub_preboot_t* grub_preboot_hnd; > typedef grub_err_t *(grub_preboot_func)(int noreturn); > > So that the prototypes would look > > grub_preboot_hnd add(grub_preboot_func f); > void remove(grub_preboot_hnd handle); I noticed that actually no code needs the size of grub_preoot_hnd. So I changed it to void * Vladimir Serbinenko --------------020307030803010004050500 Content-Type: text/x-diff; name="preboot.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="preboot.patch" Index: kern/loader.c =================================================================== --- kern/loader.c (revision 1845) +++ kern/loader.c (working copy) @@ -22,12 +22,54 @@ #include #include +#define PREBOOT_HND(x) (((struct grub_preboot_t *)x)) + +struct grub_preboot_t +{ + grub_err_t (*preboot_func) (int); + struct grub_preboot_t *next; + struct grub_preboot_t **prev_pointer; +}; + static grub_err_t (*grub_loader_boot_func) (void); static grub_err_t (*grub_loader_unload_func) (void); static int grub_loader_noreturn; static int grub_loader_loaded; +static struct grub_preboot_t *grub_loader_preboots=0; + +void * +grub_loader_add_preboot (grub_err_t (*preboot_func) (int)) +{ + struct grub_preboot_t *cur; + if (!preboot_func) + return 0; + cur=(struct grub_preboot_t *)grub_malloc (sizeof (struct grub_preboot_t)); + if (!cur) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, "hook not added"); + return 0; + } + cur->next=grub_loader_preboots; + cur->prev_pointer=0; + cur->next->prev_pointer=&(cur->next); + cur->preboot_func=preboot_func; + grub_loader_preboots=cur; + return cur; +} + +void +grub_loader_remove_preboot (void *p) +{ + if (!p) + return; + *(PREBOOT_HND(p)->prev_pointer)=PREBOOT_HND(p)->next; + if (PREBOOT_HND(p)->next) + PREBOOT_HND(p)->next->prev_pointer=PREBOOT_HND(p)->prev_pointer; + grub_free (p); +} + int grub_loader_is_loaded (void) { @@ -64,12 +106,18 @@ grub_err_t grub_loader_boot (void) { + struct grub_preboot_t *iter=grub_loader_preboots; if (! grub_loader_loaded) return grub_error (GRUB_ERR_NO_KERNEL, "no loaded kernel"); if (grub_loader_noreturn) grub_machine_fini (); - + while (iter) + { + if (iter->preboot_func) + iter->preboot_func (grub_loader_noreturn); + iter=iter->next; + } return (grub_loader_boot_func) (); } Index: include/grub/loader.h =================================================================== --- include/grub/loader.h (revision 1845) +++ include/grub/loader.h (working copy) @@ -25,6 +25,7 @@ #include #include + /* Check if a loader is loaded. */ int EXPORT_FUNC(grub_loader_is_loaded) (void); @@ -37,6 +38,12 @@ /* Unset current loader, if any. */ void EXPORT_FUNC(grub_loader_unset) (void); +/*Add a preboot function*/ +void *EXPORT_FUNC(grub_loader_add_preboot) (grub_err_t (*preboot_func) (int noreturn)); + +/*Remove given preboot function*/ +void EXPORT_FUNC(grub_loader_remove_preboot) (void *hnd); + /* Call the boot hook in current loader. This may or may not return, depending on the setting by grub_loader_set. */ grub_err_t EXPORT_FUNC(grub_loader_boot) (void); --------------020307030803010004050500--