diff options
Diffstat (limited to 'common/cmd_pxe.c')
| -rw-r--r-- | common/cmd_pxe.c | 141 | 
1 files changed, 133 insertions, 8 deletions
| diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c index 0fc863b22..2b1115d72 100644 --- a/common/cmd_pxe.c +++ b/common/cmd_pxe.c @@ -132,6 +132,51 @@ static int get_bootfile_path(const char *file_path, char *bootfile_path,  	return 1;  } +static int (*do_getfile)(char *file_path, char *file_addr); + +static int do_get_tftp(char *file_path, char *file_addr) +{ +	char *tftp_argv[] = {"tftp", NULL, NULL, NULL}; + +	tftp_argv[1] = file_addr; +	tftp_argv[2] = file_path; + +	if (do_tftpb(NULL, 0, 3, tftp_argv)) +		return -ENOENT; + +	return 1; +} + +static char *fs_argv[5]; + +static int do_get_ext2(char *file_path, char *file_addr) +{ +#ifdef CONFIG_CMD_EXT2 +	fs_argv[0] = "ext2load"; +	fs_argv[3] = file_addr; +	fs_argv[4] = file_path; + +	if (!do_ext2load(NULL, 0, 5, fs_argv)) +		return 1; +#endif +	return -ENOENT; +} + +static int do_get_fat(char *file_path, char *file_addr) +{ +#ifdef CONFIG_CMD_FAT +	fs_argv[0] = "fatload"; +	fs_argv[3] = file_addr; +	fs_argv[4] = file_path; + +	if (!do_fat_fsload(NULL, 0, 5, fs_argv)) +		return 1; +#endif +	return -ENOENT; +} + + +  /*   * As in pxelinux, paths to files referenced from files we retrieve are   * relative to the location of bootfile. get_relfile takes such a path and @@ -145,7 +190,6 @@ static int get_relfile(char *file_path, void *file_addr)  	size_t path_len;  	char relfile[MAX_TFTP_PATH_LEN+1];  	char addr_buf[10]; -	char *tftp_argv[] = {"tftp", NULL, NULL, NULL};  	int err;  	err = get_bootfile_path(file_path, relfile, sizeof(relfile)); @@ -170,13 +214,7 @@ static int get_relfile(char *file_path, void *file_addr)  	sprintf(addr_buf, "%p", file_addr); -	tftp_argv[1] = addr_buf; -	tftp_argv[2] = relfile; - -	if (do_tftpb(NULL, 0, 3, tftp_argv)) -		return -ENOENT; - -	return 1; +	return do_getfile(relfile, addr_buf);  }  /* @@ -322,6 +360,8 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	unsigned long pxefile_addr_r;  	int err; +	do_getfile = do_get_tftp; +  	if (argc != 1)  		return CMD_RET_USAGE; @@ -1331,6 +1371,8 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	struct pxe_menu *cfg;  	char *pxefile_addr_str; +	do_getfile = do_get_tftp; +  	if (argc == 1) {  		pxefile_addr_str = from_env("pxefile_addr_r");  		if (!pxefile_addr_str) @@ -1391,3 +1433,86 @@ U_BOOT_CMD(  	"get - try to retrieve a pxe file using tftp\npxe "  	"boot [pxefile_addr_r] - boot from the pxe file at pxefile_addr_r\n"  ); + +/* + * Boots a system using a local disk syslinux/extlinux file + * + * Returns 0 on success, 1 on error. + */ +int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	unsigned long pxefile_addr_r; +	struct pxe_menu *cfg; +	char *pxefile_addr_str; +	char *filename; +	int prompt = 0; + +	if (strstr(argv[1], "-p")) { +		prompt = 1; +		argc--; +		argv++; +	} + +	if (argc < 4) +		return cmd_usage(cmdtp); + +	if (argc < 5) { +		pxefile_addr_str = from_env("pxefile_addr_r"); +		if (!pxefile_addr_str) +			return 1; +	} else { +		pxefile_addr_str = argv[4]; +	} + +	if (argc < 6) +		filename = getenv("bootfile"); +	else { +		filename = argv[5]; +		setenv("bootfile", filename); +	} + +	if (strstr(argv[3], "ext2")) +		do_getfile = do_get_ext2; +	else if (strstr(argv[3], "fat")) +		do_getfile = do_get_fat; +	else { +		printf("Invalid filesystem: %s\n", argv[3]); +		return 1; +	} +	fs_argv[1] = argv[1]; +	fs_argv[2] = argv[2]; + +	if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) { +		printf("Invalid pxefile address: %s\n", pxefile_addr_str); +		return 1; +	} + +	if (get_pxe_file(filename, (void *)pxefile_addr_r) < 0) { +		printf("Error reading config file\n"); +		return 1; +	} + +	cfg = parse_pxefile((char *)(pxefile_addr_r)); + +	if (cfg == NULL) { +		printf("Error parsing config file\n"); +		return 1; +	} + +	if (prompt) +		cfg->prompt = 1; + +	handle_pxe_menu(cfg); + +	destroy_pxe_menu(cfg); + +	return 0; +} + +U_BOOT_CMD( +	sysboot, 7, 1, do_sysboot, +	"command to get and boot from syslinux files", +	"[-p] <interface> <dev[:part]> <ext2|fat> [addr] [filename]\n" +	"    - load and parse syslinux menu file 'filename' from ext2 or fat\n" +	"      filesystem on 'dev' on 'interface' to address 'addr'" +); |