From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A9608C433F5 for ; Fri, 1 Apr 2022 06:08:58 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2759E84241; Fri, 1 Apr 2022 08:08:56 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="LqPexqd4"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 2430F8425C; Fri, 1 Apr 2022 08:08:54 +0200 (CEST) Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CEC67839A1 for ; Fri, 1 Apr 2022 08:08:50 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ilias.apalodimas@linaro.org Received: by mail-wr1-x42b.google.com with SMTP id r13so2630215wrr.9 for ; Thu, 31 Mar 2022 23:08:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=RLLoRLzKPGmAIcdQ+kXavlTIAhqfkG6s2Utf6o+rYrg=; b=LqPexqd4M2OHPFpVv2iibBj37zVYA1ycfKmUen1JH/xpEMbSnXoE2vtFiGP6RLQqNy 7eHxzfOoHGwYpMeQZu/Zu/b4YDDvfvetADetzqow+PrtY8O0lnf1rsIzYgWnwHbdaV1E 9j933VBUoIx+X9WruBS0x3N8P88vUTbJCkMC/4rJkOl/+tQUa71SVSqM9HtfIGt0r10H ZQBorlwc+kNnfkzNSc2o47KdW8pmcXI96eLoNxYk+O3mPMg4hIBDY2V7txbSEG/JmnBy jWjETgmF+4QtKN7+/UlT50azApJ4s48PbstvX5vqQletlNbCoxB4H1UWTbJaNMk376kI W0bw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=RLLoRLzKPGmAIcdQ+kXavlTIAhqfkG6s2Utf6o+rYrg=; b=2xfhPXhBOX3JxGvQCVMzHT8ow3sboqcOIKGAAiC1TNBhzRvce+3o1f995c0A/P73hd uV/qUcmzWXR58o7KecwCDNizwPyGN+cVKY59izKL1p13ZmB9Qc+rRTGiFi5J7olIxZYH 5ISF9BCQjhkohQaNs+IcYrse5PYaM5+TvHaiUZcBj4RKgGEQj+LWyUP4RcLg2Rl6ve61 V+xal/WvVcybZm70Y4LLHS43jj8Gm/CHA0BDSNDG374xu4iWpijaKpfZTh+ekzNW5/j4 OPi9t7u4L7cbvP9IC85VwL6pfRxrh/hBVrAJRLb4Uyo34gYfD3R0EGdUFdBWm+cvCCqq avWQ== X-Gm-Message-State: AOAM532VTzoDkM+VyDYJMuW5T1O4FO0jp3O5cfSGQLD8jfLg3c/00SpS Ud0zXzw/oYpquVljPTDu7xXTMg== X-Google-Smtp-Source: ABdhPJya8OEV6429q9R8rRxqGU0VaaoOODsaPubc0CwMdo5+5Wlwf6JG4SVxSbsNt3iR+kA19cOfjw== X-Received: by 2002:adf:f78f:0:b0:205:dc9c:221c with SMTP id q15-20020adff78f000000b00205dc9c221cmr6454641wrp.178.1648793330381; Thu, 31 Mar 2022 23:08:50 -0700 (PDT) Received: from hades (athedsl-4461682.home.otenet.gr. [94.71.4.98]) by smtp.gmail.com with ESMTPSA id r65-20020a1c4444000000b0038c48dd23b9sm1421340wma.5.2022.03.31.23.08.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 31 Mar 2022 23:08:49 -0700 (PDT) Date: Fri, 1 Apr 2022 09:08:46 +0300 From: Ilias Apalodimas To: Masahisa Kojima Cc: u-boot@lists.denx.de, Heinrich Schuchardt , Simon Glass , Takahiro Akashi , Francois Ozog , Mark Kettenis , Peng Fan , Jaehoon Chung , Michal Simek , Kory Maincent , Aswath Govindraju , Ovidiu Panait , Ashok Reddy Soma , Franck LENORMAND Subject: Re: [PATCH v4 07/11] bootmenu: add UEFI and disto_boot entries Message-ID: References: <20220324135443.1571-1-masahisa.kojima@linaro.org> <20220324135443.1571-8-masahisa.kojima@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220324135443.1571-8-masahisa.kojima@linaro.org> X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Hi Kojima-san, [...] > + entry->title = u16_strdup(lo.label); > + if (!entry->title) { > + free(load_option); > + free(entry); We need to free bootorder as well > + return -ENOMEM; > + } > + entry->command = strdup("bootefi bootmgr"); > + sprintf(entry->key, "%d", i); > + entry->num = i; > + entry->menu = menu; > + entry->type = BOOTMENU_TYPE_UEFI_BOOT_OPTION; > + entry->bootorder = bootorder[j]; > + entry->next = NULL; > + > + if (!iter) > + menu->first = entry; > + else > + iter->next = entry; > + > + iter = entry; > + i++; > + } > + > + free(load_option); > + > + if (i == MAX_COUNT - 1) > + break; > + } > + > + free(bootorder); > + *index = i; > + *current = iter; > + > + return 1; > +} > + > +static int prepare_distro_boot_entry(struct bootmenu_data *menu, > + struct bootmenu_entry **current, > + unsigned short int *index) > +{ > + char *p; > + int len; > + char *token; > + char *boot_targets; > + unsigned short int i = *index; > + struct bootmenu_entry *entry = NULL; > + struct bootmenu_entry *iter = *current; > + > + /* list the distro boot "boot_targets" */ > + boot_targets = env_get("boot_targets"); > + if (!boot_targets) > + return -ENOENT; > + > + len = strlen(boot_targets); > + p = calloc(1, len + 1); > + strlcpy(p, boot_targets, len); > + > + token = strtok(p, " "); > + > + do { > + u16 *buf; > + char *command; > + int command_size; > + > + entry = malloc(sizeof(struct bootmenu_entry)); > + if (!entry) > + return -ENOMEM; > + > + len = strlen(token); > + buf = calloc(1, (len + 1) * sizeof(u16)); > + entry->title = buf; > + if (!entry->title) { > + free(entry); > + return -ENOMEM; > + } > + utf8_utf16_strncpy(&buf, token, len); > + sprintf(entry->key, "%d", i); > + entry->num = i; > + entry->menu = menu; > + > + command_size = sizeof("run bootcmd_") + len; > + command = calloc(1, command_size); > + if (!command) { > + free(entry->title); > + free(entry); > + return -ENOMEM; We need to free p as well > + } > + snprintf(command, command_size, "run bootcmd_%s", token); > + entry->command = command; > + entry->type = BOOTMENU_TYPE_DISTRO_BOOT; > entry->next = NULL; > > if (!iter) > @@ -341,10 +512,59 @@ static struct bootmenu_data *bootmenu_create(int delay) > iter->next = entry; > > iter = entry; > - ++i; > + i++; > > if (i == MAX_COUNT - 1) > break; > + > + token = strtok(NULL, " "); > + } while (token); > + > + free(p); > + *index = i; > + *current = iter; > + > + return 1; > +} > + > +static struct bootmenu_data *bootmenu_create(int delay) > +{ > + int ret; > + unsigned short int i = 0; > + struct bootmenu_data *menu; > + struct bootmenu_entry *iter = NULL; > + struct bootmenu_entry *entry; > + > + char *default_str; > + > + menu = malloc(sizeof(struct bootmenu_data)); > + if (!menu) > + return NULL; > + > + menu->delay = delay; > + menu->active = 0; > + menu->first = NULL; > + > + default_str = env_get("bootmenu_default"); > + if (default_str) > + menu->active = (int)simple_strtol(default_str, NULL, 10); > + > + ret = prepare_bootmenu_entry(menu, &iter, &i); > + if (ret < 0) > + goto cleanup; > + > + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { > + if (i < MAX_COUNT - 1) { > + ret = prepare_uefi_bootorder_entry(menu, &iter, &i); > + if (ret < 0 && ret != -ENOENT) > + goto cleanup; > + } > + } > + > + if (i < MAX_COUNT - 1) { > + ret = prepare_distro_boot_entry(menu, &iter, &i); > + if (ret < 0 && ret != -ENOENT) > + goto cleanup; > } > > /* Add U-Boot console entry at the end */ > @@ -353,7 +573,12 @@ static struct bootmenu_data *bootmenu_create(int delay) > if (!entry) > goto cleanup; > > - entry->title = strdup("U-Boot console"); > + /* Add dummy entry if entering U-Boot console is disabled */ > + if (IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE)) > + entry->title = u16_strdup(u"U-Boot console"); > + else > + entry->title = u16_strdup(u""); > + > if (!entry->title) { > free(entry); > goto cleanup; > @@ -370,6 +595,7 @@ static struct bootmenu_data *bootmenu_create(int delay) > > entry->num = i; > entry->menu = menu; > + entry->type = BOOTMENU_TYPE_NONE; > entry->next = NULL; > > if (!iter) > @@ -378,7 +604,7 @@ static struct bootmenu_data *bootmenu_create(int delay) > iter->next = entry; > > iter = entry; > - ++i; > + i++; > } > > menu->count = i; > @@ -423,43 +649,73 @@ static void menu_display_statusline(struct menu *m) > puts(ANSI_CLEAR_LINE); > } > > -static void bootmenu_show(int delay) > +static void handle_uefi_bootnext(void) > { > + u16 bootnext; > + efi_status_t ret; > + efi_uintn_t size; > + > + /* Initialize EFI drivers */ > + ret = efi_init_obj_list(); > + if (ret != EFI_SUCCESS) { > + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", > + ret & ~EFI_ERROR_MASK); > + > + return; > + } > + > + /* If UEFI BootNext variable is set, boot the BootNext load option */ > + size = sizeof(u16); > + ret = efi_get_variable_int(u"BootNext", > + &efi_global_variable_guid, > + NULL, &size, &bootnext, NULL); > + if (ret == EFI_SUCCESS) > + /* BootNext does exist here, try to boot */ > + run_command("bootefi bootmgr", 0); > +} > + > +static enum bootmenu_ret bootmenu_show(int delay) > +{ > + int cmd_ret; > int init = 0; > void *choice = NULL; > - char *title = NULL; > + u16 *title = NULL; > char *command = NULL; > struct menu *menu; > struct bootmenu_data *bootmenu; > struct bootmenu_entry *iter; > + efi_status_t efi_ret = EFI_SUCCESS; > char *option, *sep; > > + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) > + handle_uefi_bootnext(); > + > /* If delay is 0 do not create menu, just run first entry */ > if (delay == 0) { > option = bootmenu_getoption(0); > if (!option) { > puts("bootmenu option 0 was not found\n"); > - return; > + return BOOTMENU_RET_FAIL; > } > sep = strchr(option, '='); > if (!sep) { > puts("bootmenu option 0 is invalid\n"); > - return; > + return BOOTMENU_RET_FAIL; > } > - run_command(sep+1, 0); > - return; > + cmd_ret = run_command(sep + 1, 0); > + return (cmd_ret == CMD_RET_SUCCESS ? BOOTMENU_RET_SUCCESS : BOOTMENU_RET_FAIL); > } > > bootmenu = bootmenu_create(delay); > if (!bootmenu) > - return; > + return BOOTMENU_RET_FAIL; > > menu = menu_create(NULL, bootmenu->delay, 1, menu_display_statusline, > bootmenu_print_entry, bootmenu_choice_entry, > bootmenu); > if (!menu) { > bootmenu_destroy(bootmenu); > - return; > + return BOOTMENU_RET_FAIL; > } > > for (iter = bootmenu->first; iter; iter = iter->next) { > @@ -478,8 +734,33 @@ static void bootmenu_show(int delay) > > if (menu_get_choice(menu, &choice) == 1) { > iter = choice; > - title = strdup(iter->title); > + /* last entry is U-Boot console or Quit */ > + if (iter->num == iter->menu->count - 1) { > + menu_destroy(menu); > + bootmenu_destroy(bootmenu); > + return BOOTMENU_RET_QUIT; > + } > + > + title = u16_strdup(iter->title); > command = strdup(iter->command); > + } else { > + goto cleanup; > + } > + > + /* > + * If the selected entry is UEFI BOOT####, set the BootNext variable. > + * Then uefi bootmgr is invoked by the preset command in iter->command. > + */ > + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) { > + if (iter->type == BOOTMENU_TYPE_UEFI_BOOT_OPTION) { > + efi_ret = efi_set_variable_int(u"BootNext", &efi_global_variable_guid, > + EFI_VARIABLE_NON_VOLATILE | > + EFI_VARIABLE_BOOTSERVICE_ACCESS | > + EFI_VARIABLE_RUNTIME_ACCESS, > + sizeof(u16), &iter->bootorder, false); > + if (efi_ret != EFI_SUCCESS) > + goto cleanup; > + } > } > > cleanup: > @@ -493,21 +774,47 @@ cleanup: > } > > if (title && command) { > - debug("Starting entry '%s'\n", title); > + debug("Starting entry '%ls'\n", title); > free(title); > - run_command(command, 0); > + if (efi_ret == EFI_SUCCESS) > + cmd_ret = run_command(command, 0); > free(command); > } > > #ifdef CONFIG_POSTBOOTMENU > run_command(CONFIG_POSTBOOTMENU, 0); > #endif > + > + if (efi_ret == EFI_SUCCESS && cmd_ret == CMD_RET_SUCCESS) > + return BOOTMENU_RET_SUCCESS; > + > + return BOOTMENU_RET_FAIL; > } > > #ifdef CONFIG_AUTOBOOT_MENU_SHOW > int menu_show(int bootdelay) > { > - bootmenu_show(bootdelay); > + int ret; > + > + while (1) { > + ret = bootmenu_show(bootdelay); > + bootdelay = -1; > + if (ret == BOOTMENU_RET_UPDATED) > + continue; > + > + if (!IS_ENABLED(CONFIG_CMD_BOOTMENU_ENTER_UBOOT_CONSOLE)) { > + if (ret == BOOTMENU_RET_QUIT) { > + /* default boot process */ > + if (IS_ENABLED(CONFIG_CMD_BOOTEFI_BOOTMGR)) > + run_command("bootefi bootmgr", 0); > + > + run_command("run bootcmd", 0); > + } > + } else { > + break; > + } > + } > + > return -1; /* -1 - abort boot and run monitor code */ > } > #endif > -- > 2.17.1 > Thanks /Ilias