1 /* chainloader.c - boot another boot loader */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2002,2004,2007,2009,2010 Free Software Foundation, Inc.
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.
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.
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/>.
20 #include <grub/loader.h>
21 #include <grub/file.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>
29 #include <grub/command.h>
30 #include <grub/machine/biosnum.h>
31 #include <grub/i18n.h>
32 #include <grub/video.h>
34 #include <grub/cpu/relocator.h>
35 #include <grub/machine/chainloader.h>
37 GRUB_MOD_LICENSE ("GPLv3+");
39 static grub_dl_t my_mod
;
40 static struct grub_relocator
*rel
;
41 static grub_uint32_t edx
= 0xffffffff;
43 #define GRUB_NTLDR_SEGMENT 0x2000
46 grub_ntldr_boot (void)
48 struct grub_relocator16_state state
= {
49 .cs
= GRUB_NTLDR_SEGMENT
,
60 grub_video_set_mode ("text", 0, 0);
62 return grub_relocator16_boot (rel
, state
);
66 grub_ntldr_unload (void)
68 grub_relocator_unload (rel
);
70 grub_dl_unref (my_mod
);
75 grub_cmd_ntldr (grub_command_t cmd
__attribute__ ((unused
)),
76 int argc
, char *argv
[])
81 grub_size_t ntldrsize
;
85 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("filename expected"));
89 rel
= grub_relocator_new ();
93 file
= grub_file_open (argv
[0]);
98 grub_relocator_chunk_t ch
;
99 err
= grub_relocator_alloc_chunk_addr (rel
, &ch
, 0x7C00,
100 GRUB_DISK_SECTOR_SIZE
);
103 bs
= get_virtual_current_address (ch
);
106 edx
= grub_get_root_biosnumber ();
107 dev
= grub_device_open (0);
109 if (dev
&& dev
->disk
)
111 err
= grub_disk_read (dev
->disk
, 0, 0, GRUB_DISK_SECTOR_SIZE
, bs
);
114 grub_device_close (dev
);
117 grub_chainloader_patch_bpb (bs
, dev
, edx
);
121 grub_device_close (dev
);
123 ntldrsize
= grub_file_size (file
);
125 grub_relocator_chunk_t ch
;
126 err
= grub_relocator_alloc_chunk_addr (rel
, &ch
, GRUB_NTLDR_SEGMENT
<< 4,
130 ntldr
= get_virtual_current_address (ch
);
133 if (grub_file_read (file
, ntldr
, ntldrsize
)
134 != (grub_ssize_t
) ntldrsize
)
137 grub_loader_set (grub_ntldr_boot
, grub_ntldr_unload
, 1);
138 return GRUB_ERR_NONE
;
143 grub_file_close (file
);
145 grub_ntldr_unload ();
150 static grub_command_t cmd
;
154 cmd
= grub_register_command ("ntldr", grub_cmd_ntldr
,
155 0, N_("Load NTLDR or BootMGR."));
161 grub_unregister_command (cmd
);