All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Preboot support
@ 2009-04-10 23:48 phcoder
  2009-04-11 10:16 ` Yoshinori K. Okuji
  0 siblings, 1 reply; 9+ messages in thread
From: phcoder @ 2009-04-10 23:48 UTC (permalink / raw)
  To: The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 258 bytes --]

Hello, here is the preboot hooks support. Apply on top of my bootmove 
patch. They are very useful for patches like sendkey (my old patch that 
I'll rediff), badram, acpi (2 patches in separate threads) or drivemap
-- 

Regards
Vladimir 'phcoder' Serbinenko

[-- Attachment #2: preboot.patch --]
[-- Type: text/x-diff, Size: 4301 bytes --]

diff --git a/ChangeLog b/ChangeLog
index a69e381..2b37e04 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-04-06  Vladimir Serbinenko <phcoder@gmail.com>
+
+	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 <phcoder@gmail.com>
 
 	Move loader out of the kernel
diff --git a/commands/boot.c b/commands/boot.c
index 9a08fea..3eaf111 100644
--- a/commands/boot.c
+++ b/commands/boot.c
@@ -22,12 +22,25 @@
 #include <grub/misc.h>
 #include <grub/loader.h>
 #include <grub/kernel.h>
+#include <grub/mm.h>
 
 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 +48,69 @@ grub_loader_is_loaded (void)
   return grub_loader_loaded;
 }
 
+/*Add a preboot function*/
+void *
+grub_loader_add_preboot (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 +141,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;
 }
 
 
diff --git a/include/grub/loader.h b/include/grub/loader.h
index 185d297..f701569 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);
 
+/* Add a preboot function */
+void *grub_loader_add_preboot (grub_err_t (*preboot_func) (int noreturn),
+			       grub_err_t (*preboot_rest_func) (void),
+			       int prio);
+
+/* Remove given preboot function */
+void grub_loader_remove_preboot (void *hnd);
+
 #endif /* ! GRUB_LOADER_HEADER */

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-04-27 16:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-04-10 23:48 [PATCH] Preboot support phcoder
2009-04-11 10:16 ` Yoshinori K. Okuji
2009-04-11 15:44   ` phcoder
2009-04-12 17:19     ` phcoder
2009-04-14 14:42       ` Yoshinori K. Okuji
2009-04-15  8:23         ` phcoder
2009-04-15  8:40           ` John Stanley
2009-04-26 14:38             ` Vladimir 'phcoder' Serbinenko
2009-04-27 16:49               ` Vladimir 'phcoder' Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.