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 <s...@shealevy.com> 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/>.
> + */
> +
> +#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
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to