bootm.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * Copyright (C) 2011 Andes Technology Corporation
  3. * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
  4. * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
  5. *
  6. * SPDX-License-Identifier: GPL-2.0+
  7. */
  8. #include <common.h>
  9. #include <command.h>
  10. #include <image.h>
  11. #include <u-boot/zlib.h>
  12. #include <asm/byteorder.h>
  13. DECLARE_GLOBAL_DATA_PTR;
  14. #if defined(CONFIG_SETUP_MEMORY_TAGS) || \
  15. defined(CONFIG_CMDLINE_TAG) || \
  16. defined(CONFIG_INITRD_TAG) || \
  17. defined(CONFIG_SERIAL_TAG) || \
  18. defined(CONFIG_REVISION_TAG)
  19. static void setup_start_tag(bd_t *bd);
  20. # ifdef CONFIG_SETUP_MEMORY_TAGS
  21. static void setup_memory_tags(bd_t *bd);
  22. # endif
  23. static void setup_commandline_tag(bd_t *bd, char *commandline);
  24. # ifdef CONFIG_INITRD_TAG
  25. static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
  26. # endif
  27. static void setup_end_tag(bd_t *bd);
  28. static struct tag *params;
  29. #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
  30. int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
  31. {
  32. bd_t *bd = gd->bd;
  33. char *s;
  34. int machid = bd->bi_arch_number;
  35. void (*theKernel)(int zero, int arch, uint params);
  36. #ifdef CONFIG_CMDLINE_TAG
  37. char *commandline = getenv("bootargs");
  38. #endif
  39. /*
  40. * allow the PREP bootm subcommand, it is required for bootm to work
  41. */
  42. if (flag & BOOTM_STATE_OS_PREP)
  43. return 0;
  44. if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
  45. return 1;
  46. theKernel = (void (*)(int, int, uint))images->ep;
  47. s = getenv("machid");
  48. if (s) {
  49. machid = simple_strtoul(s, NULL, 16);
  50. printf("Using machid 0x%x from environment\n", machid);
  51. }
  52. bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  53. debug("## Transferring control to Linux (at address %08lx) ...\n",
  54. (ulong)theKernel);
  55. #if defined(CONFIG_SETUP_MEMORY_TAGS) || \
  56. defined(CONFIG_CMDLINE_TAG) || \
  57. defined(CONFIG_INITRD_TAG) || \
  58. defined(CONFIG_SERIAL_TAG) || \
  59. defined(CONFIG_REVISION_TAG)
  60. setup_start_tag(bd);
  61. #ifdef CONFIG_SERIAL_TAG
  62. setup_serial_tag(&params);
  63. #endif
  64. #ifdef CONFIG_REVISION_TAG
  65. setup_revision_tag(&params);
  66. #endif
  67. #ifdef CONFIG_SETUP_MEMORY_TAGS
  68. setup_memory_tags(bd);
  69. #endif
  70. #ifdef CONFIG_CMDLINE_TAG
  71. setup_commandline_tag(bd, commandline);
  72. #endif
  73. #ifdef CONFIG_INITRD_TAG
  74. if (images->rd_start && images->rd_end)
  75. setup_initrd_tag(bd, images->rd_start, images->rd_end);
  76. #endif
  77. setup_end_tag(bd);
  78. #endif
  79. /* we assume that the kernel is in place */
  80. printf("\nStarting kernel ...\n\n");
  81. #ifdef CONFIG_USB_DEVICE
  82. {
  83. extern void udc_disconnect(void);
  84. udc_disconnect();
  85. }
  86. #endif
  87. cleanup_before_linux();
  88. theKernel(0, machid, bd->bi_boot_params);
  89. /* does not return */
  90. return 1;
  91. }
  92. #if defined(CONFIG_SETUP_MEMORY_TAGS) || \
  93. defined(CONFIG_CMDLINE_TAG) || \
  94. defined(CONFIG_INITRD_TAG) || \
  95. defined(CONFIG_SERIAL_TAG) || \
  96. defined(CONFIG_REVISION_TAG)
  97. static void setup_start_tag(bd_t *bd)
  98. {
  99. params = (struct tag *)bd->bi_boot_params;
  100. params->hdr.tag = ATAG_CORE;
  101. params->hdr.size = tag_size(tag_core);
  102. params->u.core.flags = 0;
  103. params->u.core.pagesize = 0;
  104. params->u.core.rootdev = 0;
  105. params = tag_next(params);
  106. }
  107. #ifdef CONFIG_SETUP_MEMORY_TAGS
  108. static void setup_memory_tags(bd_t *bd)
  109. {
  110. int i;
  111. for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
  112. params->hdr.tag = ATAG_MEM;
  113. params->hdr.size = tag_size(tag_mem32);
  114. params->u.mem.start = bd->bi_dram[i].start;
  115. params->u.mem.size = bd->bi_dram[i].size;
  116. params = tag_next(params);
  117. }
  118. }
  119. #endif /* CONFIG_SETUP_MEMORY_TAGS */
  120. static void setup_commandline_tag(bd_t *bd, char *commandline)
  121. {
  122. char *p;
  123. if (!commandline)
  124. return;
  125. /* eat leading white space */
  126. for (p = commandline; *p == ' '; p++)
  127. ;
  128. /* skip non-existent command lines so the kernel will still
  129. * use its default command line.
  130. */
  131. if (*p == '\0')
  132. return;
  133. params->hdr.tag = ATAG_CMDLINE;
  134. params->hdr.size =
  135. (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
  136. strcpy(params->u.cmdline.cmdline, p)
  137. ;
  138. params = tag_next(params);
  139. }
  140. #ifdef CONFIG_INITRD_TAG
  141. static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
  142. {
  143. /* an ATAG_INITRD node tells the kernel where the compressed
  144. * ramdisk can be found. ATAG_RDIMG is a better name, actually.
  145. */
  146. params->hdr.tag = ATAG_INITRD2;
  147. params->hdr.size = tag_size(tag_initrd);
  148. params->u.initrd.start = initrd_start;
  149. params->u.initrd.size = initrd_end - initrd_start;
  150. params = tag_next(params);
  151. }
  152. #endif /* CONFIG_INITRD_TAG */
  153. #ifdef CONFIG_SERIAL_TAG
  154. void setup_serial_tag(struct tag **tmp)
  155. {
  156. struct tag *params = *tmp;
  157. struct tag_serialnr serialnr;
  158. void get_board_serial(struct tag_serialnr *serialnr);
  159. get_board_serial(&serialnr);
  160. params->hdr.tag = ATAG_SERIAL;
  161. params->hdr.size = tag_size(tag_serialnr);
  162. params->u.serialnr.low = serialnr.low;
  163. params->u.serialnr.high = serialnr.high;
  164. params = tag_next(params);
  165. *tmp = params;
  166. }
  167. #endif
  168. #ifdef CONFIG_REVISION_TAG
  169. void setup_revision_tag(struct tag **in_params)
  170. {
  171. u32 rev = 0;
  172. u32 get_board_rev(void);
  173. rev = get_board_rev();
  174. params->hdr.tag = ATAG_REVISION;
  175. params->hdr.size = tag_size(tag_revision);
  176. params->u.revision.rev = rev;
  177. params = tag_next(params);
  178. }
  179. #endif /* CONFIG_REVISION_TAG */
  180. static void setup_end_tag(bd_t *bd)
  181. {
  182. params->hdr.tag = ATAG_NONE;
  183. params->hdr.size = 0;
  184. }
  185. #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */