From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1aQ5wQ-0003xp-Hx for mharc-grub-devel@gnu.org; Sun, 31 Jan 2016 23:18:18 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36250) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQ5wM-0003xR-SI for grub-devel@gnu.org; Sun, 31 Jan 2016 23:18:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aQ5wJ-00047W-Fb for grub-devel@gnu.org; Sun, 31 Jan 2016 23:18:14 -0500 Received: from mail-lf0-x22f.google.com ([2a00:1450:4010:c07::22f]:33254) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aQ5wJ-00047S-1f for grub-devel@gnu.org; Sun, 31 Jan 2016 23:18:11 -0500 Received: by mail-lf0-x22f.google.com with SMTP id m1so12921278lfg.0 for ; Sun, 31 Jan 2016 20:18:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=v7g7NLmHPZwWD4/lTr7T+zaxFXBYzH/GhY9vxlLUkyc=; b=NrXpLJF4fO0jOzsN1WiYlhLdasIAwR3KXldYDMN0jFwlx3WMLtGbH2Ps5KAnBxbF+3 rzoR7+hKeNfga5KIzXPnh7b+g/Ucq2deuuuHO4yr/di/ABClmyNKIAyqGYsJlIjfv+r2 I+f4++6wnv6DbfVci6wGAmAokVlQg0Forw7MFMh95epUVqsBR7h+xXFnSrU6haTufLb1 YhL1asJnJZqetglwO4eHxU1Z2jAsm8cG6x0h3BpLU1Ai6EnG0QJaJxzL9lnwCaDQzf1B jELbxYY12QhuhNOYprluAibU/DrttN8md5TNK2kXll9fDAOPqEVHWHDEJOB9RDZPQ7TH 3OpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=v7g7NLmHPZwWD4/lTr7T+zaxFXBYzH/GhY9vxlLUkyc=; b=AaU2//74JIlOjq5tb9JM3+vN8KtAPYDASxnqhRo50kruX940WUAQ5Pc3NVdeyWTlaE xQUK8xLOrAQp0hMwWRFgMwUdX4NERpxcnMU1w2BTJe8R1u5eQcuQdzk/4HG7ckd71gE4 NpEHHZzZShZEbNCy1NmpUqbAhipL7xQK+EGIlF2I1TJCC3jdI8OR7GEtQDYOWsBXxInE 6OSW3Pgny3sUND+m/32fu36OSvOEZG49vp8g8/fZl/7buvSIhwCB5k8k5WFDmaX/3amJ 8RSxwBa4dslUHI/4zfArt7sAqoFTs7T7sTzWZPWSqehCZ6S6WD4CWEzu6klhvf2C56WE lsXQ== X-Gm-Message-State: AG10YOQu4TKEa7KMdqsZWrCj+HSIPmoONtMi2FxDFzzyby9b1w41lRwc2tAG7Tu14RG7Bg== X-Received: by 10.25.149.21 with SMTP id x21mr7690279lfd.124.1454300290162; Sun, 31 Jan 2016 20:18:10 -0800 (PST) Received: from [192.168.1.41] (ppp109-252-76-159.pppoe.spdop.ru. [109.252.76.159]) by smtp.gmail.com with ESMTPSA id b5sm3634940lbc.14.2016.01.31.20.18.08 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 31 Jan 2016 20:18:09 -0800 (PST) Subject: Re: [PATCH] Add module for interacting with the android bootloader control block To: The development of GNU GRUB , Vladimir 'phcoder' Serbinenko References: <1454281263-19141-1-git-send-email-shea@shealevy.com> From: Andrei Borzenkov X-Enigmail-Draft-Status: N1110 Message-ID: <56AEDC80.7020301@gmail.com> Date: Mon, 1 Feb 2016 07:18:08 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:4010:c07::22f X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Feb 2016 04:18:16 -0000 01.02.2016 02:55, Shea Levy пишет: > > > Android systems use a so-called "bootloader control block" to > coordinate between the bootloader and the recovery system (which handles > factory resets, system updates, firmware updates, etc.). The BCB is > traditionally either an MTD device or an eMMC partition, and it contains > a struct bootloader_message directly on the device/partition. The > recovery system will write a message into the control block, which the > bootloader is then meant to check to see if it should boot into recovery > mode or normal mode (the idea being that the control block is only > cleared once recovery is finished, ensuring fault-tolerance; if the > device is powered off mid-update, it will boot back into the same > recovery mode). > > This module exports the bcb fields as env variables. > First the user sets android_bcb_disk to the partition containing the BCB > (I don't know how to support MTDs yet but I only deal with x86). Then > variables such as android_bcb_command and android_bcb_recovery can be > checked and used to determine which mode to boot into. They can also, if > necessary, be modified by setting the variables in question. The typical > use case will probably be to check if there is a recovery command > present and if so boot into recovery mode. > > Does that explain enough? > How these variables are intended to be used? Could you provide example of actual values in this block and example of grub code using them? How BCB area is identified? Your code allows writing to arbitrary device without any sanity check. Is bootloader even *allowed* to make any choice here to remain compliant? I.e. can bootloader ignore request stored in BCB? > > 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 > 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 > . >>> + */ >>> + >>> +#include > >>> + >>> +#include >>> +#include >>> > +#include >>> + >>> +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 >>> Grub-devel@gnu.org >>> > 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 > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel >