2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
5
* GRUB is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 3 of the License, or
8
* (at your option) any later version.
10
* GRUB is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
19
#include <grub/loader.h>
20
#include <grub/memory.h>
21
#include <grub/normal.h>
22
#include <grub/file.h>
23
#include <grub/disk.h>
25
#include <grub/misc.h>
26
#include <grub/types.h>
29
#include <grub/term.h>
30
#include <grub/cpu/linux.h>
31
#include <grub/video.h>
32
#include <grub/video_fb.h>
33
#include <grub/command.h>
34
#include <grub/i386/relocator.h>
35
#include <grub/i18n.h>
36
#include <grub/lib/cmdline.h>
38
GRUB_MOD_LICENSE ("GPLv3+");
40
#ifdef GRUB_MACHINE_PCBIOS
41
#include <grub/i386/pc/vesa_modes_table.h>
44
#ifdef GRUB_MACHINE_EFI
45
#include <grub/efi/efi.h>
46
#define HAS_VGA_TEXT 0
47
#define DEFAULT_VIDEO_MODE "auto"
48
#define ACCEPTS_PURE_TEXT 0
49
#elif defined (GRUB_MACHINE_IEEE1275)
50
#include <grub/ieee1275/ieee1275.h>
51
#define HAS_VGA_TEXT 0
52
#define DEFAULT_VIDEO_MODE "text"
53
#define ACCEPTS_PURE_TEXT 1
55
#include <grub/i386/pc/vbe.h>
56
#include <grub/i386/pc/console.h>
57
#define HAS_VGA_TEXT 1
58
#define DEFAULT_VIDEO_MODE "text"
59
#define ACCEPTS_PURE_TEXT 1
62
static grub_dl_t my_mod;
64
static grub_size_t linux_mem_size;
66
static void *prot_mode_mem;
67
static grub_addr_t prot_mode_target;
68
static void *initrd_mem;
69
static grub_addr_t initrd_mem_target;
70
static grub_size_t prot_init_space;
71
static grub_uint32_t initrd_pages;
72
static struct grub_relocator *relocator = NULL;
73
static void *efi_mmap_buf;
74
static grub_size_t maximal_cmdline_size;
75
static struct linux_kernel_params linux_params;
76
static char *linux_cmdline;
77
#ifdef GRUB_MACHINE_EFI
78
static int using_linuxefi;
79
static grub_command_t initrdefi_cmd;
80
static grub_efi_uintn_t efi_mmap_size;
82
static const grub_size_t efi_mmap_size = 0;
91
} __attribute__ ((packed));
93
static struct idt_descriptor idt_desc =
100
static inline grub_size_t
101
page_align (grub_size_t size)
103
return (size + (1 << 12) - 1) & (~((1 << 12) - 1));
106
#ifdef GRUB_MACHINE_EFI
107
/* Find the optimal number of pages for the memory map. Is it better to
108
move this code to efi/mm.c? */
109
static grub_efi_uintn_t
110
find_efi_mmap_size (void)
112
static grub_efi_uintn_t mmap_size = 0;
117
mmap_size = (1 << 12);
121
grub_efi_memory_descriptor_t *mmap;
122
grub_efi_uintn_t desc_size;
123
grub_efi_uintn_t cur_mmap_size = mmap_size;
125
mmap = grub_malloc (cur_mmap_size);
129
ret = grub_efi_get_memory_map (&cur_mmap_size, mmap, 0, &desc_size, 0);
134
grub_error (GRUB_ERR_IO, "cannot get memory map");
140
if (mmap_size < cur_mmap_size)
141
mmap_size = cur_mmap_size;
142
mmap_size += (1 << 12);
145
/* Increase the size a bit for safety, because GRUB allocates more on
146
later, and EFI itself may allocate more. */
147
mmap_size += (3 << 12);
149
mmap_size = page_align (mmap_size);
155
/* Find the optimal number of pages for the memory map. */
157
find_mmap_size (void)
159
grub_size_t count = 0, mmap_size;
161
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
163
int NESTED_FUNC_ATTR hook (grub_uint64_t addr __attribute__ ((unused)),
164
grub_uint64_t size __attribute__ ((unused)),
165
grub_memory_type_t type __attribute__ ((unused)))
171
grub_mmap_iterate (hook);
173
mmap_size = count * sizeof (struct grub_e820_mmap);
175
/* Increase the size a bit for safety, because GRUB allocates more on
177
mmap_size += (1 << 12);
179
return page_align (mmap_size);
185
grub_relocator_unload (relocator);
187
prot_mode_mem = initrd_mem = 0;
188
prot_mode_target = initrd_mem_target = 0;
191
/* Allocate pages for the real mode code and the protected mode code
192
for linux as well as a memory map buffer. */
194
allocate_pages (grub_size_t prot_size, grub_size_t *align,
195
grub_size_t min_align, int relocatable,
196
grub_uint64_t prefered_address)
200
prot_size = page_align (prot_size);
202
/* Initialize the memory pointers with NULL for convenience. */
205
relocator = grub_relocator_new ();
212
/* FIXME: Should request low memory from the heap when this feature is
216
grub_relocator_chunk_t ch;
219
err = grub_relocator_alloc_chunk_align (relocator, &ch,
223
GRUB_RELOCATOR_PREFERENCE_LOW,
225
for (; err && *align + 1 > min_align; (*align)--)
227
grub_errno = GRUB_ERR_NONE;
228
err = grub_relocator_alloc_chunk_align (relocator, &ch,
230
0xffffffff & ~prot_size,
231
prot_size, 1 << *align,
232
GRUB_RELOCATOR_PREFERENCE_LOW,
239
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
244
prot_mode_mem = get_virtual_current_address (ch);
245
prot_mode_target = get_physical_target_address (ch);
248
grub_dprintf ("linux", "prot_mode_mem = %lx, prot_mode_target = %lx, prot_size = %x\n",
249
(unsigned long) prot_mode_mem, (unsigned long) prot_mode_target,
250
(unsigned) prot_size);
251
return GRUB_ERR_NONE;
259
grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num,
260
grub_uint64_t start, grub_uint64_t size,
265
if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) &&
266
(e820_map[n - 1].type == type))
267
e820_map[n - 1].size += size;
270
e820_map[n].addr = start;
271
e820_map[n].size = size;
272
e820_map[n].type = type;
275
return GRUB_ERR_NONE;
279
grub_linux_setup_video (struct linux_kernel_params *params)
281
struct grub_video_mode_info mode_info;
284
grub_video_driver_id_t driver_id;
285
const char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb");
287
driver_id = grub_video_get_driver_id ();
289
if (driver_id == GRUB_VIDEO_DRIVER_NONE)
292
err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
296
grub_errno = GRUB_ERR_NONE;
300
params->lfb_width = mode_info.width;
301
params->lfb_height = mode_info.height;
302
params->lfb_depth = mode_info.bpp;
303
params->lfb_line_len = mode_info.pitch;
305
params->lfb_base = (grub_size_t) framebuffer;
306
params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536);
308
params->red_mask_size = mode_info.red_mask_size;
309
params->red_field_pos = mode_info.red_field_pos;
310
params->green_mask_size = mode_info.green_mask_size;
311
params->green_field_pos = mode_info.green_field_pos;
312
params->blue_mask_size = mode_info.blue_mask_size;
313
params->blue_field_pos = mode_info.blue_field_pos;
314
params->reserved_mask_size = mode_info.reserved_mask_size;
315
params->reserved_field_pos = mode_info.reserved_field_pos;
317
if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y'))
318
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
323
case GRUB_VIDEO_DRIVER_VBE:
324
params->lfb_size >>= 16;
325
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
328
case GRUB_VIDEO_DRIVER_EFI_UGA:
329
case GRUB_VIDEO_DRIVER_EFI_GOP:
330
params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB;
333
/* FIXME: check if better id is available. */
334
case GRUB_VIDEO_DRIVER_SM712:
335
case GRUB_VIDEO_DRIVER_SIS315PRO:
336
case GRUB_VIDEO_DRIVER_VGA:
337
case GRUB_VIDEO_DRIVER_CIRRUS:
338
case GRUB_VIDEO_DRIVER_BOCHS:
339
case GRUB_VIDEO_DRIVER_RADEON_FULOONG2E:
340
/* Make gcc happy. */
341
case GRUB_VIDEO_DRIVER_SDL:
342
case GRUB_VIDEO_DRIVER_NONE:
343
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
348
#ifdef GRUB_MACHINE_PCBIOS
349
/* VESA packed modes may come with zeroed mask sizes, which need
350
to be set here according to DAC Palette width. If we don't,
351
this results in Linux displaying a black screen. */
352
if (driver_id == GRUB_VIDEO_DRIVER_VBE && mode_info.bpp <= 8)
354
struct grub_vbe_info_block controller_info;
358
status = grub_vbe_bios_get_controller_info (&controller_info);
360
if (status == GRUB_VBE_STATUS_OK &&
361
(controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH))
362
status = grub_vbe_bios_set_dac_palette_width (&width);
364
if (status != GRUB_VBE_STATUS_OK)
365
/* 6 is default after mode reset. */
368
params->red_mask_size = params->green_mask_size
369
= params->blue_mask_size = width;
370
params->reserved_mask_size = 0;
374
return GRUB_ERR_NONE;
378
grub_linux_boot (void)
384
struct grub_relocator32_state state;
386
grub_addr_t real_mode_target = 0;
387
grub_size_t real_size, mmap_size;
388
grub_size_t cl_offset;
390
#ifdef GRUB_MACHINE_IEEE1275
392
const char *bootpath;
395
bootpath = grub_env_get ("root");
397
grub_ieee1275_set_property (grub_ieee1275_chosen,
398
"bootpath", bootpath,
399
grub_strlen (bootpath) + 1,
401
linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE;
402
linux_params.ofw_num_items = 1;
403
linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn;
404
linux_params.ofw_idt = 0;
408
modevar = grub_env_get ("gfxpayload");
410
/* Now all graphical modes are acceptable.
411
May change in future if we have modes without framebuffer. */
412
if (modevar && *modevar != 0)
414
tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar);
417
#if ACCEPTS_PURE_TEXT
418
err = grub_video_set_mode (tmp, 0, 0);
420
err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
426
#if ACCEPTS_PURE_TEXT
427
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0);
429
err = grub_video_set_mode (DEFAULT_VIDEO_MODE,
430
GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0);
437
grub_puts_ (N_("Booting in blind mode"));
438
grub_errno = GRUB_ERR_NONE;
441
if (grub_linux_setup_video (&linux_params))
443
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
444
linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
445
linux_params.video_mode = 0x3;
447
linux_params.have_vga = 0;
448
linux_params.video_mode = 0;
449
linux_params.video_width = 0;
450
linux_params.video_height = 0;
455
#ifndef GRUB_MACHINE_IEEE1275
456
if (linux_params.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT)
459
grub_term_output_t term;
461
FOR_ACTIVE_TERM_OUTPUTS(term)
462
if (grub_strcmp (term->name, "vga_text") == 0
463
|| grub_strcmp (term->name, "console") == 0
464
|| grub_strcmp (term->name, "ofconsole") == 0)
466
grub_uint16_t pos = grub_term_getxy (term);
467
linux_params.video_cursor_x = pos >> 8;
468
linux_params.video_cursor_y = pos & 0xff;
469
linux_params.video_width = grub_term_width (term);
470
linux_params.video_height = grub_term_height (term);
476
linux_params.video_cursor_x = 0;
477
linux_params.video_cursor_y = 0;
478
linux_params.video_width = 80;
479
linux_params.video_height = 25;
483
mmap_size = find_mmap_size ();
484
/* Make sure that each size is aligned to a page boundary. */
485
cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096);
486
if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS))
487
cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects
488
<< GRUB_DISK_SECTOR_BITS), 4096);
489
real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096);
491
#ifdef GRUB_MACHINE_EFI
492
efi_mmap_size = find_efi_mmap_size ();
493
if (efi_mmap_size == 0)
497
grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n",
498
(unsigned) real_size, (unsigned) mmap_size);
500
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
502
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
503
grub_memory_type_t type)
505
/* We must put real mode code in the traditional space. */
506
if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000)
509
if (addr + size < 0x10000)
514
size += addr - 0x10000;
518
if (addr + size > 0x90000)
519
size = 0x90000 - addr;
521
if (real_size + efi_mmap_size > size)
524
grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n",
525
(unsigned long) addr,
527
(unsigned) (real_size + efi_mmap_size));
528
real_mode_target = ((addr + size) - (real_size + efi_mmap_size));
531
#ifdef GRUB_MACHINE_EFI
532
grub_efi_mmap_iterate (hook, 1);
533
if (! real_mode_target)
534
grub_efi_mmap_iterate (hook, 0);
536
grub_mmap_iterate (hook);
538
grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n",
539
(unsigned long) real_mode_target,
540
(unsigned) real_size,
541
(unsigned) efi_mmap_size);
543
if (! real_mode_target)
544
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages");
547
grub_relocator_chunk_t ch;
548
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
550
(real_size + efi_mmap_size));
553
real_mode_mem = get_virtual_current_address (ch);
555
efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size;
557
grub_dprintf ("linux", "real_mode_mem = %lx\n",
558
(unsigned long) real_mode_mem);
560
struct linux_kernel_params *params;
562
params = real_mode_mem;
564
*params = linux_params;
565
params->cmd_line_ptr = real_mode_target + cl_offset;
566
grub_memcpy ((char *) params + cl_offset, linux_cmdline,
567
maximal_cmdline_size);
569
grub_dprintf ("linux", "code32_start = %x\n",
570
(unsigned) params->code32_start);
572
auto int NESTED_FUNC_ATTR hook_fill (grub_uint64_t, grub_uint64_t,
574
int NESTED_FUNC_ATTR hook_fill (grub_uint64_t addr, grub_uint64_t size,
575
grub_memory_type_t type)
577
grub_uint32_t e820_type;
580
case GRUB_MEMORY_AVAILABLE:
581
e820_type = GRUB_E820_RAM;
584
case GRUB_MEMORY_ACPI:
585
e820_type = GRUB_E820_ACPI;
588
case GRUB_MEMORY_NVS:
589
e820_type = GRUB_E820_NVS;
592
case GRUB_MEMORY_BADRAM:
593
e820_type = GRUB_E820_BADRAM;
597
e820_type = GRUB_E820_RESERVED;
599
if (grub_e820_add_region (params->e820_map, &e820_num,
600
addr, size, e820_type))
607
if (grub_mmap_iterate (hook_fill))
609
params->mmap_size = e820_num;
611
#ifdef GRUB_MACHINE_EFI
613
grub_efi_uintn_t efi_desc_size;
614
grub_size_t efi_mmap_target;
615
grub_efi_uint32_t efi_desc_version;
616
err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL,
617
&efi_desc_size, &efi_desc_version);
621
/* Note that no boot services are available from here. */
622
efi_mmap_target = real_mode_target
623
+ ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem);
624
/* Pass EFI parameters. */
625
if (grub_le_to_cpu16 (params->version) >= 0x0208)
627
params->v0208.efi_mem_desc_size = efi_desc_size;
628
params->v0208.efi_mem_desc_version = efi_desc_version;
629
params->v0208.efi_mmap = efi_mmap_target;
630
params->v0208.efi_mmap_size = efi_mmap_size;
633
params->v0208.efi_mmap_hi = (efi_mmap_target >> 32);
636
else if (grub_le_to_cpu16 (params->version) >= 0x0206)
638
params->v0206.efi_mem_desc_size = efi_desc_size;
639
params->v0206.efi_mem_desc_version = efi_desc_version;
640
params->v0206.efi_mmap = efi_mmap_target;
641
params->v0206.efi_mmap_size = efi_mmap_size;
643
else if (grub_le_to_cpu16 (params->version) >= 0x0204)
645
params->v0204.efi_mem_desc_size = efi_desc_size;
646
params->v0204.efi_mem_desc_version = efi_desc_version;
647
params->v0204.efi_mmap = efi_mmap_target;
648
params->v0204.efi_mmap_size = efi_mmap_size;
654
/* asm volatile ("lidt %0" : : "m" (idt_desc)); */
655
state.ebp = state.edi = state.ebx = 0;
656
state.esi = real_mode_target;
657
state.esp = real_mode_target;
658
state.eip = params->code32_start;
659
return grub_relocator32_boot (relocator, state, 0);
663
grub_linux_unload (void)
665
grub_dl_unref (my_mod);
667
grub_free (linux_cmdline);
669
return GRUB_ERR_NONE;
673
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
674
int argc, char *argv[])
676
grub_file_t file = 0;
677
struct linux_kernel_header lh;
678
struct linux_kernel_params *params;
679
grub_uint8_t setup_sects;
680
grub_size_t real_size, prot_size, prot_file_size;
683
grub_size_t align, min_align;
685
grub_uint64_t preffered_address = GRUB_LINUX_BZIMAGE_ADDR;
687
grub_dl_ref (my_mod);
689
#ifdef GRUB_MACHINE_EFI
691
if (grub_efi_secure_boot ())
693
/* Try linuxefi first, which will require a successful signature check
694
and then hand over to the kernel without calling ExitBootServices.
695
If that fails, however, fall back to calling ExitBootServices
696
ourselves and then booting an unsigned kernel. */
698
grub_command_t linuxefi_cmd;
700
grub_dprintf ("linux", "Secure Boot enabled: trying linuxefi\n");
702
mod = grub_dl_load ("linuxefi");
706
linuxefi_cmd = grub_command_find ("linuxefi");
707
initrdefi_cmd = grub_command_find ("initrdefi");
708
if (linuxefi_cmd && initrdefi_cmd)
710
(linuxefi_cmd->func) (linuxefi_cmd, argc, argv);
711
if (grub_errno == GRUB_ERR_NONE)
713
grub_dprintf ("linux", "Handing off to linuxefi\n");
715
return GRUB_ERR_NONE;
717
grub_dprintf ("linux", "linuxefi failed (%d)\n", grub_errno);
718
grub_errno = GRUB_ERR_NONE;
726
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
730
file = grub_file_open (argv[0]);
734
if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
737
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
742
if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
744
grub_error (GRUB_ERR_BAD_OS, "invalid magic number");
748
if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
750
grub_error (GRUB_ERR_BAD_OS, "too many setup sectors");
754
/* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and
755
still not support 32-bit boot. */
756
if (lh.header != grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
757
|| grub_le_to_cpu16 (lh.version) < 0x0203)
759
grub_error (GRUB_ERR_BAD_OS, "version too old for 32-bit boot"
760
#ifdef GRUB_MACHINE_PCBIOS
761
" (try with `linux16')"
767
if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL))
769
grub_error (GRUB_ERR_BAD_OS, "zImage doesn't support 32-bit boot"
770
#ifdef GRUB_MACHINE_PCBIOS
771
" (try with `linux16')"
777
if (grub_le_to_cpu16 (lh.version) >= 0x0206)
778
maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1;
780
maximal_cmdline_size = 256;
782
if (maximal_cmdline_size < 128)
783
maximal_cmdline_size = 128;
785
setup_sects = lh.setup_sects;
787
/* If SETUP_SECTS is not set, set it to the default (4). */
789
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
791
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
792
prot_file_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
794
if (grub_le_to_cpu16 (lh.version) >= 0x205
795
&& lh.kernel_alignment != 0
796
&& ((lh.kernel_alignment - 1) & lh.kernel_alignment) == 0)
798
for (align = 0; align < 32; align++)
799
if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align))
801
relocatable = grub_le_to_cpu32 (lh.relocatable);
809
if (grub_le_to_cpu16 (lh.version) >= 0x020a)
811
min_align = lh.min_alignment;
812
prot_size = grub_le_to_cpu32 (lh.init_size);
813
prot_init_space = page_align (prot_size);
815
preffered_address = grub_le_to_cpu64 (lh.pref_address);
817
preffered_address = GRUB_LINUX_BZIMAGE_ADDR;
822
prot_size = prot_file_size;
823
preffered_address = GRUB_LINUX_BZIMAGE_ADDR;
824
/* Usually, the compression ratio is about 50%. */
825
prot_init_space = page_align (prot_size) * 3;
828
if (allocate_pages (prot_size, &align,
829
min_align, relocatable,
833
params = (struct linux_kernel_params *) &linux_params;
834
grub_memset (params, 0, sizeof (*params));
835
grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
837
params->code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
838
params->kernel_alignment = (1 << align);
839
params->ps_mouse = params->padding10 = 0;
841
len = sizeof (*params) - sizeof (lh);
842
if (grub_file_read (file, (char *) params + sizeof (lh), len) != len)
845
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
850
params->type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
852
/* These two are used (instead of cmd_line_ptr) by older versions of Linux,
853
and otherwise ignored. */
854
params->cl_magic = GRUB_LINUX_CL_MAGIC;
855
params->cl_offset = 0x1000;
857
params->ramdisk_image = 0;
858
params->ramdisk_size = 0;
860
params->heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET;
861
params->loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
863
/* These are not needed to be precise, because Linux uses these values
864
only to raise an error when the decompression code cannot find good
866
params->ext_mem = ((32 * 0x100000) >> 10);
867
params->alt_mem = ((32 * 0x100000) >> 10);
869
/* Ignored by Linux. */
870
params->video_page = 0;
872
/* Only used when `video_mode == 0x7', otherwise ignored. */
873
params->video_ega_bx = 0;
875
params->font_size = 16; /* XXX */
877
#ifdef GRUB_MACHINE_EFI
879
if (grub_le_to_cpu16 (params->version < 0x0208) &&
880
((grub_addr_t) grub_efi_system_table >> 32) != 0)
881
return grub_error(GRUB_ERR_BAD_OS,
882
"kernel does not support 64-bit addressing");
885
if (grub_le_to_cpu16 (params->version) >= 0x0208)
887
params->v0208.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
888
params->v0208.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
890
params->v0208.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32);
893
else if (grub_le_to_cpu16 (params->version) >= 0x0206)
895
params->v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE;
896
params->v0206.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
898
else if (grub_le_to_cpu16 (params->version) >= 0x0204)
900
params->v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204;
901
params->v0204.efi_system_table = (grub_uint32_t) (unsigned long) grub_efi_system_table;
905
/* The other parameters are filled when booting. */
907
grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE);
909
grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n",
910
(unsigned) real_size, (unsigned) prot_size);
912
/* Look for memory size and video mode specified on the command line. */
914
for (i = 1; i < argc; i++)
915
#ifdef GRUB_MACHINE_PCBIOS
916
if (grub_memcmp (argv[i], "vga=", 4) == 0)
918
/* Video mode selection support. */
919
char *val = argv[i] + 4;
920
unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
921
struct grub_vesa_mode_table_entry *linux_mode;
925
grub_dl_load ("vbe");
927
if (grub_strcmp (val, "normal") == 0)
928
vid_mode = GRUB_LINUX_VID_MODE_NORMAL;
929
else if (grub_strcmp (val, "ext") == 0)
930
vid_mode = GRUB_LINUX_VID_MODE_EXTENDED;
931
else if (grub_strcmp (val, "ask") == 0)
933
grub_puts_ (N_("Legacy `ask' parameter no longer supported."));
935
/* We usually would never do this in a loader, but "vga=ask" means user
936
requested interaction, so it can't hurt to request keyboard input. */
937
grub_wait_after_message ();
942
vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0);
947
case GRUB_LINUX_VID_MODE_NORMAL:
948
grub_env_set ("gfxpayload", "text");
949
grub_printf_ (N_("%s is deprecated. "
950
"Use set gfxpayload=%s before "
951
"linux command instead.\n"), "text",
956
case GRUB_LINUX_VID_MODE_EXTENDED:
957
/* FIXME: support 80x50 text. */
958
grub_env_set ("gfxpayload", "text");
959
grub_printf_ (N_("%s is deprecated. "
960
"Use set gfxpayload=%s before "
961
"linux command instead.\n"), "text",
965
/* Ignore invalid values. */
966
if (vid_mode < GRUB_VESA_MODE_TABLE_START ||
967
vid_mode > GRUB_VESA_MODE_TABLE_END)
969
grub_env_set ("gfxpayload", "text");
970
/* TRANSLATORS: "x" has to be entered in, like an identifier,
971
so please don't use better Unicode codepoints. */
972
grub_printf_ (N_("%s is deprecated. VGA mode %d isn't recognized. "
973
"Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] "
974
"before linux command instead.\n"),
979
linux_mode = &grub_vesa_mode_table[vid_mode
980
- GRUB_VESA_MODE_TABLE_START];
982
buf = grub_xasprintf ("%ux%ux%u,%ux%u",
983
linux_mode->width, linux_mode->height,
985
linux_mode->width, linux_mode->height);
989
grub_printf_ (N_("%s is deprecated. "
990
"Use set gfxpayload=%s before "
991
"linux command instead.\n"),
993
err = grub_env_set ("gfxpayload", buf);
1000
#endif /* GRUB_MACHINE_PCBIOS */
1001
if (grub_memcmp (argv[i], "mem=", 4) == 0)
1003
char *val = argv[i] + 4;
1005
linux_mem_size = grub_strtoul (val, &val, 0);
1009
grub_errno = GRUB_ERR_NONE;
1016
switch (grub_tolower (val[0]))
1028
/* Check an overflow. */
1029
if (linux_mem_size > (~0UL >> shift))
1032
linux_mem_size <<= shift;
1035
else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0)
1037
params->loadflags |= GRUB_LINUX_FLAG_QUIET;
1040
/* Create kernel command line. */
1041
linux_cmdline = grub_zalloc (maximal_cmdline_size + 1);
1044
grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
1045
grub_create_loader_cmdline (argc, argv,
1047
+ sizeof (LINUX_IMAGE) - 1,
1048
maximal_cmdline_size
1049
- (sizeof (LINUX_IMAGE) - 1));
1051
len = prot_file_size;
1052
if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno)
1053
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
1056
if (grub_errno == GRUB_ERR_NONE)
1058
grub_loader_set (grub_linux_boot, grub_linux_unload,
1059
0 /* set noreturn=0 in order to avoid grub_console_fini() */);
1066
grub_file_close (file);
1068
if (grub_errno != GRUB_ERR_NONE)
1070
grub_dl_unref (my_mod);
1078
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
1079
int argc, char *argv[])
1081
grub_file_t *files = 0;
1082
grub_size_t size = 0;
1083
grub_addr_t addr_min, addr_max;
1090
#ifdef GRUB_MACHINE_EFI
1091
/* If we're using linuxefi, just forward to initrdefi. */
1092
if (using_linuxefi && initrdefi_cmd)
1093
return (initrdefi_cmd->func) (initrdefi_cmd, argc, argv);
1098
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
1104
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
1108
files = grub_zalloc (argc * sizeof (files[0]));
1112
for (i = 0; i < argc; i++)
1114
grub_file_filter_disable_compression ();
1115
files[i] = grub_file_open (argv[i]);
1119
size += ALIGN_UP (grub_file_size (files[i]), 4);
1122
initrd_pages = (page_align (size) >> 12);
1124
/* Get the highest address available for the initrd. */
1125
if (grub_le_to_cpu16 (linux_params.version) >= 0x0203)
1127
addr_max = grub_cpu_to_le32 (linux_params.initrd_addr_max);
1129
/* XXX in reality, Linux specifies a bogus value, so
1130
it is necessary to make sure that ADDR_MAX does not exceed
1132
if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS)
1133
addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
1136
addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
1138
if (linux_mem_size != 0 && linux_mem_size < addr_max)
1139
addr_max = linux_mem_size;
1141
/* Linux 2.3.xx has a bug in the memory range check, so avoid
1143
Linux 2.2.xx has a bug in the memory range check, which is
1144
worse than that of Linux 2.3.xx, so avoid the last 64kb. */
1145
addr_max -= 0x10000;
1147
addr_min = (grub_addr_t) prot_mode_target + prot_init_space
1148
+ page_align (size);
1150
/* Put the initrd as high as possible, 4KiB aligned. */
1151
addr = (addr_max - size) & ~0xFFF;
1153
if (addr < addr_min)
1155
grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big");
1160
grub_relocator_chunk_t ch;
1161
err = grub_relocator_alloc_chunk_align (relocator, &ch,
1162
addr_min, addr, size, 0x1000,
1163
GRUB_RELOCATOR_PREFERENCE_HIGH,
1167
initrd_mem = get_virtual_current_address (ch);
1168
initrd_mem_target = get_physical_target_address (ch);
1172
for (i = 0; i < nfiles; i++)
1174
grub_ssize_t cursize = grub_file_size (files[i]);
1175
if (grub_file_read (files[i], ptr, cursize) != cursize)
1178
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
1183
grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
1184
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
1187
grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n",
1188
(unsigned) addr, (unsigned) size);
1190
linux_params.ramdisk_image = initrd_mem_target;
1191
linux_params.ramdisk_size = size;
1192
linux_params.root_dev = 0x0100; /* XXX */
1195
for (i = 0; i < nfiles; i++)
1196
grub_file_close (files[i]);
1202
static grub_command_t cmd_linux, cmd_initrd;
1204
GRUB_MOD_INIT(linux)
1206
cmd_linux = grub_register_command ("linux", grub_cmd_linux,
1207
0, N_("Load Linux."));
1208
cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd,
1209
0, N_("Load initrd."));
1213
GRUB_MOD_FINI(linux)
1215
grub_unregister_command (cmd_linux);
1216
grub_unregister_command (cmd_initrd);