Sorry, forgot to attach phcoder wrote: > Hello, again > I had a look at your patch. In some mail it was suggested that kernel > patch should be split from module that uses it. So I resend the kernel > part of my patch. Another question is whether we need some kind of > abortion procedure (like in your patch) if a preboot hook fails. > Javier Martín wrote: >> An interface like this is implemented in another patch in "discussion", >> my drivemap patch (see the August list archives). As yours, it is >> linked-list based and very similar in the prototypes. I haven't checked >> if your code has any kind of errors/corner cases, > > I checked and found that I didn't check if grub_malloc succeeded > >> but it seems terser >> than mine even though it's a bit more difficult to understand because >> you use double pointers to avoid my handling of the head case. I don't >> understand the purpose of doubly-linking the list though... >> > The goal is to avoid walking through list when deleting an entry from it. >>> Whether we need also interface for adding "postboot" commands? (in case >>> boot_function returns) >> I don't think it would offer a lot of functionality because most loaders >> don't return on failure, they just get stuck or their payload >> triple-faults and reboots. > > It's the case for i386-pc loaders but not the case of some other targets > (e.g. EFI). So the question remains. > > Vladimir Serbinenko
Index: kern/loader.c =================================================================== --- kern/loader.c (revision 1845) +++ kern/loader.c (working copy) @@ -22,12 +22,46 @@ #include <grub/err.h> #include <grub/kernel.h> + 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; + +struct grub_preboot_t * +grub_loader_add_preboot (grub_err_t (*preboot_func) (int)) +{ + struct grub_preboot_t **cur=&grub_loader_preboots; + if (!preboot_func) + return 0; + while (*cur) + cur=&((*cur)->next); + *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)->prev_pointer=cur; + (*cur)->next=0; + (*cur)->preboot_func=preboot_func; + return *cur; +} + +void +grub_loader_remove_preboot (struct grub_preboot_t *p) +{ + if (!p) + return; + *(p->prev_pointer)=p->next; + if (p->next) + (p->next)->prev_pointer=p->prev_pointer; + grub_free (p); +} + int grub_loader_is_loaded (void) { @@ -64,11 +98,19 @@ 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,14 @@ #include <grub/err.h> #include <grub/types.h> +struct grub_preboot_t +{ + grub_err_t (*preboot_func) (int); + struct grub_preboot_t *next; + struct grub_preboot_t **prev_pointer; +}; + + /* Check if a loader is loaded. */ int EXPORT_FUNC(grub_loader_is_loaded) (void); @@ -37,6 +45,12 @@ /* Unset current loader, if any. */ void EXPORT_FUNC(grub_loader_unset) (void); +/*Add a preboot function*/ +struct grub_preboot_t *EXPORT_FUNC(grub_loader_add_preboot) (grub_err_t (*preboot_func) (int noreturn)); + +/*Remove given preboot function*/ +void EXPORT_FUNC(grub_loader_remove_preboot) (struct grub_preboot_t *p); + /* 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);
_______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel