bootm.c 2.8 KB

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