diff options
author | David Zeuthen <zeuthen@google.com> | 2015-08-31 17:55:33 -0400 |
---|---|---|
committer | David Zeuthen <zeuthen@google.com> | 2015-08-31 17:55:33 -0400 |
commit | 9a854761276a004d1ea3ea597151b62b2e444aef (patch) | |
tree | bd0d3c25a3c232ddb8cfaf1db6b72a2e824aa7e6 /bootctl | |
parent | 44df7549d622456c3f18e371ec57dbf585a68a1b (diff) | |
download | extras-9a854761276a004d1ea3ea597151b62b2e444aef.tar.gz |
bootctl: Command-line wrapper for boot_control HAL.
Change-Id: Icd7bfee8fcc04ca113c2e6dc8bcefd614e804bb6
Diffstat (limited to 'bootctl')
-rw-r--r-- | bootctl/Android.mk | 12 | ||||
-rw-r--r-- | bootctl/bootctl.c | 185 |
2 files changed, 197 insertions, 0 deletions
diff --git a/bootctl/Android.mk b/bootctl/Android.mk new file mode 100644 index 00000000..f0f5a067 --- /dev/null +++ b/bootctl/Android.mk @@ -0,0 +1,12 @@ +# Copyright 2015 The Android Open Source Project + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := bootctl.c +LOCAL_SHARED_LIBRARIES := libhardware +LOCAL_MODULE := bootctl +LOCAL_C_INCLUDES = hardware/libhardware/include +LOCAL_CFLAGS := -Wno-unused-parameter + +include $(BUILD_EXECUTABLE) diff --git a/bootctl/bootctl.c b/bootctl/bootctl.c new file mode 100644 index 00000000..8e0125c4 --- /dev/null +++ b/bootctl/bootctl.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2015 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. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sysexits.h> + +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <hardware/hardware.h> +#include <hardware/boot_control.h> + +static void usage(FILE* where, int argc, char* argv[]) +{ + fprintf(where, + "%s - command-line wrapper for the boot_control HAL.\n" + "\n" + "Usage:\n" + " %s COMMAND\n" + "\n" + "Commands:\n" + " %s hal-info - Show info about boot_control HAL used.\n" + " %s get-number-slots - Prints number of slots.\n" + " %s get-current-slot - Prints currently running SLOT.\n" + " %s mark-boot-successful - Mark current slot as GOOD.\n" + " %s set-active-boot-slot SLOT - On next boot, load and execute SLOT.\n" + " %s set-slot-as-unbootable SLOT - Mark SLOT as invalid.\n" + " %s is-slot-bootable SLOT - Returns 0 only if SLOT is bootable.\n" + " %s get-suffix SLOT - Prints suffix for SLOT.\n" + "\n" + "SLOT parameter is the zero-based slot-number.\n", + argv[0], argv[0], argv[0], argv[0], argv[0], + argv[0], argv[0], argv[0], argv[0], argv[0]); +} + +static int do_hal_info(const hw_module_t *hw_module) +{ + fprintf(stdout, + "HAL name: %s\n" + "HAL author: %s\n" + "HAL module version: %d.%d\n", + hw_module->name, + hw_module->author, + hw_module->module_api_version>>8, + hw_module->module_api_version&0xff); + return EX_OK; +} + +static int do_get_number_slots(boot_control_module_t *module) +{ + int num_slots = module->getNumberSlots(module); + fprintf(stdout, "%d\n", num_slots); + return EX_OK; +} + +static int do_get_current_slot(boot_control_module_t *module) +{ + int cur_slot = module->getCurrentSlot(module); + fprintf(stdout, "%d\n", cur_slot); + return EX_OK; +} + +static int do_mark_boot_successful(boot_control_module_t *module) +{ + int ret = module->markBootSuccessful(module); + if (ret == 0) + return EX_OK; + fprintf(stderr, "Error marking as having booted successfully: %s\n", + strerror(-ret)); + return EX_SOFTWARE; +} + +static int do_set_active_boot_slot(boot_control_module_t *module, + int slot_number) +{ + int ret = module->setActiveBootSlot(module, slot_number); + if (ret == 0) + return EX_OK; + fprintf(stderr, "Error setting active boot slot: %s\n", strerror(-ret)); + return EX_SOFTWARE; +} + +static int do_set_slot_as_unbootable(boot_control_module_t *module, + int slot_number) +{ + int ret = module->setSlotAsUnbootable(module, slot_number); + if (ret == 0) + return EX_OK; + fprintf(stderr, "Error setting slot as unbootable: %s\n", strerror(-ret)); + return EX_SOFTWARE; +} + + +static int do_is_slot_bootable(boot_control_module_t *module, int slot_number) +{ + int ret = module->isSlotBootable(module, slot_number); + if (ret == 0) + return EX_SOFTWARE; + return EX_OK; +} + + +static int do_get_suffix(boot_control_module_t *module, int slot_number) +{ + const char* suffix = module->getSuffix(module, slot_number); + fprintf(stdout, "%s\n", suffix); + return EX_OK; +} + +static int parse_slot(int pos, int argc, char *argv[]) +{ + if (pos > argc - 1) { + usage(stderr, argc, argv); + exit(EX_USAGE); + return -1; + } + int ret = strtol(argv[pos], NULL, 10); + if (ret == LONG_MIN || ret == LONG_MAX) { + usage(stderr, argc, argv); + exit(EX_USAGE); + return -1; + } + return ret; +} + +int main(int argc, char *argv[]) +{ + const hw_module_t *hw_module; + boot_control_module_t *module; + int ret; + + ret = hw_get_module("bootctrl", &hw_module); + if (ret != 0) { + fprintf(stderr, "Error getting bootctrl module.\n"); + return EX_SOFTWARE; + } + module = (boot_control_module_t*) hw_module; + module->init(module); + + if (argc < 2) { + usage(stderr, argc, argv); + return EX_USAGE; + } + + if (strcmp(argv[1], "hal-info") == 0) { + return do_hal_info(hw_module); + } else if (strcmp(argv[1], "get-number-slots") == 0) { + return do_get_number_slots(module); + } else if (strcmp(argv[1], "get-current-slot") == 0) { + return do_get_current_slot(module); + } else if (strcmp(argv[1], "mark-boot-successful") == 0) { + return do_mark_boot_successful(module); + } else if (strcmp(argv[1], "set-active-boot-slot") == 0) { + return do_set_active_boot_slot(module, parse_slot(2, argc, argv)); + } else if (strcmp(argv[1], "set-slot-as-unbootable") == 0) { + return do_set_slot_as_unbootable(module, parse_slot(2, argc, argv)); + } else if (strcmp(argv[1], "is-slot-bootable") == 0) { + return do_is_slot_bootable(module, parse_slot(2, argc, argv)); + } else if (strcmp(argv[1], "get-suffix") == 0) { + return do_get_suffix(module, parse_slot(2, argc, argv)); + } else { + usage(stderr, argc, argv); + return EX_USAGE; + } + + return 0; +} |