microblaze_linux.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. extern image_header_t header; /* from cmd_bootm.c */
  33. /*cmd_boot.c*/
  34. extern int do_reset (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
  35. void do_bootm_linux (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
  36. ulong addr, ulong * len_ptr, int verify)
  37. {
  38. ulong len = 0, checksum;
  39. ulong initrd_start, initrd_end;
  40. ulong data;
  41. /* First parameter is mapped to $r5 for kernel boot args */
  42. void (*theKernel) (char *);
  43. image_header_t *hdr = &header;
  44. char *commandline = getenv ("bootargs");
  45. int i;
  46. theKernel = (void (*)(char *))ntohl (hdr->ih_ep);
  47. /* Check if there is an initrd image */
  48. if (argc >= 3) {
  49. show_boot_progress (9);
  50. addr = simple_strtoul (argv[2], NULL, 16);
  51. printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
  52. /* Copy header so we can blank CRC field for re-calculation */
  53. memcpy (&header, (char *)addr, sizeof (image_header_t));
  54. if (ntohl (hdr->ih_magic) != IH_MAGIC) {
  55. printf ("Bad Magic Number\n");
  56. show_boot_progress (-10);
  57. do_reset (cmdtp, flag, argc, argv);
  58. }
  59. data = (ulong) & header;
  60. len = sizeof (image_header_t);
  61. checksum = ntohl (hdr->ih_hcrc);
  62. hdr->ih_hcrc = 0;
  63. if (crc32 (0, (char *)data, len) != checksum) {
  64. printf ("Bad Header Checksum\n");
  65. show_boot_progress (-11);
  66. do_reset (cmdtp, flag, argc, argv);
  67. }
  68. show_boot_progress (10);
  69. print_image_hdr (hdr);
  70. data = addr + sizeof (image_header_t);
  71. len = ntohl (hdr->ih_size);
  72. if (verify) {
  73. ulong csum = 0;
  74. printf (" Verifying Checksum ... ");
  75. csum = crc32 (0, (char *)data, len);
  76. if (csum != ntohl (hdr->ih_dcrc)) {
  77. printf ("Bad Data CRC\n");
  78. show_boot_progress (-12);
  79. do_reset (cmdtp, flag, argc, argv);
  80. }
  81. printf ("OK\n");
  82. }
  83. show_boot_progress (11);
  84. if ((hdr->ih_os != IH_OS_LINUX) ||
  85. (hdr->ih_arch != IH_CPU_MICROBLAZE) ||
  86. (hdr->ih_type != IH_TYPE_RAMDISK)) {
  87. printf ("No Linux Microblaze Ramdisk Image\n");
  88. show_boot_progress (-13);
  89. do_reset (cmdtp, flag, argc, argv);
  90. }
  91. /*
  92. * Now check if we have a multifile image
  93. */
  94. } else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
  95. ulong tail = ntohl (len_ptr[0]) % 4;
  96. show_boot_progress (13);
  97. /* skip kernel length and terminator */
  98. data = (ulong) (&len_ptr[2]);
  99. /* skip any additional image length fields */
  100. for (i = 1; len_ptr[i]; ++i)
  101. data += 4;
  102. /* add kernel length, and align */
  103. data += ntohl (len_ptr[0]);
  104. if (tail) {
  105. data += 4 - tail;
  106. }
  107. len = ntohl (len_ptr[1]);
  108. } else {
  109. /*
  110. * no initrd image
  111. */
  112. show_boot_progress (14);
  113. data = 0;
  114. }
  115. #ifdef DEBUG
  116. if (!data) {
  117. printf ("No initrd\n");
  118. }
  119. #endif
  120. if (data) {
  121. initrd_start = data;
  122. initrd_end = initrd_start + len;
  123. } else {
  124. initrd_start = 0;
  125. initrd_end = 0;
  126. }
  127. show_boot_progress (15);
  128. #ifdef DEBUG
  129. printf ("## Transferring control to Linux (at address %08lx) ...\n",
  130. (ulong) theKernel);
  131. #endif
  132. theKernel (commandline);
  133. }