]> git.sur5r.net Git - u-boot/blob - lib_i386/i386_linux.c
[new uImage] Remove I386 uImage fake_header() routine
[u-boot] / lib_i386 / i386_linux.c
1 /*
2  * (C) Copyright 2002
3  * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
4  * Marius Groeger <mgroeger@sysgo.de>
5  *
6  * Copyright (C) 2001  Erik Mouw (J.A.K.Mouw@its.tudelft.nl)
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include <common.h>
25 #include <command.h>
26 #include <image.h>
27 #include <zlib.h>
28 #include <asm/byteorder.h>
29 #include <asm/zimage.h>
30
31 /*cmd_boot.c*/
32 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
33
34 extern image_header_t header;           /* from cmd_bootm.c */
35
36 void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
37                 ulong addr, ulong *len_ptr, int   verify)
38 {
39         void *base_ptr;
40
41         ulong len = 0;
42         ulong initrd_start, initrd_end;
43         ulong data;
44         image_header_t *hdr = &header;
45
46         /*
47          * Check if there is an initrd image
48          */
49         if (argc >= 3) {
50                 addr = simple_strtoul(argv[2], NULL, 16);
51                 hdr = (image_header_t *)addr;
52
53                 printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
54
55                 if (!image_check_magic (hdr)) {
56                         printf ("Bad Magic Number\n");
57                         do_reset (cmdtp, flag, argc, argv);
58                 }
59
60                 if (!image_check_hcrc (hdr)) {
61                         printf ("Bad Header Checksum\n");
62                         do_reset (cmdtp, flag, argc, argv);
63                 }
64
65                 print_image_hdr (hdr);
66
67                 data = image_get_data (hdr);
68                 len = image_get_data_size (hdr);
69
70                 if (verify) {
71                         printf ("   Verifying Checksum ... ");
72                         if (!image_check_dcrc (hdr)) {
73                                 printf ("Bad Data CRC\n");
74                                 do_reset (cmdtp, flag, argc, argv);
75                         }
76                         printf ("OK\n");
77                 }
78
79                 if (!image_check_os (hdr, IH_OS_LINUX) ||
80                     !image_check_arch (hdr, IH_ARCH_I386) ||
81                     !image_check_type (hdr, IH_TYPE_RAMDISK)) {
82                         printf ("No Linux i386 Ramdisk Image\n");
83                         do_reset (cmdtp, flag, argc, argv);
84                 }
85
86                 /*
87                  * Now check if we have a multifile image
88                  */
89         } else if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
90                 ulong tail    = image_to_cpu (len_ptr[0]) % 4;
91                 int i;
92
93                 /* skip kernel length and terminator */
94                 data = (ulong)(&len_ptr[2]);
95                 /* skip any additional image length fields */
96                 for (i=1; len_ptr[i]; ++i)
97                         data += 4;
98                 /* add kernel length, and align */
99                 data += image_to_cpu (len_ptr[0]);
100                 if (tail) {
101                         data += 4 - tail;
102                 }
103
104                 len   = image_to_cpu (len_ptr[1]);
105
106         } else {
107                 /*
108                  * no initrd image
109                  */
110                 data = 0;
111         }
112
113 #ifdef  DEBUG
114         if (!data) {
115                 printf ("No initrd\n");
116         }
117 #endif
118
119         if (data) {
120                 initrd_start = data;
121                 initrd_end   = initrd_start + len;
122                 printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
123                         initrd_start, initrd_end);
124                 memmove ((void *)initrd_start, (void *)data, len);
125                 printf ("OK\n");
126         } else {
127                 initrd_start = 0;
128                 initrd_end = 0;
129         }
130
131         /* if multi-part image, we need to advance base ptr */
132         if (image_check_type (hdr, IH_TYPE_MULTI) && (len_ptr[1])) {
133                 int i;
134                 for (i=0, addr+=sizeof(int); len_ptr[i++]; addr+=sizeof(int));
135         }
136
137         base_ptr = load_zimage((void*)addr + image_get_header_size (),
138                                image_get_data_size (hdr),
139                                initrd_start, initrd_end-initrd_start, 0);
140
141         if (NULL == base_ptr) {
142                 printf ("## Kernel loading failed ...\n");
143                 do_reset(cmdtp, flag, argc, argv);
144
145         }
146
147 #ifdef DEBUG
148         printf ("## Transferring control to Linux (at address %08x) ...\n",
149                 (u32)base_ptr);
150 #endif
151
152         /* we assume that the kernel is in place */
153         printf("\nStarting kernel ...\n\n");
154
155         boot_zimage(base_ptr);
156
157 }