]> git.proxmox.com Git - grub2.git/blame - grub-core/loader/i386/pc/ntldr.c
verifiers: File type for fine-grained signature-verification controlling
[grub2.git] / grub-core / loader / i386 / pc / ntldr.c
CommitLineData
b883356c
VS
1/* chainloader.c - boot another boot loader */
2/*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2004,2007,2009,2010 Free Software Foundation, Inc.
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
20#include <grub/loader.h>
21#include <grub/file.h>
22#include <grub/err.h>
23#include <grub/device.h>
24#include <grub/disk.h>
25#include <grub/misc.h>
26#include <grub/types.h>
27#include <grub/partition.h>
28#include <grub/dl.h>
29#include <grub/command.h>
30#include <grub/machine/biosnum.h>
31#include <grub/i18n.h>
32#include <grub/video.h>
33#include <grub/mm.h>
34#include <grub/cpu/relocator.h>
b38a4983 35#include <grub/machine/chainloader.h>
b883356c 36
e745cf0c
VS
37GRUB_MOD_LICENSE ("GPLv3+");
38
b883356c
VS
39static grub_dl_t my_mod;
40static struct grub_relocator *rel;
dae84898 41static grub_uint32_t edx = 0xffffffff;
b883356c
VS
42
43#define GRUB_NTLDR_SEGMENT 0x2000
44
45static grub_err_t
46grub_ntldr_boot (void)
47{
48 struct grub_relocator16_state state = {
49 .cs = GRUB_NTLDR_SEGMENT,
dae84898
VS
50 .ip = 0,
51 .ds = 0,
52 .es = 0,
53 .fs = 0,
54 .gs = 0,
55 .ss = 0,
56 .sp = 0x7c00,
db1326f5
VS
57 .edx = edx,
58 .a20 = 1
b883356c
VS
59 };
60 grub_video_set_mode ("text", 0, 0);
61
62 return grub_relocator16_boot (rel, state);
63}
64
65static grub_err_t
66grub_ntldr_unload (void)
67{
68 grub_relocator_unload (rel);
69 rel = NULL;
70 grub_dl_unref (my_mod);
71 return GRUB_ERR_NONE;
72}
73
74static grub_err_t
75grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
76 int argc, char *argv[])
77{
78 grub_file_t file = 0;
79 grub_err_t err;
80 void *bs, *ntldr;
81 grub_size_t ntldrsize;
82 grub_device_t dev;
83
84 if (argc == 0)
9c4b5c13 85 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
b883356c
VS
86
87 grub_dl_ref (my_mod);
88
89 rel = grub_relocator_new ();
90 if (!rel)
91 goto fail;
92
ca0a4f68 93 file = grub_file_open (argv[0], GRUB_FILE_TYPE_NTLDR);
b883356c
VS
94 if (! file)
95 goto fail;
96
4b2ec20b
VS
97 {
98 grub_relocator_chunk_t ch;
99 err = grub_relocator_alloc_chunk_addr (rel, &ch, 0x7C00,
100 GRUB_DISK_SECTOR_SIZE);
101 if (err)
102 goto fail;
103 bs = get_virtual_current_address (ch);
104 }
b883356c 105
dae84898 106 edx = grub_get_root_biosnumber ();
b883356c
VS
107 dev = grub_device_open (0);
108
109 if (dev && dev->disk)
110 {
111 err = grub_disk_read (dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, bs);
112 if (err)
113 {
114 grub_device_close (dev);
115 goto fail;
116 }
b38a4983 117 grub_chainloader_patch_bpb (bs, dev, edx);
b883356c
VS
118 }
119
120 if (dev)
121 grub_device_close (dev);
122
123 ntldrsize = grub_file_size (file);
4b2ec20b
VS
124 {
125 grub_relocator_chunk_t ch;
126 err = grub_relocator_alloc_chunk_addr (rel, &ch, GRUB_NTLDR_SEGMENT << 4,
127 ntldrsize);
128 if (err)
129 goto fail;
130 ntldr = get_virtual_current_address (ch);
131 }
b883356c
VS
132
133 if (grub_file_read (file, ntldr, ntldrsize)
134 != (grub_ssize_t) ntldrsize)
135 goto fail;
136
137 grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1);
138 return GRUB_ERR_NONE;
139
140 fail:
141
142 if (file)
143 grub_file_close (file);
144
145 grub_ntldr_unload ();
146
147 return grub_errno;
148}
149
150static grub_command_t cmd;
151
152GRUB_MOD_INIT(ntldr)
153{
154 cmd = grub_register_command ("ntldr", grub_cmd_ntldr,
155 0, N_("Load NTLDR or BootMGR."));
156 my_mod = mod;
157}
158
159GRUB_MOD_FINI(ntldr)
160{
161 grub_unregister_command (cmd);
162}