bootmenu: update bootmenu_entry structure
This is a preparation for succeeding addition of uefi boot and distro boot menu entries into bootmenu. The bootmenu_entry title is updated to u16 string because uefi use u16 string. This commit also factors out the function to prepare the entries generated by "bootmenu_x" U-Boot environment variable. Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org> Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
This commit is contained in:
		
							parent
							
								
									4e65ca00f3
								
							
						
					
					
						commit
						a3d0aa87ac
					
				|  | @ -353,6 +353,7 @@ source lib/efi_selftest/Kconfig | ||||||
| config CMD_BOOTMENU | config CMD_BOOTMENU | ||||||
| 	bool "bootmenu" | 	bool "bootmenu" | ||||||
| 	select MENU | 	select MENU | ||||||
|  | 	select CHARSET | ||||||
| 	help | 	help | ||||||
| 	  Add an ANSI terminal boot menu command. | 	  Add an ANSI terminal boot menu command. | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										107
									
								
								cmd/bootmenu.c
								
								
								
								
							
							
						
						
									
										107
									
								
								cmd/bootmenu.c
								
								
								
								
							|  | @ -3,6 +3,7 @@ | ||||||
|  * (C) Copyright 2011-2013 Pali Rohár <pali@kernel.org> |  * (C) Copyright 2011-2013 Pali Rohár <pali@kernel.org> | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <charset.h> | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <command.h> | #include <command.h> | ||||||
| #include <ansi.h> | #include <ansi.h> | ||||||
|  | @ -24,11 +25,18 @@ | ||||||
|  */ |  */ | ||||||
| #define MAX_ENV_SIZE	(9 + 2 + 1) | #define MAX_ENV_SIZE	(9 + 2 + 1) | ||||||
| 
 | 
 | ||||||
