bootm.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2003
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. *
  6. * (c) Copyright 2008 Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
  7. * (c) Copyright 2008 Renesas Solutions Corp.
  8. */
  9. #include <common.h>
  10. #include <command.h>
  11. #include <env.h>
  12. #include <image.h>
  13. #include <asm/byteorder.h>
  14. #include <asm/zimage.h>
  15. #ifdef CONFIG_SYS_DEBUG
  16. static void hexdump(unsigned char *buf, int len)
  17. {
  18. int i;
  19. for (i = 0; i < len; i++) {
  20. if ((i % 16) == 0)
  21. printf("%s%08x: ", i ? "\n" : "",
  22. (unsigned int)&buf[i]);
  23. printf("%02x ", buf[i]);
  24. }
  25. printf("\n");
  26. }
  27. #endif
  28. #ifdef CONFIG_SH_SDRAM_OFFSET
  29. #define GET_INITRD_START(initrd, linux) (initrd - linux + CONFIG_SH_SDRAM_OFFSET)
  30. #else
  31. #define GET_INITRD_START(initrd, linux) (initrd - linux)
  32. #endif
  33. static void set_sh_linux_param(unsigned long param_addr, unsigned long data)
  34. {
  35. *(unsigned long *)(param_addr) = data;
  36. }
  37. static unsigned long sh_check_cmd_arg(char *cmdline, char *key, int base)
  38. {
  39. unsigned long val = 0;
  40. char *p = strstr(cmdline, key);
  41. if (p) {
  42. p += strlen(key);
  43. val = simple_strtol(p, NULL, base);
  44. }
  45. return val;
  46. }
  47. int do_bootm_linux(int flag, int argc, char *const argv[],
  48. bootm_headers_t *images)
  49. {
  50. /* Linux kernel load address */
  51. void (*kernel) (void) = (void (*)(void))images->ep;
  52. /* empty_zero_page */
  53. unsigned char *param
  54. = (unsigned char *)image_get_load(images->legacy_hdr_os);
  55. /* Linux kernel command line */
  56. char *cmdline = (char *)param + COMMAND_LINE;
  57. /* PAGE_SIZE */
  58. unsigned long size = images->ep - (unsigned long)param;
  59. char *bootargs = env_get("bootargs");
  60. /*
  61. * allow the PREP bootm subcommand, it is required for bootm to work
  62. */
  63. if (flag & BOOTM_STATE_OS_PREP)
  64. return 0;
  65. if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
  66. return 1;
  67. /* Clear zero page */
  68. memset(param, 0, size);
  69. /* Set commandline */
  70. strcpy(cmdline, bootargs);
  71. /* Initrd */
  72. if (images->rd_start || images->rd_end) {
  73. unsigned long ramdisk_flags = 0;
  74. int val = sh_check_cmd_arg(bootargs, CMD_ARG_RD_PROMPT, 10);
  75. if (val == 1)
  76. ramdisk_flags |= RD_PROMPT;
  77. else
  78. ramdisk_flags &= ~RD_PROMPT;
  79. val = sh_check_cmd_arg(bootargs, CMD_ARG_RD_DOLOAD, 10);
  80. if (val == 1)
  81. ramdisk_flags |= RD_DOLOAD;
  82. else
  83. ramdisk_flags &= ~RD_DOLOAD;
  84. set_sh_linux_param((unsigned long)param + MOUNT_ROOT_RDONLY, 0x0001);
  85. set_sh_linux_param((unsigned long)param + RAMDISK_FLAGS, ramdisk_flags);
  86. set_sh_linux_param((unsigned long)param + ORIG_ROOT_DEV, 0x0200);
  87. set_sh_linux_param((unsigned long)param + LOADER_TYPE, 0x0001);
  88. set_sh_linux_param((unsigned long)param + INITRD_START,
  89. GET_INITRD_START(images->rd_start, CONFIG_SYS_SDRAM_BASE));
  90. set_sh_linux_param((unsigned long)param + INITRD_SIZE,
  91. images->rd_end - images->rd_start);
  92. }
  93. /* Boot kernel */
  94. kernel();
  95. /* does not return */
  96. return 1;
  97. }