grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2] Initial module to interact with the android bcb.


From: Shea Levy
Subject: [PATCH v2] Initial module to interact with the android bcb.
Date: Mon, 8 Feb 2016 15:50:17 -0500

Android uses a dedicated partition or mtd to handle communication
between the bootloader and the recovery system, which handles system
and firmware updates as well as factory resets. This is known as the
bootloader control block, or "bcb".

The current form of the module allows the user to specify which
partition should be used as the bcb, as well as reading the 'command'
field of the message via the android_bcb_command env var. During a
recovery operation, the recovery system populates the command field and
only clears it once the operation is done, with the intended semantics
being that the system reboots into recovery mode if the operation is
interrupted. Thus, a grub configuration can check to see if
android_bcb_command non-empty, and if so boot into recovery.

Future versions may give access to other fields, or allow write access.
---
 grub-core/Makefile.core.def     |   5 ++
 grub-core/android/android_bcb.c | 104 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+)
 create mode 100644 grub-core/android/android_bcb.c

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 0cc40bb..b045ea4 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2327,3 +2327,8 @@ module = {
   common = loader/i386/xen_file64.c;
   extra_dist = loader/i386/xen_fileXX.c;
 };
+
+module = {
+  name = android_bcb;
+  common = android/android_bcb.c;
+};
diff --git a/grub-core/android/android_bcb.c b/grub-core/android/android_bcb.c
new file mode 100644
index 0000000..1841bba
--- /dev/null
+++ b/grub-core/android/android_bcb.c
@@ -0,0 +1,104 @@
+/* android_bcb.c - module for interacting with the android bootloader control 
block */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2016  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/env.h>
+#include <grub/disk.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+/* Definition of struct bootloader message from 
https://android.googlesource.com/platform/bootable/recovery/+/9d72d4175b06a70c64c8867ff65b3c4c2181c9a9/bootloader.h#20
+ * Available under the following copyright and terms:
+ *
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+struct bootloader_message
+{
+  char command[32];
+  char status[32];
+  char recovery[768];
+  // The 'recovery' field used to be 1024 bytes.  It has only ever
+  // been used to store the recovery command line, so 768 bytes
+  // should be plenty.  We carve off the last 256 bytes to store the
+  // stage string (for multistage packages) and possible future
+  // expansion.
+  char stage[32];
+  char slot_suffix[32];
+  char reserved[192];
+} GRUB_PACKED;
+
+static grub_err_t read_message (const char *name) {
+  grub_disk_t disk = grub_disk_open (name);
+  if (disk)
+    {
+      struct bootloader_message msg;
+      grub_err_t err = grub_disk_read (disk, 0, 0, sizeof msg, &msg);
+      if (!err)
+        {
+          /* struct bootloader_message has no magic number or other 
identifier! */
+          if (!grub_memchr (msg.command, '\0', sizeof msg.command))
+            err = grub_error (GRUB_ERR_BAD_FS,
+                              N_("%s doesn't contain a valid bcb"), name);
+          else
+            grub_env_set ("android_bcb_command", msg.command);
+        }
+
+      grub_disk_close (disk);
+
+      return err;
+    }
+  else
+    return grub_errno;
+}
+
+static char *handle_write (struct grub_env_var *var __attribute__ ((unused)),
+                           const char *val)
+{
+  if (read_message (val))
+    grub_print_error ();
+
+  return grub_strdup (val);
+}
+
+GRUB_MOD_INIT(android_bcb)
+{
+  const char *disk_path = grub_env_get ("android_bcb_disk");
+  if (disk_path && read_message (disk_path))
+    grub_print_error ();
+
+  if (!grub_register_variable_hook ("android_bcb_disk", 0, handle_write))
+    grub_print_error ();
+}
+
+GRUB_MOD_FINI(android_bcb)
+{
+  grub_register_variable_hook ("android_bcb_disk", 0, 0);
+}
-- 
2.7.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]