|  | enum boot_type { | ||||||
|  | 	BOOTMENU_TYPE_NONE = 0, | ||||||
|  | 	BOOTMENU_TYPE_BOOTMENU, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| struct bootmenu_entry { | struct bootmenu_entry { | ||||||
| 	unsigned short int num;		/* unique number 0 .. MAX_COUNT */ | 	unsigned short int num;		/* unique number 0 .. MAX_COUNT */ | ||||||
| 	char key[3];			/* key identifier of number */ | 	char key[3];			/* key identifier of number */ | ||||||
| 	char *title;			/* title of entry */ | 	u16 *title;			/* title of entry */ | ||||||
| 	char *command;			/* hush command of entry */ | 	char *command;			/* hush command of entry */ | ||||||
|  | 	enum boot_type type;		/* boot type of entry */ | ||||||
|  | 	u16 bootorder;			/* order for each boot type */ | ||||||
| 	struct bootmenu_data *menu;	/* this bootmenu */ | 	struct bootmenu_data *menu;	/* this bootmenu */ | ||||||
| 	struct bootmenu_entry *next;	/* next menu entry (num+1) */ | 	struct bootmenu_entry *next;	/* next menu entry (num+1) */ | ||||||
| }; | }; | ||||||
|  | @ -73,7 +81,7 @@ static void bootmenu_print_entry(void *data) | ||||||
| 	if (reverse) | 	if (reverse) | ||||||
| 		puts(ANSI_COLOR_REVERSE); | 		puts(ANSI_COLOR_REVERSE); | ||||||
| 
 | 
 | ||||||
| 	puts(entry->title); | 	printf("%ls", entry->title); | ||||||
| 
 | 
 | ||||||
| 	if (reverse) | 	if (reverse) | ||||||
| 		puts(ANSI_COLOR_RESET); | 		puts(ANSI_COLOR_RESET); | ||||||
|  | @ -269,31 +277,32 @@ static void bootmenu_destroy(struct bootmenu_data *menu) | ||||||
| 	free(menu); | 	free(menu); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static struct bootmenu_data *bootmenu_create(int delay) | /**
 | ||||||
|  |  * prepare_bootmenu_entry() - generate the bootmenu_xx entries | ||||||
|  |  * | ||||||
|  |  * This function read the "bootmenu_x" U-Boot environment variable | ||||||
|  |  * and generate the bootmenu entries. | ||||||
|  |  * | ||||||
|  |  * @menu:	pointer to the bootmenu structure | ||||||
|  |  * @current:	pointer to the last bootmenu entry list | ||||||
|  |  * @index:	pointer to the index of the last bootmenu entry, | ||||||
|  |  *		the number of bootmenu entry is added by this function | ||||||
|  |  * Return:	1 on success, negative value on error | ||||||
|  |  */ | ||||||
|  | static int prepare_bootmenu_entry(struct bootmenu_data *menu, | ||||||
|  | 				  struct bootmenu_entry **current, | ||||||
|  | 				  unsigned short int *index) | ||||||
| { | { | ||||||
| 	unsigned short int i = 0; |  | ||||||
| 	const char *option; |  | ||||||
| 	struct bootmenu_data *menu; |  | ||||||
| 	struct bootmenu_entry *iter = NULL; |  | ||||||
| 
 |  | ||||||
| 	int len; | 	int len; | ||||||
| 	char *sep; | 	char *sep; | ||||||
| 	char *default_str; | 	const char *option; | ||||||
| 	struct bootmenu_entry *entry; | 	unsigned short int i = *index; | ||||||
| 
 | 	struct bootmenu_entry *entry = NULL; | ||||||
| 	menu = malloc(sizeof(struct bootmenu_data)); | 	struct bootmenu_entry *iter = *current; | ||||||
| 	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); |  | ||||||
| 
 | 
 | ||||||
| 	while ((option = bootmenu_getoption(i))) { | 	while ((option = bootmenu_getoption(i))) { | ||||||
|  | 		u16 *buf; | ||||||
|  | 
 | ||||||
| 		sep = strchr(option, '='); | 		sep = strchr(option, '='); | ||||||
| 		if (!sep) { | 		if (!sep) { | ||||||
| 			printf("Invalid bootmenu entry: %s\n", option); | 			printf("Invalid bootmenu entry: %s\n", option); | ||||||
|  | @ -302,23 +311,23 @@ static struct bootmenu_data *bootmenu_create(int delay) | ||||||
| 
 | 
 | ||||||
| 		entry = malloc(sizeof(struct bootmenu_entry)); | 		entry = malloc(sizeof(struct bootmenu_entry)); | ||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 			goto cleanup; | 			return -ENOMEM; | ||||||
| 
 | 
 | ||||||
| 		len = sep-option; | 		len = sep-option; | ||||||
| 		entry->title = malloc(len + 1); | 		buf = calloc(1, (len + 1) * sizeof(u16)); | ||||||
|  | 		entry->title = buf; | ||||||
| 		if (!entry->title) { | 		if (!entry->title) { | ||||||
| 			free(entry); | 			free(entry); | ||||||
| 			goto cleanup; | 			return -ENOMEM; | ||||||
| 		} | 		} | ||||||
| 		memcpy(entry->title, option, len); | 		utf8_utf16_strncpy(&buf, option, len); | ||||||
| 		entry->title[len] = 0; |  | ||||||
| 
 | 
 | ||||||
| 		len = strlen(sep + 1); | 		len = strlen(sep + 1); | ||||||
| 		entry->command = malloc(len + 1); | 		entry->command = malloc(len + 1); | ||||||
| 		if (!entry->command) { | 		if (!entry->command) { | ||||||
| 			free(entry->title); | 			free(entry->title); | ||||||
| 			free(entry); | 			free(entry); | ||||||
| 			goto cleanup; | 			return -ENOMEM; | ||||||
| 		} | 		} | ||||||
| 		memcpy(entry->command, sep + 1, len); | 		memcpy(entry->command, sep + 1, len); | ||||||
| 		entry->command[len] = 0; | 		entry->command[len] = 0; | ||||||
|  | @ -327,6 +336,8 @@ static struct bootmenu_data *bootmenu_create(int delay) | ||||||
| 
 | 
 | ||||||
| 		entry->num = i; | 		entry->num = i; | ||||||
| 		entry->menu = menu; | 		entry->menu = menu; | ||||||
|  | 		entry->type = BOOTMENU_TYPE_BOOTMENU; | ||||||
|  | 		entry->bootorder = i; | ||||||
| 		entry->next = NULL; | 		entry->next = NULL; | ||||||
| 
 | 
 | ||||||
| 		if (!iter) | 		if (!iter) | ||||||
|  | @ -341,13 +352,44 @@ static struct bootmenu_data *bootmenu_create(int delay) | ||||||
| 			break; | 			break; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	*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; | ||||||
|  | 
 | ||||||
| 	/* Add U-Boot console entry at the end */ | 	/* Add U-Boot console entry at the end */ | ||||||
| 	if (i <= MAX_COUNT - 1) { | 	if (i <= MAX_COUNT - 1) { | ||||||
| 		entry = malloc(sizeof(struct bootmenu_entry)); | 		entry = malloc(sizeof(struct bootmenu_entry)); | ||||||
| 		if (!entry) | 		if (!entry) | ||||||
| 			goto cleanup; | 			goto cleanup; | ||||||
| 
 | 
 | ||||||
| 		entry->title = strdup("U-Boot console"); | 		entry->title = u16_strdup(u"U-Boot console"); | ||||||
| 		if (!entry->title) { | 		if (!entry->title) { | ||||||
| 			free(entry); | 			free(entry); | ||||||
| 			goto cleanup; | 			goto cleanup; | ||||||
|  | @ -364,6 +406,7 @@ static struct bootmenu_data *bootmenu_create(int delay) | ||||||
| 
 | 
 | ||||||
| 		entry->num = i; | 		entry->num = i; | ||||||
| 		entry->menu = menu; | 		entry->menu = menu; | ||||||
|  | 		entry->type = BOOTMENU_TYPE_NONE; | ||||||
| 		entry->next = NULL; | 		entry->next = NULL; | ||||||
| 
 | 
 | ||||||
| 		if (!iter) | 		if (!iter) | ||||||
|  | @ -421,7 +464,7 @@ static void bootmenu_show(int delay) | ||||||
| { | { | ||||||
| 	int init = 0; | 	int init = 0; | ||||||
| 	void *choice = NULL; | 	void *choice = NULL; | ||||||
| 	char *title = NULL; | 	u16 *title = NULL; | ||||||
| 	char *command = NULL; | 	char *command = NULL; | ||||||
| 	struct menu *menu; | 	struct menu *menu; | ||||||
| 	struct bootmenu_data *bootmenu; | 	struct bootmenu_data *bootmenu; | ||||||
|  | @ -472,7 +515,7 @@ static void bootmenu_show(int delay) | ||||||
| 
 | 
 | ||||||
| 	if (menu_get_choice(menu, &choice) == 1) { | 	if (menu_get_choice(menu, &choice) == 1) { | ||||||
| 		iter = choice; | 		iter = choice; | ||||||
| 		title = strdup(iter->title); | 		title = u16_strdup(iter->title); | ||||||
| 		command = strdup(iter->command); | 		command = strdup(iter->command); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -487,7 +530,7 @@ cleanup: | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (title && command) { | 	if (title && command) { | ||||||
| 		debug("Starting entry '%s'\n", title); | 		debug("Starting entry '%ls'\n", title); | ||||||
| 		free(title); | 		free(title); | ||||||
| 		run_command(command, 0); | 		run_command(command, 0); | ||||||
| 		free(command); | 		free(command); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue