sysboot.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // SPDX-License-Identifier: GPL-2.0+
  2. #include <common.h>
  3. #include <command.h>
  4. #include <env.h>
  5. #include <fs.h>
  6. #include "pxe_utils.h"
  7. static char *fs_argv[5];
  8. static int do_get_ext2(struct cmd_tbl *cmdtp, const char *file_path,
  9. char *file_addr)
  10. {
  11. #ifdef CONFIG_CMD_EXT2
  12. fs_argv[0] = "ext2load";
  13. fs_argv[3] = file_addr;
  14. fs_argv[4] = (void *)file_path;
  15. if (!do_ext2load(cmdtp, 0, 5, fs_argv))
  16. return 1;
  17. #endif
  18. return -ENOENT;
  19. }
  20. static int do_get_fat(struct cmd_tbl *cmdtp, const char *file_path,
  21. char *file_addr)
  22. {
  23. #ifdef CONFIG_CMD_FAT
  24. fs_argv[0] = "fatload";
  25. fs_argv[3] = file_addr;
  26. fs_argv[4] = (void *)file_path;
  27. if (!do_fat_fsload(cmdtp, 0, 5, fs_argv))
  28. return 1;
  29. #endif
  30. return -ENOENT;
  31. }
  32. static int do_get_any(struct cmd_tbl *cmdtp, const char *file_path,
  33. char *file_addr)
  34. {
  35. #ifdef CONFIG_CMD_FS_GENERIC
  36. fs_argv[0] = "load";
  37. fs_argv[3] = file_addr;
  38. fs_argv[4] = (void *)file_path;
  39. if (!do_load(cmdtp, 0, 5, fs_argv, FS_TYPE_ANY))
  40. return 1;
  41. #endif
  42. return -ENOENT;
  43. }
  44. /*
  45. * Boots a system using a local disk syslinux/extlinux file
  46. *
  47. * Returns 0 on success, 1 on error.
  48. */
  49. static int do_sysboot(struct cmd_tbl *cmdtp, int flag, int argc,
  50. char *const argv[])
  51. {
  52. unsigned long pxefile_addr_r;
  53. struct pxe_menu *cfg;
  54. char *pxefile_addr_str;
  55. char *filename;
  56. int prompt = 0;
  57. is_pxe = false;
  58. if (argc > 1 && strstr(argv[1], "-p")) {
  59. prompt = 1;
  60. argc--;
  61. argv++;
  62. }
  63. if (argc < 4)
  64. return cmd_usage(cmdtp);
  65. if (argc < 5) {
  66. pxefile_addr_str = from_env("pxefile_addr_r");
  67. if (!pxefile_addr_str)
  68. return 1;
  69. } else {
  70. pxefile_addr_str = argv[4];
  71. }
  72. if (argc < 6) {
  73. filename = env_get("bootfile");
  74. } else {
  75. filename = argv[5];
  76. env_set("bootfile", filename);
  77. }
  78. if (strstr(argv[3], "ext2")) {
  79. do_getfile = do_get_ext2;
  80. } else if (strstr(argv[3], "fat")) {
  81. do_getfile = do_get_fat;
  82. } else if (strstr(argv[3], "any")) {
  83. do_getfile = do_get_any;
  84. } else {
  85. printf("Invalid filesystem: %s\n", argv[3]);
  86. return 1;
  87. }
  88. fs_argv[1] = argv[1];
  89. fs_argv[2] = argv[2];
  90. if (strict_strtoul(pxefile_addr_str, 16, &pxefile_addr_r) < 0) {
  91. printf("Invalid pxefile address: %s\n", pxefile_addr_str);
  92. return 1;
  93. }
  94. if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
  95. printf("Error reading config file\n");
  96. return 1;
  97. }
  98. cfg = parse_pxefile(cmdtp, pxefile_addr_r);
  99. if (!cfg) {
  100. printf("Error parsing config file\n");
  101. return 1;
  102. }
  103. if (prompt)
  104. cfg->prompt = 1;
  105. handle_pxe_menu(cmdtp, cfg);
  106. destroy_pxe_menu(cfg);
  107. return 0;
  108. }
  109. U_BOOT_CMD(sysboot, 7, 1, do_sysboot,
  110. "command to get and boot from syslinux files",
  111. "[-p] <interface> <dev[:part]> <ext2|fat|any> [addr] [filename]\n"
  112. " - load and parse syslinux menu file 'filename' from ext2, fat\n"
  113. " or any filesystem on 'dev' on 'interface' to address 'addr'"
  114. );