[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Add module for interacting with the android bootloader control b
From: |
Shea Levy |
Subject: |
[PATCH] Add module for interacting with the android bootloader control block |
Date: |
Sun, 31 Jan 2016 18:01:03 -0500 |
---
grub-core/Makefile.core.def | 5 ++
grub-core/android/android_bcb.c | 163 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 168 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..db49446
--- /dev/null
+++ b/grub-core/android/android_bcb.c
@@ -0,0 +1,163 @@
+/* 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 <stddef.h>
+
+#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;
+
+struct bcb_state
+{
+ grub_disk_t disk;
+ char internal_write;
+ struct bootloader_message msg;
+};
+
+static struct bcb_state state = { 0 };
+
+#define SET_FIELD(field) \
+ state.msg. field[sizeof state.msg. field - 1] = '\0'; \
+ grub_env_set ("android_bcb_" #field, state.msg. field)
+
+static void open_disk (const char *name) {
+ if (state.disk) {
+ grub_disk_close (state.disk);
+ }
+
+ state.disk = grub_disk_open (name);
+ if (state.disk) {
+ grub_err_t err = grub_disk_read (state.disk, 0, 0, sizeof state.msg,
+ &state.msg);
+ if (err) {
+ grub_disk_close (state.disk);
+ state.disk = 0;
+ } else {
+ state.internal_write = 1;
+ SET_FIELD (command);
+ SET_FIELD (status);
+ SET_FIELD (recovery);
+ SET_FIELD (stage);
+ SET_FIELD (slot_suffix);
+ state.internal_write = 0;
+ }
+ }
+}
+
+#define MAYBE_UPDATE_FIELD(field) \
+ do { if (!grub_strcmp (var->name, "android_bcb_" #field)) \
+ { \
+ grub_memcpy (state.msg. field, val, sizeof state.msg. field - 1); \
+ state.msg. field[sizeof state.msg. field - 1] = '\0'; \
+ grub_disk_write (state.disk, 0, \
+ offsetof (struct bootloader_message, field), \
+ sizeof state.msg. field, state.msg. field); \
+ } } while (0)
+
+static char *handle_write (struct grub_env_var *var,
+ const char *val)
+{
+ if (!grub_strcmp (var->name, "android_bcb_disk"))
+ {
+ open_disk (val);
+ if (!state.disk)
+ grub_print_error ();
+ }
+ else if (state.disk && !state.internal_write)
+ {
+ MAYBE_UPDATE_FIELD (command);
+ MAYBE_UPDATE_FIELD (status);
+ MAYBE_UPDATE_FIELD (recovery);
+ MAYBE_UPDATE_FIELD (stage);
+ MAYBE_UPDATE_FIELD (slot_suffix);
+ }
+
+ return grub_strdup (val);
+}
+
+GRUB_MOD_INIT(android_bcb)
+{
+ const char *disk = grub_env_get ("android_bcb_disk");
+ if (disk)
+ {
+ open_disk (disk);
+ if (!state.disk)
+ grub_print_error ();
+ }
+
+ if (!grub_register_variable_hook ("android_bcb_disk", 0, handle_write))
+ grub_print_error ();
+ if (grub_register_variable_hook ("android_bcb_command", 0, handle_write))
+ grub_print_error ();
+ if (grub_register_variable_hook ("android_bcb_status", 0, handle_write))
+ grub_print_error ();
+ if (grub_register_variable_hook ("android_bcb_recovery", 0, handle_write))
+ grub_print_error ();
+ if (grub_register_variable_hook ("android_bcb_stage", 0, handle_write))
+ grub_print_error ();
+ if (grub_register_variable_hook ("android_bcb_slot_suffix", 0, handle_write))
+ grub_print_error ();
+}
+
+GRUB_MOD_FINI(android_bcb)
+{
+ grub_register_variable_hook ("android_bcb_disk", 0, 0);
+ grub_register_variable_hook ("android_bcb_command", 0, 0);
+ grub_register_variable_hook ("android_bcb_status", 0, 0);
+ grub_register_variable_hook ("android_bcb_recovery", 0, 0);
+ grub_register_variable_hook ("android_bcb_stage", 0, 0);
+ grub_register_variable_hook ("android_bcb_slot_suffix", 0, 0);
+
+ if (state.disk)
+ grub_disk_close (state.disk);
+}
--
2.7.0
- [PATCH] Add module for interacting with the android bootloader control block,
Shea Levy <=