]> git.proxmox.com Git - grub2.git/blame - loader/multiboot_loader.c
merge from trunk
[grub2.git] / loader / multiboot_loader.c
CommitLineData
bc8b32b3 1/* multiboot_loader.c - boot multiboot kernel image */
e5dfe777 2/*
3 * GRUB -- GRand Unified Bootloader
bc8b32b3 4 * Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc.
e5dfe777 5 *
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
18 */
19
e5dfe777 20#include <grub/multiboot.h>
e5dfe777 21#include <grub/elf.h>
22#include <grub/file.h>
23#include <grub/err.h>
e5dfe777 24#include <grub/dl.h>
25#include <grub/mm.h>
26#include <grub/misc.h>
27#include <grub/gzio.h>
b1b797cb 28#include <grub/command.h>
809bbfeb 29#include <grub/i18n.h>
e5dfe777 30
31grub_dl_t my_mod;
32
e5dfe777 33static int
34find_multi_boot1_header (grub_file_t file)
35{
8d0edf4a 36 struct multiboot_header *header;
e5dfe777 37 char buffer[MULTIBOOT_SEARCH];
38 int found_status = 0;
39 grub_ssize_t len;
b39f9d20 40
e5dfe777 41 len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
42 if (len < 32)
43 return found_status;
44
45 /* Look for the multiboot header in the buffer. The header should
46 be at least 12 bytes and aligned on a 4-byte boundary. */
8d0edf4a 47 for (header = (struct multiboot_header *) buffer;
e5dfe777 48 ((char *) header <= buffer + len - 12) || (header = 0);
8d0edf4a 49 header = (struct multiboot_header *) ((char *) header + 4))
e5dfe777 50 {
e4d47d8d 51 if (header->magic == MULTIBOOT_HEADER_MAGIC
e5dfe777 52 && !(header->magic + header->flags + header->checksum))
53 {
54 found_status = 1;
55 break;
56 }
57 }
58
59 return found_status;
60}
61
b1b797cb 62static grub_err_t
63grub_cmd_multiboot_loader (grub_command_t cmd __attribute__ ((unused)),
64 int argc, char *argv[])
e5dfe777 65{
e5dfe777 66 grub_file_t file = 0;
67 int header_multi_ver_found = 0;
68
69 grub_dl_ref (my_mod);
70
71 if (argc == 0)
72 {
7fd0baee 73 grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
e5dfe777 74 goto fail;
75 }
76
77 file = grub_gzfile_open (argv[0], 1);
78 if (! file)
79 {
7fd0baee 80 grub_error (GRUB_ERR_BAD_ARGUMENT, "couldn't open file");
e5dfe777 81 goto fail;
82 }
83
84 /* find which header is in the file */
c32ee8c9 85 if (find_multi_boot1_header (file))
e5dfe777 86 header_multi_ver_found = 1;
87 else
88 {
7fd0baee 89 grub_error (GRUB_ERR_BAD_OS, "multiboot header not found");
c32ee8c9 90 goto fail;
e5dfe777 91 }
92
1bc09c35 93 /* close file before calling functions */
94 if (file)
95 grub_file_close (file);
e5dfe777 96
1bc09c35 97 /* Launch multi boot with header */
e5dfe777 98
bc8b32b3
RM
99 grub_dprintf ("multiboot_loader",
100 "Launching multiboot 1 grub_multiboot() function\n");
101 grub_multiboot (argc, argv);
e5dfe777 102
1bc09c35 103 return grub_errno;
e5dfe777 104
105fail:
106 if (file)
1bc09c35 107 grub_file_close (file);
e5dfe777 108
109 grub_dl_unref (my_mod);
b1b797cb 110
111 return grub_errno;
e5dfe777 112}
113
b1b797cb 114static grub_err_t
115grub_cmd_module_loader (grub_command_t cmd __attribute__ ((unused)),
116 int argc, char *argv[])
e5dfe777 117{
118
bc8b32b3
RM
119 grub_dprintf("multiboot_loader",
120 "Launching multiboot 1 grub_module() function\n");
121 grub_module (argc, argv);
b1b797cb 122
123 return grub_errno;
e5dfe777 124}
125
b1b797cb 126static grub_command_t cmd_multiboot, cmd_module;
127
e5dfe777 128GRUB_MOD_INIT(multiboot)
129{
b1b797cb 130 cmd_multiboot =
bc8b32b3
RM
131#ifdef GRUB_USE_MULTIBOOT2
132 grub_register_command ("multiboot2", grub_cmd_multiboot_loader,
809bbfeb 133 0, N_("Load a multiboot 2 kernel."));
bc8b32b3 134#else
b1b797cb 135 grub_register_command ("multiboot", grub_cmd_multiboot_loader,
809bbfeb 136 0, N_("Load a multiboot kernel."));
bc8b32b3
RM
137#endif
138
b1b797cb 139 cmd_module =
140 grub_register_command ("module", grub_cmd_module_loader,
809bbfeb 141 0, N_("Load a multiboot module."));
e5dfe777 142
143 my_mod = mod;
144}
145
146GRUB_MOD_FINI(multiboot)
147{
b1b797cb 148 grub_unregister_command (cmd_multiboot);
149 grub_unregister_command (cmd_module);
e5dfe777 150}