|
@@ -14,6 +14,7 @@
|
|
#include <errno.h>
|
|
#include <errno.h>
|
|
#include <linux/list.h>
|
|
#include <linux/list.h>
|
|
#include <fs.h>
|
|
#include <fs.h>
|
|
|
|
+#include <asm/io.h>
|
|
|
|
|
|
#include "menu.h"
|
|
#include "menu.h"
|
|
#include "cli.h"
|
|
#include "cli.h"
|
|
@@ -189,11 +190,12 @@ static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
|
|
*
|
|
*
|
|
* Returns 1 for success, or < 0 on error.
|
|
* Returns 1 for success, or < 0 on error.
|
|
*/
|
|
*/
|
|
-static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
|
|
|
|
|
|
+static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
|
|
|
|
+ unsigned long file_addr)
|
|
{
|
|
{
|
|
size_t path_len;
|
|
size_t path_len;
|
|
char relfile[MAX_TFTP_PATH_LEN+1];
|
|
char relfile[MAX_TFTP_PATH_LEN+1];
|
|
- char addr_buf[10];
|
|
|
|
|
|
+ char addr_buf[18];
|
|
int err;
|
|
int err;
|
|
|
|
|
|
err = get_bootfile_path(file_path, relfile, sizeof(relfile));
|
|
err = get_bootfile_path(file_path, relfile, sizeof(relfile));
|
|
@@ -216,7 +218,7 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
|
|
|
|
|
|
printf("Retrieving file: %s\n", relfile);
|
|
printf("Retrieving file: %s\n", relfile);
|
|
|
|
|
|
- sprintf(addr_buf, "%p", file_addr);
|
|
|
|
|
|
+ sprintf(addr_buf, "%lx", file_addr);
|
|
|
|
|
|
return do_getfile(cmdtp, relfile, addr_buf);
|
|
return do_getfile(cmdtp, relfile, addr_buf);
|
|
}
|
|
}
|
|
@@ -228,11 +230,13 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
|
|
*
|
|
*
|
|
* Returns 1 on success, or < 0 for error.
|
|
* Returns 1 on success, or < 0 for error.
|
|
*/
|
|
*/
|
|
-static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
|
|
|
|
|
|
+static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
|
|
|
|
+ unsigned long file_addr)
|
|
{
|
|
{
|
|
unsigned long config_file_size;
|
|
unsigned long config_file_size;
|
|
char *tftp_filesize;
|
|
char *tftp_filesize;
|
|
int err;
|
|
int err;
|
|
|
|
+ char *buf;
|
|
|
|
|
|
err = get_relfile(cmdtp, file_path, file_addr);
|
|
err = get_relfile(cmdtp, file_path, file_addr);
|
|
|
|
|
|
@@ -251,7 +255,9 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr
|
|
if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0)
|
|
if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- *(char *)(file_addr + config_file_size) = '\0';
|
|
|
|
|
|
+ buf = map_sysmem(file_addr + config_file_size, 1);
|
|
|
|
+ *buf = '\0';
|
|
|
|
+ unmap_sysmem(buf);
|
|
|
|
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
@@ -267,7 +273,8 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr
|
|
*
|
|
*
|
|
* Returns 1 on success or < 0 on error.
|
|
* Returns 1 on success or < 0 on error.
|
|
*/
|
|
*/
|
|
-static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_addr_r)
|
|
|
|
|
|
+static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file,
|
|
|
|
+ unsigned long pxefile_addr_r)
|
|
{
|
|
{
|
|
size_t base_len = strlen(PXELINUX_DIR);
|
|
size_t base_len = strlen(PXELINUX_DIR);
|
|
char path[MAX_TFTP_PATH_LEN+1];
|
|
char path[MAX_TFTP_PATH_LEN+1];
|
|
@@ -288,7 +295,7 @@ static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_a
|
|
*
|
|
*
|
|
* Returns 1 on success or < 0 on error.
|
|
* Returns 1 on success or < 0 on error.
|
|
*/
|
|
*/
|
|
-static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
|
|
|
|
|
|
+static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
|
|
{
|
|
{
|
|
char *uuid_str;
|
|
char *uuid_str;
|
|
|
|
|
|
@@ -306,7 +313,7 @@ static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
|
|
*
|
|
*
|
|
* Returns 1 on success or < 0 on error.
|
|
* Returns 1 on success or < 0 on error.
|
|
*/
|
|
*/
|
|
-static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
|
|
|
|
|
|
+static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
|
|
{
|
|
{
|
|
char mac_str[21];
|
|
char mac_str[21];
|
|
int err;
|
|
int err;
|
|
@@ -326,7 +333,7 @@ static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
|
|
*
|
|
*
|
|
* Returns 1 on success or < 0 on error.
|
|
* Returns 1 on success or < 0 on error.
|
|
*/
|
|
*/
|
|
-static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
|
|
|
|
|
|
+static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
|
|
{
|
|
{
|
|
char ip_addr[9];
|
|
char ip_addr[9];
|
|
int mask_pos, err;
|
|
int mask_pos, err;
|
|
@@ -385,9 +392,9 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
* Keep trying paths until we successfully get a file we're looking
|
|
* Keep trying paths until we successfully get a file we're looking
|
|
* for.
|
|
* for.
|
|
*/
|
|
*/
|
|
- if (pxe_uuid_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
|
|
|
|
- pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
|
|
|
|
- pxe_ipaddr_paths(cmdtp, (void *)pxefile_addr_r) > 0) {
|
|
|
|
|
|
+ if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 ||
|
|
|
|
+ pxe_mac_path(cmdtp, pxefile_addr_r) > 0 ||
|
|
|
|
+ pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) {
|
|
printf("Config file found\n");
|
|
printf("Config file found\n");
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
@@ -395,7 +402,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
|
|
|
|
while (pxe_default_paths[i]) {
|
|
while (pxe_default_paths[i]) {
|
|
if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
|
|
if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
|
|
- (void *)pxefile_addr_r) > 0) {
|
|
|
|
|
|
+ pxefile_addr_r) > 0) {
|
|
printf("Config file found\n");
|
|
printf("Config file found\n");
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -428,7 +435,7 @@ static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const ch
|
|
if (strict_strtoul(envaddr, 16, &file_addr) < 0)
|
|
if (strict_strtoul(envaddr, 16, &file_addr) < 0)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
- return get_relfile(cmdtp, file_path, (void *)file_addr);
|
|
|
|
|
|
+ return get_relfile(cmdtp, file_path, file_addr);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -791,6 +798,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
|
|
else
|
|
else
|
|
do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
|
|
do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
|
|
#endif
|
|
#endif
|
|
|
|
+ unmap_sysmem(buf);
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1055,7 +1063,8 @@ static int parse_integer(char **c, int *dst)
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level);
|
|
|
|
|
|
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
|
|
|
|
+ struct pxe_menu *cfg, int nest_level);
|
|
|
|
|
|
/*
|
|
/*
|
|
* Parse an include statement, and retrieve and parse the file it mentions.
|
|
* Parse an include statement, and retrieve and parse the file it mentions.
|
|
@@ -1065,12 +1074,14 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
|
|
* include, nest_level has already been incremented and doesn't need to be
|
|
* include, nest_level has already been incremented and doesn't need to be
|
|
* incremented here.
|
|
* incremented here.
|
|
*/
|
|
*/
|
|
-static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
|
|
|
|
|
|
+static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base,
|
|
struct pxe_menu *cfg, int nest_level)
|
|
struct pxe_menu *cfg, int nest_level)
|
|
{
|
|
{
|
|
char *include_path;
|
|
char *include_path;
|
|
char *s = *c;
|
|
char *s = *c;
|
|
int err;
|
|
int err;
|
|
|
|
+ char *buf;
|
|
|
|
+ int ret;
|
|
|
|
|
|
err = parse_sliteral(c, &include_path);
|
|
err = parse_sliteral(c, &include_path);
|
|
|
|
|
|
@@ -1087,20 +1098,25 @@ static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
- return parse_pxefile_top(cmdtp, base, cfg, nest_level);
|
|
|
|
|
|
+ buf = map_sysmem(base, 0);
|
|
|
|
+ ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level);
|
|
|
|
+ unmap_sysmem(buf);
|
|
|
|
+
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
* Parse lines that begin with 'menu'.
|
|
* Parse lines that begin with 'menu'.
|
|
*
|
|
*
|
|
- * b and nest are provided to handle the 'menu include' case.
|
|
|
|
|
|
+ * base and nest are provided to handle the 'menu include' case.
|
|
*
|
|
*
|
|
- * b should be the address where the file currently being parsed is stored.
|
|
|
|
|
|
+ * base should point to a location where it's safe to store the included file.
|
|
*
|
|
*
|
|
* nest_level should be 1 when parsing the top level pxe file, 2 when parsing
|
|
* nest_level should be 1 when parsing the top level pxe file, 2 when parsing
|
|
* a file it includes, 3 when parsing a file included by that file, and so on.
|
|
* a file it includes, 3 when parsing a file included by that file, and so on.
|
|
*/
|
|
*/
|
|
-static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, int nest_level)
|
|
|
|
|
|
+static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
|
|
|
|
+ unsigned long base, int nest_level)
|
|
{
|
|
{
|
|
struct token t;
|
|
struct token t;
|
|
char *s = *c;
|
|
char *s = *c;
|
|
@@ -1115,7 +1131,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b,
|
|
break;
|
|
break;
|
|
|
|
|
|
case T_INCLUDE:
|
|
case T_INCLUDE:
|
|
- err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg,
|
|
|
|
|
|
+ err = handle_include(cmdtp, c, base, cfg,
|
|
nest_level + 1);
|
|
nest_level + 1);
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -1282,7 +1298,8 @@ static int parse_label(char **c, struct pxe_menu *cfg)
|
|
*
|
|
*
|
|
* Returns 1 on success, < 0 on error.
|
|
* Returns 1 on success, < 0 on error.
|
|
*/
|
|
*/
|
|
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level)
|
|
|
|
|
|
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
|
|
|
|
+ struct pxe_menu *cfg, int nest_level)
|
|
{
|
|
{
|
|
struct token t;
|
|
struct token t;
|
|
char *s, *b, *label_name;
|
|
char *s, *b, *label_name;
|
|
@@ -1304,7 +1321,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
|
|
switch (t.type) {
|
|
switch (t.type) {
|
|
case T_MENU:
|
|
case T_MENU:
|
|
cfg->prompt = 1;
|
|
cfg->prompt = 1;
|
|
- err = parse_menu(cmdtp, &p, cfg, b, nest_level);
|
|
|
|
|
|
+ err = parse_menu(cmdtp, &p, cfg,
|
|
|
|
+ base + ALIGN(strlen(b) + 1, 4),
|
|
|
|
+ nest_level);
|
|
break;
|
|
break;
|
|
|
|
|
|
case T_TIMEOUT:
|
|
case T_TIMEOUT:
|
|
@@ -1329,8 +1348,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
|
|
break;
|
|
break;
|
|
|
|
|
|
case T_INCLUDE:
|
|
case T_INCLUDE:
|
|
- err = handle_include(cmdtp, &p, b + ALIGN(strlen(b), 4), cfg,
|
|
|
|
- nest_level + 1);
|
|
|
|
|
|
+ err = handle_include(cmdtp, &p,
|
|
|
|
+ base + ALIGN(strlen(b), 4), cfg,
|
|
|
|
+ nest_level + 1);
|
|
break;
|
|
break;
|
|
|
|
|
|
case T_PROMPT:
|
|
case T_PROMPT:
|
|
@@ -1386,9 +1406,11 @@ static void destroy_pxe_menu(struct pxe_menu *cfg)
|
|
* files it includes). The resulting pxe_menu struct can be free()'d by using
|
|
* files it includes). The resulting pxe_menu struct can be free()'d by using
|
|
* the destroy_pxe_menu() function.
|
|
* the destroy_pxe_menu() function.
|
|
*/
|
|
*/
|
|
-static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
|
|
|
|
|
|
+static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg)
|
|
{
|
|
{
|
|
struct pxe_menu *cfg;
|
|
struct pxe_menu *cfg;
|
|
|
|
+ char *buf;
|
|
|
|
+ int r;
|
|
|
|
|
|
cfg = malloc(sizeof(struct pxe_menu));
|
|
cfg = malloc(sizeof(struct pxe_menu));
|
|
|
|
|
|
@@ -1399,7 +1421,11 @@ static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
|
|
|
|
|
|
INIT_LIST_HEAD(&cfg->labels);
|
|
INIT_LIST_HEAD(&cfg->labels);
|
|
|
|
|
|
- if (parse_pxefile_top(cmdtp, menucfg, cfg, 1) < 0) {
|
|
|
|
|
|
+ buf = map_sysmem(menucfg, 0);
|
|
|
|
+ r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1);
|
|
|
|
+ unmap_sysmem(buf);
|
|
|
|
+
|
|
|
|
+ if (r < 0) {
|
|
destroy_pxe_menu(cfg);
|
|
destroy_pxe_menu(cfg);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
@@ -1557,7 +1583,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
- cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
|
|
|
|
|
|
+ cfg = parse_pxefile(cmdtp, pxefile_addr_r);
|
|
|
|
|
|
if (cfg == NULL) {
|
|
if (cfg == NULL) {
|
|
printf("Error parsing config file\n");
|
|
printf("Error parsing config file\n");
|
|
@@ -1664,12 +1690,12 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
- if (get_pxe_file(cmdtp, filename, (void *)pxefile_addr_r) < 0) {
|
|
|
|
|
|
+ if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
|
|
printf("Error reading config file\n");
|
|
printf("Error reading config file\n");
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
- cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
|
|
|
|
|
|
+ cfg = parse_pxefile(cmdtp, pxefile_addr_r);
|
|
|
|
|
|
if (cfg == NULL) {
|
|
if (cfg == NULL) {
|
|
printf("Error parsing config file\n");
|
|
printf("Error parsing config file\n");
|