microblaze_linux.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * (C) Copyright 2007 Michal Simek
  3. * (C) Copyright 2004 Atmark Techno, Inc.
  4. *
  5. * Michal SIMEK <monstr@monstr.eu>
  6. * Yasushi SHOJI <yashi@atmark-techno.com>
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <command.h>
  28. #include <image.h>
  29. #include <zlib.h>
  30. #include <asm/byteorder.h>
  31. DECLARE_GLOBAL_DATA_PTR;
  32. #ifdef CONFIG_SHOW_BOOT_PROGRESS
  33. # include <status_led.h>
  34. # define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
  35. #else
  36. # define SHOW_BOOT_PROGRESS(arg)
  37. #endif
  38. extern image_header_t header; /* from cmd_bootm.c */
  39. /*cmd_boot.c*/
  40. extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
  41. void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
  42. ulong addr, ulong * len_ptr, int verify)
  43. {
  44. ulong len = 0, checksum;
  45. ulong initrd_start, initrd_end;
  46. ulong data;
  47. /* First parameter is mapped to $r5 for kernel boot args */
  48. void (*theKernel) (char *);
  49. image_header_t *hdr = &header;
  50. char *commandline = getenv ("bootargs");
  51. int i;
  52. theKernel = (void (*)(char *))ntohl (hdr->ih_ep);
  53. /* Check if there is an initrd image */
  54. if (argc >= 3) {
  55. SHOW_BOOT_PROGRESS (9);
  56. addr = simple_strtoul (argv[2], NULL, 16);
  57. printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
  58. /* Copy header so we can blank CRC field for re-calculation */
  59. memcpy (&header, (char *)addr, sizeof (image_header_t));
  60. if (ntohl (hdr->ih_magic) != IH_MAGIC) {
  61. printf ("Bad Magic Number\n");
  62. SHOW_BOOT_PROGRESS (-10);
  63. do_reset (cmdtp, flag, argc, argv);
  64. }
  65. data = (ulong) & header;
  66. len = sizeof (image_header_t);
  67. checksum = ntohl (hdr->ih_hcrc);
  68. hdr->ih_hcrc = 0;
  69. if (crc32 (0, (char *)data, len) != checksum) {
  70. printf ("Bad Header Checksum\n");
  71. SHOW_BOOT_PROGRESS (-11);
  72. do_reset (cmdtp, flag, argc, argv);
  73. }
  74. SHOW_BOOT_PROGRESS (10);
  75. print_image_hdr (hdr);
  76. data = addr + sizeof (image_header_t);
  77. len = ntohl (hdr->ih_size);
  78. if (verify) {
  79. ulong csum = 0;
  80. printf (" Verifying Checksum ... ");
  81. csum = crc32 (0, (char *)data, len);
  82. if (csum != ntohl (hdr->ih_dcrc)) {
  83. printf ("Bad Data CRC\n");
  84. SHOW_BOOT_PROGRESS (-12);
  85. do_reset (cmdtp, flag, argc, argv);
  86. }
  87. printf ("OK\n");
  88. }
  89. SHOW_BOOT_PROGRESS (11);
  90. if ((hdr->ih_os != IH_OS_LINUX) ||
  91. (hdr->ih_arch != IH_CPU_MICROBLAZE) ||
  92. (hdr->ih_type != IH_TYPE_RAMDISK)) {
  93. printf ("No Linux Microblaze Ramdisk Image\n");
  94. SHOW_BOOT_PROGRESS (-13);
  95. do_reset (cmdtp, flag, argc, argv);
  96. }
  97. /*
  98. * Now check if we have a multifile image
  99. */
  100. } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
  101. ulong tail = ntohl (len_ptr[0]) % 4;
  102. SHOW_BOOT_PROGRESS (13);
  103. /* skip kernel length and terminator */
  104. data = (ulong) (&len_ptr[2]);
  105. /* skip any additional image length fields */
  106. for (i = 1; len_ptr[i]; ++i)
  107. data += 4;
  108. /* add kernel length, and align */
  109. data += ntohl (len_ptr[0]);
  110. if (tail) {
  111. data += 4 - tail;
  112. }
  113. len = ntohl (len_ptr[1]);
  114. } else {
  115. /*
  116. * no initrd image
  117. */
  118. SHOW_BOOT_PROGRESS (14);
  119. data = 0;
  120. }
  121. #ifdef DEBUG
  122. if (!data) {
  123. printf ("No initrd\n");
  124. }
  125. #endif
  126. if (data) {
  127. initrd_start = data;
  128. initrd_end = initrd_start + len;
  129. } else {
  130. initrd_start = 0;
  131. initrd_end = 0;
  132. }
  133. SHOW_BOOT_PROGRESS (15);
  134. #ifdef DEBUG
  135. printf ("## Transferring control to Linux (at address %08lx) ...\n",
  136. (ulong) theKernel);
  137. #endif
  138. theKernel (commandline);
  139. }