Upgraded GRUB2 to 2.00 release.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / loader / i386 / pc / ntldr.c
blob1b88f40d87198200e1f9f319d712f495d645928d
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.
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>
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>
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
45 static grub_err_t
46 grub_ntldr_boot (void)
48 struct grub_relocator16_state state = {
49 .cs = GRUB_NTLDR_SEGMENT,
50 .ip = 0,
51 .ds = 0,
52 .es = 0,
53 .fs = 0,
54 .gs = 0,
55 .ss = 0,
56 .sp = 0x7c00,
57 .edx = edx,
58 .a20 = 1
60 grub_video_set_mode ("text", 0, 0);
62 return grub_relocator16_boot (rel, state);
65 static grub_err_t
66 grub_ntldr_unload (void)
68 grub_relocator_unload (rel);
69 rel = NULL;
70 grub_dl_unref (my_mod);
71 return GRUB_ERR_NONE;
74 static grub_err_t
75 grub_cmd_ntldr (grub_command_t cmd __attribute__ ((unused)),
76 int argc, char *argv[])
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;
84 if (argc == 0)
85 return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
87 grub_dl_ref (my_mod);
89 rel = grub_relocator_new ();
90 if (!rel)
91 goto fail;
93 file = grub_file_open (argv[0]);
94 if (! file)
95 goto fail;
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);
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);
112 if (err)
114 grub_device_close (dev);
115 goto fail;
117 grub_chainloader_patch_bpb (bs, dev, edx);
120 if (dev)
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,
127 ntldrsize);
128 if (err)
129 goto fail;
130 ntldr = get_virtual_current_address (ch);
133 if (grub_file_read (file, ntldr, ntldrsize)
134 != (grub_ssize_t) ntldrsize)
135 goto fail;
137 grub_loader_set (grub_ntldr_boot, grub_ntldr_unload, 1);
138 return GRUB_ERR_NONE;
140 fail:
142 if (file)
143 grub_file_close (file);
145 grub_ntldr_unload ();
147 return grub_errno;
150 static grub_command_t cmd;
152 GRUB_MOD_INIT(ntldr)
154 cmd = grub_register_command ("ntldr", grub_cmd_ntldr,
155 0, N_("Load NTLDR or BootMGR."));
156 my_mod = mod;
159 GRUB_MOD_FINI(ntldr)
161 grub_unregister_command (cmd);