Thanks,
Shea
On 2016-01-31 18:41, Vladimir 'phcoder' Serbinenko
wrote:
Sorry but I don't quite understand what this module is for.
Can you please give an example of how it's used both in original
context
and in GRUB. I have couple of style comments as well but clarifying
the
usecase first is important.
Le lun. 1 févr. 2016 00:01, Shea Levy
<address@hidden> a écrit :
---
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/ [1]>.
+ */
+
+#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
[2]
+ * 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 [3]
+ *
+ * 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] =
'';
+ 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] = '';
+
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
_______________________________________________
Grub-devel mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/grub-devel [4]
Links:
------
[1] http://www.gnu.org/licenses/
[2]
https://android.googlesource.com/platform/bootable/recovery/+/9d72d4175b06a70c64c8867ff65b3c4c2181c9a9/bootloader.h#20
[3]
http://www.apache.org/licenses/LICENSE-2.0
[4]
https://lists.gnu.org/mailman/listinfo/grub-devel
_______________________________________________
Grub-devel mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/grub-devel