52
53
#define COMMAND_LINE_SIZE 2048
55
unsigned generic_install_e820_map(unsigned max_entries,
56
struct e820entry *entries)
61
unsigned install_e820_map(unsigned max_entries,
62
struct e820entry *entries)
63
__attribute__((weak, alias("generic_install_e820_map")));
54
65
static void build_command_line(char *command_line, int auto_boot)
56
67
char *env_command_line;
78
89
printf("Kernel command line: \"%s\"\n", command_line);
81
void *load_zimage(char *image, unsigned long kernel_size,
82
unsigned long initrd_addr, unsigned long initrd_size,
92
static int kernel_magic_ok(struct setup_header *hdr)
90
struct setup_header *hdr;
92
hdr = (struct setup_header *)(image + SETUP_SECTS_OFF);
94
/* base address for real-mode segment */
95
setup_base = (void *)DEFAULT_SETUP_BASE;
97
94
if (KERNEL_MAGIC != hdr->boot_flag) {
98
printf("Error: Invalid Boot Flag (found 0x%04x, expected 0x%04x)\n",
99
hdr->boot_flag, KERNEL_MAGIC);
95
printf("Error: Invalid Boot Flag "
96
"(found 0x%04x, expected 0x%04x)\n",
97
hdr->boot_flag, KERNEL_MAGIC);
102
100
printf("Valid Boot Flag\n");
105
/* determine boot protocol version */
106
if (KERNEL_V2_MAGIC == hdr->header) {
105
static int get_boot_protocol(struct setup_header *hdr)
107
if (hdr->header == KERNEL_V2_MAGIC) {
107
108
printf("Magic signature found\n");
109
bootproto = hdr->version;
111
111
/* Very old kernel */
112
112
printf("Magic signature not found\n");
117
struct boot_params *load_zimage(char *image, unsigned long kernel_size,
120
struct boot_params *setup_base;
125
struct boot_params *params = (struct boot_params *)image;
126
struct setup_header *hdr = ¶ms->hdr;
128
/* base address for real-mode segment */
129
setup_base = (struct boot_params *)DEFAULT_SETUP_BASE;
131
if (!kernel_magic_ok(hdr))
116
134
/* determine size of setup */
117
135
if (0 == hdr->setup_sects) {
126
144
if (setup_size > SETUP_MAX_SIZE)
127
145
printf("Error: Setup is too large (%d bytes)\n", setup_size);
147
/* determine boot protocol version */
148
bootproto = get_boot_protocol(hdr);
150
printf("Using boot protocol version %x.%02x\n",
151
(bootproto & 0xff00) >> 8, bootproto & 0xff);
153
if (bootproto >= 0x0200) {
154
if (hdr->setup_sects >= 15) {
155
printf("Linux kernel version %s\n",
157
hdr->kernel_version + 0x200);
159
printf("Setup Sectors < 15 - "
160
"Cannot print kernel version.\n");
129
164
/* Determine image type */
130
165
big_image = (bootproto >= 0x0200) &&
131
166
(hdr->loadflags & BIG_KERNEL_FLAG);
133
168
/* Determine load address */
134
load_address = (void *)(big_image ?
170
*load_address = (void *)BZIMAGE_LOAD_ADDR;
172
*load_address = (void *)ZIMAGE_LOAD_ADDR;
174
#if defined CONFIG_ZBOOT_32
175
printf("Building boot_params at 0x%8.8lx\n", (ulong)setup_base);
176
memset(setup_base, 0, sizeof(*setup_base));
177
setup_base->hdr = params->hdr;
139
180
printf("Moving Real-Mode Code to 0x%8.8lx (%d bytes)\n",
140
181
(ulong)setup_base, setup_size);
141
182
memmove(setup_base, image, setup_size);
143
printf("Using boot protocol version %x.%02x\n",
144
(bootproto & 0xff00) >> 8, bootproto & 0xff);
185
if (bootproto >= 0x0204)
186
kernel_size = hdr->syssize * 16;
188
kernel_size -= setup_size;
146
190
if (bootproto == 0x0100) {
147
*(u16 *)(setup_base + CMD_LINE_MAGIC_OFF) = COMMAND_LINE_MAGIC;
148
*(u16 *)(setup_base + CMD_LINE_OFFSET_OFF) = COMMAND_LINE_OFFSET;
151
192
* A very old kernel MUST have its real-mode code
152
193
* loaded at 0x90000
158
199
/* Copy the command line */
159
200
memmove((void *)0x99000,
160
setup_base + COMMAND_LINE_OFFSET,
201
(u8 *)setup_base + COMMAND_LINE_OFFSET,
161
202
COMMAND_LINE_SIZE);
164
setup_base = (void *)0x90000;
205
setup_base = (struct boot_params *)0x90000;
167
208
/* It is recommended to clear memory up to the 32K mark */
168
memset((void *)0x90000 + setup_size, 0,
169
SETUP_MAX_SIZE-setup_size);
172
/* We are now setting up the real-mode version of the header */
173
hdr = (struct setup_header *)(setup_base + SETUP_SECTS_OFF);
209
memset((u8 *)0x90000 + setup_size, 0,
210
SETUP_MAX_SIZE - setup_size);
214
if (kernel_size > BZIMAGE_MAX_SIZE) {
215
printf("Error: bzImage kernel too big! "
216
"(size: %ld, max: %d)\n",
217
kernel_size, BZIMAGE_MAX_SIZE);
220
} else if ((kernel_size) > ZIMAGE_MAX_SIZE) {
221
printf("Error: zImage kernel too big! (size: %ld, max: %d)\n",
222
kernel_size, ZIMAGE_MAX_SIZE);
226
printf("Loading %s at address %p (%ld bytes)\n",
227
big_image ? "bzImage" : "zImage", *load_address, kernel_size);
229
memmove(*load_address, image + setup_size, kernel_size);
234
int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
235
unsigned long initrd_addr, unsigned long initrd_size)
237
struct setup_header *hdr = &setup_base->hdr;
238
int bootproto = get_boot_protocol(hdr);
240
#if defined CONFIG_ZBOOT_32
241
setup_base->e820_entries = install_e820_map(
242
ARRAY_SIZE(setup_base->e820_map), setup_base->e820_map);
245
if (bootproto == 0x0100) {
246
setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
247
setup_base->screen_info.cl_offset = COMMAND_LINE_OFFSET;
175
249
if (bootproto >= 0x0200) {
176
250
hdr->type_of_loader = 8;
178
if (hdr->setup_sects >= 15)
179
printf("Linux kernel version %s\n",
180
(char *)(setup_base +
181
(hdr->kernel_version + 0x200)));
183
printf("Setup Sectors < 15 - Cannot print kernel version.\n");
185
252
if (initrd_addr) {
186
printf("Initial RAM disk at linear address 0x%08lx, size %ld bytes\n",
253
printf("Initial RAM disk at linear address "
254
"0x%08lx, size %ld bytes\n",
187
255
initrd_addr, initrd_size);
189
257
hdr->ramdisk_image = initrd_addr;
199
267
if (bootproto >= 0x0202) {
200
hdr->cmd_line_ptr = (u32)setup_base + COMMAND_LINE_OFFSET;
268
hdr->cmd_line_ptr = (uintptr_t)cmd_line;
201
269
} else if (bootproto >= 0x0200) {
203
*(u16 *)(setup_base + CMD_LINE_MAGIC_OFF) = COMMAND_LINE_MAGIC;
204
*(u16 *)(setup_base + CMD_LINE_OFFSET_OFF) = COMMAND_LINE_OFFSET;
270
setup_base->screen_info.cl_magic = COMMAND_LINE_MAGIC;
271
setup_base->screen_info.cl_offset =
272
(uintptr_t)cmd_line - (uintptr_t)setup_base;
206
274
hdr->setup_move_size = 0x9100;
209
if (bootproto >= 0x0204)
210
kernel_size = hdr->syssize * 16;
212
kernel_size -= setup_size;
216
if ((kernel_size) > BZIMAGE_MAX_SIZE) {
217
printf("Error: bzImage kernel too big! (size: %ld, max: %d)\n",
218
kernel_size, BZIMAGE_MAX_SIZE);
222
} else if ((kernel_size) > ZIMAGE_MAX_SIZE) {
223
printf("Error: zImage kernel too big! (size: %ld, max: %d)\n",
224
kernel_size, ZIMAGE_MAX_SIZE);
228
277
/* build command line at COMMAND_LINE_OFFSET */
229
build_command_line(setup_base + COMMAND_LINE_OFFSET, auto_boot);
231
printf("Loading %czImage at address 0x%08x (%ld bytes)\n",
232
big_image ? 'b' : ' ', (u32)load_address, kernel_size);
235
memmove(load_address, image + setup_size, kernel_size);
237
/* ready for booting */
278
build_command_line(cmd_line, auto_boot);
241
void boot_zimage(void *setup_base)
282
void boot_zimage(void *setup_base, void *load_address)
284
printf("\nStarting kernel ...\n\n");
286
#if defined CONFIG_ZBOOT_32
288
* Set %ebx, %ebp, and %edi to 0, %esi to point to the boot_params
289
* structure, and then jump to the kernel. We assume that %cs is
290
* 0x10, 4GB flat, and read/execute, and the data segments are 0x18,
291
* 4GB flat, and read/write. U-boot is setting them up that way for
292
* itself in arch/i386/cpu/cpu.c.
294
__asm__ __volatile__ (
297
"jmp %[kernel_entry] \n"
298
:: [kernel_entry]"a"(load_address),
299
[boot_params] "S"(setup_base),
243
304
struct pt_regs regs;
245
306
memset(®s, 0, sizeof(struct pt_regs));
248
309
regs.xss = regs.xds;
249
310
regs.esp = 0x9000;
251
enter_realmode(((u32)setup_base+SETUP_START_OFFSET)>>4, 0, ®s,
312
enter_realmode(((u32)setup_base + SETUP_START_OFFSET) >> 4, 0,
317
void setup_pcat_compatibility(void)
318
__attribute__((weak, alias("__setup_pcat_compatibility")));
320
void __setup_pcat_compatibility(void)
255
324
int do_zboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
326
struct boot_params *base_ptr;
258
327
void *bzImage_addr = NULL;
260
330
ulong bzImage_size = 0;
331
ulong initrd_addr = 0;
332
ulong initrd_size = 0;
262
334
disable_interrupts();
264
336
/* Setup board for maximum PC/AT Compatibility */
265
337
setup_pcat_compatibility();
268
340
/* argv[1] holds the address of the bzImage */
271
343
s = getenv("fileaddr");
274
347
bzImage_addr = (void *)simple_strtoul(s, NULL, 16);
277
350
/* argv[2] holds the size of the bzImage */
278
351
bzImage_size = simple_strtoul(argv[2], NULL, 16);
281
base_ptr = load_zimage(bzImage_addr, bzImage_size, 0, 0, 0);
355
initrd_addr = simple_strtoul(argv[3], NULL, 16);
357
initrd_size = simple_strtoul(argv[4], NULL, 16);
360
base_ptr = load_zimage(bzImage_addr, bzImage_size, &load_address);
284
363
printf("## Kernel loading failed ...\n");
286
printf("## Transferring control to Linux (at address %08x) ...\n",
289
/* we assume that the kernel is in place */
290
printf("\nStarting kernel ...\n\n");
292
boot_zimage(base_ptr);
293
/* does not return */
366
if (setup_zimage(base_ptr, (char *)base_ptr + COMMAND_LINE_OFFSET,
367
0, initrd_addr, initrd_size)) {
368
printf("Setting up boot parameters failed ...\n");
372
printf("## Transferring control to Linux "
373
"(at address %08x) ...\n",
376
/* we assume that the kernel is in place */
377
boot_zimage(base_ptr, load_address);
378
/* does not return */
300
zboot, 2, 0, do_zboot,
384
zboot, 5, 0, do_zboot,
386
"[addr] [size] [initrd addr] [initrd size]\n"
387
" addr - The optional starting address of the bzimage.\n"
388
" If not set it defaults to the environment\n"
389
" variable \"fileaddr\".\n"
390
" size - The optional size of the bzimage. Defaults to\n"
392
" initrd addr - The address of the initrd image to use, if any.\n"
393
" initrd size - The size of the initrd image to use, if any.\n"