2
* GRUB -- GRand Unified Bootloader
3
* Copyright (C) 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/i386/bsd.h>
21
#include <grub/i386/cpuid.h>
22
#include <grub/memory.h>
23
#include <grub/i386/memory.h>
24
#include <grub/file.h>
28
#include <grub/elfload.h>
30
#include <grub/misc.h>
31
#include <grub/aout.h>
32
#include <grub/command.h>
33
#include <grub/extcmd.h>
34
#include <grub/i18n.h>
35
#include <grub/ns8250.h>
37
#include <grub/video.h>
38
#ifdef GRUB_MACHINE_PCBIOS
39
#include <grub/machine/biosnum.h>
41
#ifdef GRUB_MACHINE_EFI
42
#include <grub/efi/efi.h>
43
#define NETBSD_DEFAULT_VIDEO_MODE "800x600"
45
#define NETBSD_DEFAULT_VIDEO_MODE "text"
46
#include <grub/i386/pc/vbe.h>
48
#include <grub/video.h>
50
#include <grub/disk.h>
51
#include <grub/device.h>
52
#include <grub/partition.h>
53
#include <grub/relocator.h>
54
#include <grub/i386/relocator.h>
56
#define ALIGN_DWORD(a) ALIGN_UP (a, 4)
57
#define ALIGN_QWORD(a) ALIGN_UP (a, 8)
58
#define ALIGN_VAR(a) ((is_64bit) ? (ALIGN_QWORD(a)) : (ALIGN_DWORD(a)))
59
#define ALIGN_PAGE(a) ALIGN_UP (a, 4096)
61
static int kernel_type = KERNEL_TYPE_NONE;
62
static grub_dl_t my_mod;
63
static grub_addr_t entry, entry_hi, kern_start, kern_end;
64
static void *kern_chunk_src;
65
static grub_uint32_t bootflags;
66
static int is_elf_kernel, is_64bit;
67
static grub_uint32_t openbsd_root;
68
struct grub_relocator *relocator = NULL;
69
static struct grub_openbsd_ramdisk_descriptor openbsd_ramdisk;
83
static struct bsd_tag *tags, *tags_last;
87
struct netbsd_module *next;
88
struct grub_netbsd_btinfo_module mod;
91
static struct netbsd_module *netbsd_mods, *netbsd_mods_last;
93
static const struct grub_arg_option freebsd_opts[] =
95
{"dual", 'D', 0, N_("Display output on all consoles."), 0, 0},
96
{"serial", 'h', 0, N_("Use serial console."), 0, 0},
97
{"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
98
{"cdrom", 'C', 0, N_("Use CDROM as root."), 0, 0},
99
{"config", 'c', 0, N_("Invoke user configuration routing."), 0, 0},
100
{"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
101
{"gdb", 'g', 0, N_("Use GDB remote debugger instead of DDB."), 0, 0},
102
{"mute", 'm', 0, N_("Disable all boot output."), 0, 0},
103
{"nointr", 'n', 0, "", 0, 0},
104
{"pause", 'p', 0, N_("Wait for keypress after every line of output."), 0, 0},
105
{"quiet", 'q', 0, "", 0, 0},
106
{"dfltroot", 'r', 0, N_("Use compiled-in rootdev."), 0, 0},
107
{"single", 's', 0, N_("Boot into single mode."), 0, 0},
108
{"verbose", 'v', 0, N_("Boot with verbose messages."), 0, 0},
112
static const grub_uint32_t freebsd_flags[] =
114
FREEBSD_RB_DUAL, FREEBSD_RB_SERIAL, FREEBSD_RB_ASKNAME,
115
FREEBSD_RB_CDROM, FREEBSD_RB_CONFIG, FREEBSD_RB_KDB,
116
FREEBSD_RB_GDB, FREEBSD_RB_MUTE, FREEBSD_RB_NOINTR,
117
FREEBSD_RB_PAUSE, FREEBSD_RB_QUIET, FREEBSD_RB_DFLTROOT,
118
FREEBSD_RB_SINGLE, FREEBSD_RB_VERBOSE, 0
121
static const struct grub_arg_option openbsd_opts[] =
123
{"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
124
{"halt", 'b', 0, N_("Don't reboot, just halt."), 0, 0},
125
{"config", 'c', 0, N_("Change configured devices."), 0, 0},
126
{"single", 's', 0, N_("Boot into single mode."), 0, 0},
127
{"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
128
{"root", 'r', 0, N_("Set root device."), "wdXY", ARG_TYPE_STRING},
129
{"serial", 'h', GRUB_ARG_OPTION_OPTIONAL,
130
N_("Use serial console."), N_("comUNIT[,SPEED]"), ARG_TYPE_STRING},
134
static const grub_uint32_t openbsd_flags[] =
136
OPENBSD_RB_ASKNAME, OPENBSD_RB_HALT, OPENBSD_RB_CONFIG,
137
OPENBSD_RB_SINGLE, OPENBSD_RB_KDB, 0
140
#define OPENBSD_ROOT_ARG (ARRAY_SIZE (openbsd_flags) - 1)
141
#define OPENBSD_SERIAL_ARG (ARRAY_SIZE (openbsd_flags))
143
static const struct grub_arg_option netbsd_opts[] =
145
{"no-smp", '1', 0, N_("Disable SMP."), 0, 0},
146
{"no-acpi", '2', 0, N_("Disable ACPI."), 0, 0},
147
{"askname", 'a', 0, N_("Ask for file name to reboot from."), 0, 0},
148
{"halt", 'b', 0, N_("Don't reboot, just halt."), 0, 0},
149
{"config", 'c', 0, N_("Change configured devices."), 0, 0},
150
{"kdb", 'd', 0, N_("Enter in KDB on boot."), 0, 0},
151
{"miniroot", 'm', 0, "", 0, 0},
152
{"quiet", 'q', 0, N_("Don't display boot diagnostic messages."), 0, 0},
153
{"single", 's', 0, N_("Boot into single mode."), 0, 0},
154
{"verbose", 'v', 0, N_("Boot with verbose messages."), 0, 0},
155
{"debug", 'x', 0, N_("Boot with debug messages."), 0, 0},
156
{"silent", 'z', 0, N_("Supress normal output (warnings remain)."), 0, 0},
157
{"root", 'r', 0, N_("Set root device."), N_("DEVICE"), ARG_TYPE_STRING},
158
{"serial", 'h', GRUB_ARG_OPTION_OPTIONAL,
159
N_("Use serial console."), N_("[ADDR|comUNIT][,SPEED]"), ARG_TYPE_STRING},
163
static const grub_uint32_t netbsd_flags[] =
165
NETBSD_AB_NOSMP, NETBSD_AB_NOACPI, NETBSD_RB_ASKNAME,
166
NETBSD_RB_HALT, NETBSD_RB_USERCONFIG, NETBSD_RB_KDB,
167
NETBSD_RB_MINIROOT, NETBSD_AB_QUIET, NETBSD_RB_SINGLE,
168
NETBSD_AB_VERBOSE, NETBSD_AB_DEBUG, NETBSD_AB_SILENT, 0
171
#define NETBSD_ROOT_ARG (ARRAY_SIZE (netbsd_flags) - 1)
172
#define NETBSD_SERIAL_ARG (ARRAY_SIZE (netbsd_flags))
175
grub_bsd_get_device (grub_uint32_t * biosdev,
176
grub_uint32_t * unit,
177
grub_uint32_t * slice, grub_uint32_t * part)
181
#ifdef GRUB_MACHINE_PCBIOS
182
*biosdev = grub_get_root_biosnumber () & 0xff;
186
*unit = (*biosdev & 0x7f);
189
dev = grub_device_open (0);
190
if (dev && dev->disk && dev->disk->partition)
192
if (dev->disk->partition->parent)
194
*part = dev->disk->partition->number;
195
*slice = dev->disk->partition->parent->number + 1;
198
*slice = dev->disk->partition->number + 1;
201
grub_device_close (dev);
205
grub_bsd_add_meta (grub_uint32_t type, void *data, grub_uint32_t len)
207
struct bsd_tag *newtag;
209
newtag = grub_malloc (len + sizeof (struct bsd_tag));
216
grub_memcpy (newtag->data, data, len);
218
if (kernel_type == KERNEL_TYPE_FREEBSD
219
&& type == (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_SMAP))
223
p->type != (FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_KERNEND);
228
newtag->next = p->next;
230
if (newtag->next == NULL)
232
return GRUB_ERR_NONE;
237
tags_last->next = newtag;
242
return GRUB_ERR_NONE;
245
struct grub_e820_mmap
250
} __attribute__((packed));
251
#define GRUB_E820_RAM 1
252
#define GRUB_E820_RESERVED 2
253
#define GRUB_E820_ACPI 3
254
#define GRUB_E820_NVS 4
255
#define GRUB_E820_EXEC_CODE 5
258
generate_e820_mmap (grub_size_t *len, grub_size_t *cnt, void *buf)
261
struct grub_e820_mmap *mmap = buf;
262
struct grub_e820_mmap prev, cur;
264
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t,
266
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
267
grub_memory_type_t type)
273
case GRUB_MEMORY_AVAILABLE:
274
cur.type = GRUB_E820_RAM;
277
case GRUB_MEMORY_ACPI:
278
cur.type = GRUB_E820_ACPI;
281
case GRUB_MEMORY_NVS:
282
cur.type = GRUB_E820_NVS;
286
case GRUB_MEMORY_CODE:
287
case GRUB_MEMORY_RESERVED:
288
cur.type = GRUB_E820_RESERVED;
292
/* Merge regions if possible. */
293
if (count && cur.type == prev.type && cur.addr == prev.addr + prev.size)
295
prev.size += cur.size;
307
if (kernel_type == KERNEL_TYPE_OPENBSD && prev.addr < 0x100000
308
&& prev.addr + prev.size > 0x100000)
311
cur.size = prev.addr + prev.size - 0x100000;
312
cur.type = prev.type;
313
prev.size = 0x100000 - prev.addr;
327
grub_mmap_iterate (hook);
330
*len = count * sizeof (struct grub_e820_mmap);
337
grub_bsd_add_mmap (void)
339
grub_size_t len, cnt;
340
void *buf = NULL, *buf0;
342
generate_e820_mmap (&len, &cnt, buf);
344
if (kernel_type == KERNEL_TYPE_NETBSD)
345
len += sizeof (grub_uint32_t);
347
if (kernel_type == KERNEL_TYPE_OPENBSD)
348
len += sizeof (struct grub_e820_mmap);
350
buf = grub_malloc (len);
355
if (kernel_type == KERNEL_TYPE_NETBSD)
357
*(grub_uint32_t *) buf = cnt;
358
buf = ((grub_uint32_t *) buf + 1);
361
generate_e820_mmap (NULL, &cnt, buf);
363
if (kernel_type == KERNEL_TYPE_OPENBSD)
364
grub_memset ((grub_uint8_t *) buf + len - sizeof (struct grub_e820_mmap), 0,
365
sizeof (struct grub_e820_mmap));
367
grub_dprintf ("bsd", "%u entries in smap\n", (unsigned) cnt);
368
if (kernel_type == KERNEL_TYPE_NETBSD)
369
grub_bsd_add_meta (NETBSD_BTINFO_MEMMAP, buf0, len);
370
else if (kernel_type == KERNEL_TYPE_OPENBSD)
371
grub_bsd_add_meta (OPENBSD_BOOTARG_MMAP, buf0, len);
373
grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
374
FREEBSD_MODINFOMD_SMAP, buf0, len);
382
grub_freebsd_add_meta_module (char *filename, char *type, int argc, char **argv,
383
grub_addr_t addr, grub_uint32_t size)
386
name = grub_strrchr (filename, '/');
391
if (grub_strcmp (type, "/boot/zfs/zpool.cache") == 0)
392
name = "/boot/zfs/zpool.cache";
394
if (grub_bsd_add_meta (FREEBSD_MODINFO_NAME, name, grub_strlen (name) + 1))
399
grub_uint64_t addr64 = addr, size64 = size;
400
if (grub_bsd_add_meta (FREEBSD_MODINFO_TYPE, type, grub_strlen (type) + 1)
401
|| grub_bsd_add_meta (FREEBSD_MODINFO_ADDR, &addr64, sizeof (addr64))
402
|| grub_bsd_add_meta (FREEBSD_MODINFO_SIZE, &size64, sizeof (size64)))
407
if (grub_bsd_add_meta (FREEBSD_MODINFO_TYPE, type, grub_strlen (type) + 1)
408
|| grub_bsd_add_meta (FREEBSD_MODINFO_ADDR, &addr, sizeof (addr))
409
|| grub_bsd_add_meta (FREEBSD_MODINFO_SIZE, &size, sizeof (size)))
418
for (i = 0; i < argc; i++)
420
n += grub_strlen (argv[i]) + 1;
428
for (i = 0; i < argc; i++)
430
grub_strcpy (p, argv[i]);
431
p += grub_strlen (argv[i]);
436
if (grub_bsd_add_meta (FREEBSD_MODINFO_ARGS, cmdline, n))
441
return GRUB_ERR_NONE;
445
grub_freebsd_list_modules (void)
449
grub_printf (" %-18s %-18s%14s%14s\n", "name", "type", "addr", "size");
451
for (tag = tags; tag; tag = tag->next)
455
case FREEBSD_MODINFO_NAME:
456
case FREEBSD_MODINFO_TYPE:
457
grub_printf (" %-18s", (char *) tag->data);
459
case FREEBSD_MODINFO_ADDR:
463
addr = *((grub_uint32_t *) tag->data);
464
grub_printf (" 0x%08x", addr);
467
case FREEBSD_MODINFO_SIZE:
471
len = *((grub_uint32_t *) tag->data);
472
grub_printf (" 0x%08x\n", len);
479
grub_netbsd_add_meta_module (char *filename, grub_uint32_t type,
480
grub_addr_t addr, grub_uint32_t size)
483
struct netbsd_module *mod;
484
name = grub_strrchr (filename, '/');
491
mod = grub_zalloc (sizeof (*mod));
495
grub_strncpy (mod->mod.name, name, sizeof (mod->mod.name) - 1);
496
mod->mod.addr = addr;
497
mod->mod.type = type;
498
mod->mod.size = size;
500
if (netbsd_mods_last)
501
netbsd_mods_last->next = mod;
504
netbsd_mods_last = mod;
506
return GRUB_ERR_NONE;
510
grub_netbsd_list_modules (void)
512
struct netbsd_module *mod;
514
grub_printf (" %-18s%14s%14s%14s\n", "name", "type", "addr", "size");
516
for (mod = netbsd_mods; mod; mod = mod->next)
517
grub_printf (" %-18s 0x%08x 0x%08x 0x%08x", mod->mod.name,
518
mod->mod.type, mod->mod.addr, mod->mod.size);
521
/* This function would be here but it's under different license. */
522
#include "bsd_pagetable.c"
525
grub_freebsd_boot (void)
527
struct grub_freebsd_bootinfo bi;
528
grub_uint8_t *p, *p0;
529
grub_addr_t p_target;
530
grub_size_t p_size = 0;
531
grub_uint32_t bootdev, biosdev, unit, slice, part;
533
grub_size_t tag_buf_len = 0;
535
auto int iterate_env (struct grub_env_var *var);
536
int iterate_env (struct grub_env_var *var)
538
if ((!grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1)) && (var->name[sizeof("kFreeBSD.") - 1]))
540
grub_strcpy ((char *) p, &var->name[sizeof("kFreeBSD.") - 1]);
541
p += grub_strlen ((char *) p);
543
grub_strcpy ((char *) p, var->value);
544
p += grub_strlen ((char *) p) + 1;
550
auto int iterate_env_count (struct grub_env_var *var);
551
int iterate_env_count (struct grub_env_var *var)
553
if ((!grub_memcmp (var->name, "kFreeBSD.", sizeof("kFreeBSD.") - 1)) && (var->name[sizeof("kFreeBSD.") - 1]))
555
p_size += grub_strlen (&var->name[sizeof("kFreeBSD.") - 1]);
557
p_size += grub_strlen (var->value) + 1;
563
grub_memset (&bi, 0, sizeof (bi));
564
bi.version = FREEBSD_BOOTINFO_VERSION;
565
bi.length = sizeof (bi);
567
grub_bsd_get_device (&biosdev, &unit, &slice, &part);
568
bootdev = (FREEBSD_B_DEVMAGIC + ((slice + 1) << FREEBSD_B_SLICESHIFT) +
569
(unit << FREEBSD_B_UNITSHIFT) + (part << FREEBSD_B_PARTSHIFT));
571
bi.boot_device = biosdev;
574
grub_env_iterate (iterate_env_count);
577
p_size = ALIGN_PAGE (kern_end + p_size + 1) - kern_end;
583
err = grub_bsd_add_mmap ();
587
err = grub_bsd_add_meta (FREEBSD_MODINFO_END, 0, 0);
592
for (tag = tags; tag; tag = tag->next)
593
tag_buf_len = ALIGN_VAR (tag_buf_len
594
+ sizeof (struct freebsd_tag_header)
596
p_size = ALIGN_PAGE (kern_end + p_size + tag_buf_len) - kern_end;
603
grub_relocator_chunk_t ch;
604
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
608
p = get_virtual_current_address (ch);
614
grub_env_iterate (iterate_env);
620
bi.environment = p_target;
625
grub_uint8_t *p_tag = p;
628
for (tag = tags; tag; tag = tag->next)
630
struct freebsd_tag_header *head
631
= (struct freebsd_tag_header *) p_tag;
632
head->type = tag->type;
633
head->len = tag->len;
634
p_tag += sizeof (struct freebsd_tag_header);
637
case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_HOWTO:
639
*(grub_uint64_t *) p_tag = bootflags;
641
*(grub_uint32_t *) p_tag = bootflags;
644
case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_ENVP:
646
*(grub_uint64_t *) p_tag = bi.environment;
648
*(grub_uint32_t *) p_tag = bi.environment;
651
case FREEBSD_MODINFO_METADATA | FREEBSD_MODINFOMD_KERNEND:
653
*(grub_uint64_t *) p_tag = kern_end;
655
*(grub_uint32_t *) p_tag = kern_end;
659
grub_memcpy (p_tag, tag->data, tag->len);
663
p_tag = ALIGN_VAR (p_tag - p) + p;
666
bi.tags = (p - p0) + p_target;
668
p = (ALIGN_PAGE ((p_tag - p0) + p_target) - p_target) + p0;
671
bi.kern_end = kern_end;
673
grub_video_set_mode ("text", 0, 0);
677
struct grub_relocator64_state state;
678
grub_uint8_t *pagetable;
679
grub_uint32_t *stack;
680
grub_addr_t stack_target;
683
grub_relocator_chunk_t ch;
684
err = grub_relocator_alloc_chunk_align (relocator, &ch,
686
3 * sizeof (grub_uint32_t)
688
GRUB_RELOCATOR_PREFERENCE_NONE);
691
stack = get_virtual_current_address (ch);
692
stack_target = get_physical_target_address (ch);
695
#ifdef GRUB_MACHINE_EFI
696
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
702
fill_bsd64_pagetable (pagetable, (pagetable - p0) + p_target);
704
state.cr3 = (pagetable - p0) + p_target;
705
state.rsp = stack_target;
706
state.rip = (((grub_uint64_t) entry_hi) << 32) | entry;
711
return grub_relocator64_boot (relocator, state, 0, 0x40000000);
715
struct grub_relocator32_state state;
716
grub_uint32_t *stack;
717
grub_addr_t stack_target;
720
grub_relocator_chunk_t ch;
721
err = grub_relocator_alloc_chunk_align (relocator, &ch,
723
9 * sizeof (grub_uint32_t)
725
GRUB_RELOCATOR_PREFERENCE_NONE);
728
stack = get_virtual_current_address (ch);
729
stack_target = get_physical_target_address (ch);
732
#ifdef GRUB_MACHINE_EFI
733
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
738
grub_memcpy (&stack[9], &bi, sizeof (bi));
740
state.esp = stack_target;
741
state.ebp = stack_target;
742
stack[0] = entry; /* "Return" address. */
743
stack[1] = bootflags | FREEBSD_RB_BOOTINFO;
748
stack[6] = stack_target + 9 * sizeof (grub_uint32_t);
751
return grub_relocator32_boot (relocator, state);
755
return GRUB_ERR_NONE;
759
grub_openbsd_boot (void)
761
grub_uint32_t *stack;
762
struct grub_relocator32_state state;
763
void *curarg, *buf0, *arg0;
764
grub_addr_t buf_target;
766
grub_size_t tag_buf_len;
768
err = grub_bsd_add_mmap ();
775
for (tag = tags; tag; tag = tag->next)
776
tag_buf_len = ALIGN_VAR (tag_buf_len
777
+ sizeof (struct grub_openbsd_bootargs)
781
buf_target = GRUB_BSD_TEMP_BUFFER - 9 * sizeof (grub_uint32_t);
783
grub_relocator_chunk_t ch;
784
err = grub_relocator_alloc_chunk_addr (relocator, &ch, buf_target,
786
+ sizeof (struct grub_openbsd_bootargs)
787
+ 9 * sizeof (grub_uint32_t));
790
buf0 = get_virtual_current_address (ch);
793
stack = (grub_uint32_t *) buf0;
794
arg0 = curarg = stack + 9;
798
struct grub_openbsd_bootargs *head;
800
for (tag = tags; tag; tag = tag->next)
803
head->ba_type = tag->type;
804
head->ba_size = tag->len + sizeof (*head);
806
grub_memcpy (curarg, tag->data, tag->len);
807
curarg = (grub_uint8_t *) curarg + tag->len;
808
head->ba_next = (grub_uint8_t *) curarg - (grub_uint8_t *) buf0
812
head->ba_type = OPENBSD_BOOTARG_END;
817
grub_video_set_mode ("text", 0, 0);
819
#ifdef GRUB_MACHINE_EFI
820
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
826
state.ebp = state.esp
827
= ((grub_uint8_t *) stack - (grub_uint8_t *) buf0) + buf_target;
829
stack[1] = bootflags;
830
stack[2] = openbsd_root;
831
stack[3] = OPENBSD_BOOTARG_APIVER;
833
stack[5] = grub_mmap_get_upper () >> 10;
834
stack[6] = grub_mmap_get_lower () >> 10;
835
stack[7] = (grub_uint8_t *) curarg - (grub_uint8_t *) arg0;
836
stack[8] = ((grub_uint8_t *) arg0 - (grub_uint8_t *) buf0) + buf_target;
838
return grub_relocator32_boot (relocator, state);
842
grub_netbsd_setup_video (void)
844
struct grub_video_mode_info mode_info;
847
struct grub_netbsd_btinfo_framebuf params;
849
grub_video_driver_id_t driv_id;
851
modevar = grub_env_get ("gfxpayload");
853
/* Now all graphical modes are acceptable.
854
May change in future if we have modes without framebuffer. */
855
if (modevar && *modevar != 0)
858
tmp = grub_xasprintf ("%s;" NETBSD_DEFAULT_VIDEO_MODE, modevar);
861
err = grub_video_set_mode (tmp, 0, 0);
865
err = grub_video_set_mode (NETBSD_DEFAULT_VIDEO_MODE, 0, 0);
870
driv_id = grub_video_get_driver_id ();
871
if (driv_id == GRUB_VIDEO_DRIVER_NONE)
872
return GRUB_ERR_NONE;
874
err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
879
params.width = mode_info.width;
880
params.height = mode_info.height;
881
params.bpp = mode_info.bpp;
882
params.pitch = mode_info.pitch;
885
params.fbaddr = (grub_addr_t) framebuffer;
887
params.red_mask_size = mode_info.red_mask_size;
888
params.red_field_pos = mode_info.red_field_pos;
889
params.green_mask_size = mode_info.green_mask_size;
890
params.green_field_pos = mode_info.green_field_pos;
891
params.blue_mask_size = mode_info.blue_mask_size;
892
params.blue_field_pos = mode_info.blue_field_pos;
894
#ifdef GRUB_MACHINE_PCBIOS
895
/* VESA packed modes may come with zeroed mask sizes, which need
896
to be set here according to DAC Palette width. If we don't,
897
this results in Linux displaying a black screen. */
898
if (mode_info.bpp <= 8 && driv_id == GRUB_VIDEO_DRIVER_VBE)
900
struct grub_vbe_info_block controller_info;
904
status = grub_vbe_bios_get_controller_info (&controller_info);
906
if (status == GRUB_VBE_STATUS_OK &&
907
(controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH))
908
status = grub_vbe_bios_set_dac_palette_width (&width);
910
if (status != GRUB_VBE_STATUS_OK)
911
/* 6 is default after mode reset. */
914
params.red_mask_size = params.green_mask_size
915
= params.blue_mask_size = width;
919
err = grub_bsd_add_meta (NETBSD_BTINFO_FRAMEBUF, ¶ms, sizeof (params));
924
grub_netbsd_add_modules (void)
926
struct netbsd_module *mod;
928
struct grub_netbsd_btinfo_modules *mods;
932
for (mod = netbsd_mods; mod; mod = mod->next)
935
mods = grub_malloc (sizeof (*mods) + sizeof (mods->mods[0]) * modcnt);
940
mods->last_addr = kern_end;
941
for (mod = netbsd_mods, i = 0; mod; i++, mod = mod->next)
942
mods->mods[i] = mod->mod;
944
err = grub_bsd_add_meta (NETBSD_BTINFO_MODULES, mods,
945
sizeof (*mods) + sizeof (mods->mods[0]) * modcnt);
951
grub_netbsd_boot (void)
953
struct grub_netbsd_bootinfo *bootinfo;
955
grub_addr_t arg_target, stack_target;
956
grub_uint32_t *stack;
958
struct grub_relocator32_state state;
959
grub_size_t tag_buf_len = 0;
962
err = grub_bsd_add_mmap ();
966
err = grub_netbsd_setup_video ();
970
grub_printf ("Booting however\n");
971
grub_errno = GRUB_ERR_NONE;
974
err = grub_netbsd_add_modules ();
981
for (tag = tags; tag; tag = tag->next)
983
tag_buf_len = ALIGN_VAR (tag_buf_len
984
+ sizeof (struct grub_netbsd_btinfo_common)
990
arg_target = kern_end;
992
grub_relocator_chunk_t ch;
993
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
994
arg_target, tag_buf_len
995
+ sizeof (struct grub_netbsd_bootinfo)
996
+ tag_count * sizeof (grub_uint32_t));
999
curarg = get_virtual_current_address (ch);
1003
bootinfo = (void *) ((grub_uint8_t *) arg0 + tag_buf_len);
1006
struct bsd_tag *tag;
1009
bootinfo->bi_count = tag_count;
1010
for (tag = tags, i = 0; tag; i++, tag = tag->next)
1012
struct grub_netbsd_btinfo_common *head = curarg;
1013
bootinfo->bi_data[i] = ((grub_uint8_t *) curarg - (grub_uint8_t *) arg0)
1015
head->type = tag->type;
1016
head->len = tag->len + sizeof (*head);
1018
grub_memcpy (curarg, tag->data, tag->len);
1019
curarg = (grub_uint8_t *) curarg + tag->len;
1024
grub_relocator_chunk_t ch;
1025
err = grub_relocator_alloc_chunk_align (relocator, &ch, 0x10000, 0x90000,
1026
7 * sizeof (grub_uint32_t), 4,
1027
GRUB_RELOCATOR_PREFERENCE_NONE);
1030
stack = get_virtual_current_address (ch);
1031
stack_target = get_physical_target_address (ch);
1034
#ifdef GRUB_MACHINE_EFI
1035
err = grub_efi_finish_boot_services (NULL, NULL, NULL, NULL, NULL);
1041
state.esp = stack_target;
1042
state.ebp = stack_target;
1044
stack[1] = bootflags;
1046
stack[3] = ((grub_uint8_t *) bootinfo - (grub_uint8_t *) arg0) + arg_target;
1048
stack[5] = grub_mmap_get_upper () >> 10;
1049
stack[6] = grub_mmap_get_lower () >> 10;
1051
return grub_relocator32_boot (relocator, state);
1055
grub_bsd_unload (void)
1057
struct bsd_tag *tag, *next;
1058
for (tag = tags; tag; tag = next)
1066
kernel_type = KERNEL_TYPE_NONE;
1067
grub_dl_unref (my_mod);
1069
grub_relocator_unload (relocator);
1072
return GRUB_ERR_NONE;
1076
grub_bsd_load_aout (grub_file_t file)
1078
grub_addr_t load_addr, load_end;
1079
int ofs, align_page;
1080
union grub_aout_header ah;
1082
grub_size_t bss_size;
1084
if ((grub_file_seek (file, 0)) == (grub_off_t) - 1)
1087
if (grub_file_read (file, &ah, sizeof (ah)) != sizeof (ah))
1088
return grub_error (GRUB_ERR_READ_ERROR, "cannot read the a.out header");
1090
if (grub_aout_get_type (&ah) != AOUT_TYPE_AOUT32)
1091
return grub_error (GRUB_ERR_BAD_OS, "invalid a.out header");
1093
entry = ah.aout32.a_entry & 0xFFFFFF;
1095
if (AOUT_GETMAGIC (ah.aout32) == AOUT32_ZMAGIC)
1103
load_addr = entry & 0xF00000;
1104
ofs = sizeof (struct grub_aout32_header);
1108
if (load_addr < 0x100000)
1109
return grub_error (GRUB_ERR_BAD_OS, "load address below 1M");
1111
kern_start = load_addr;
1112
load_end = kern_end = load_addr + ah.aout32.a_text + ah.aout32.a_data;
1114
kern_end = ALIGN_PAGE (kern_end);
1116
if (ah.aout32.a_bss)
1118
kern_end += ah.aout32.a_bss;
1120
kern_end = ALIGN_PAGE (kern_end);
1122
bss_size = kern_end - load_end;
1128
grub_relocator_chunk_t ch;
1130
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
1131
kern_start, kern_end - kern_start);
1134
kern_chunk_src = get_virtual_current_address (ch);
1137
return grub_aout_load (file, ofs, kern_chunk_src,
1138
ah.aout32.a_text + ah.aout32.a_data,
1142
static int NESTED_FUNC_ATTR
1143
grub_bsd_elf32_size_hook (grub_elf_t elf __attribute__ ((unused)),
1144
Elf32_Phdr *phdr, void *arg __attribute__ ((unused)))
1148
if (phdr->p_type != PT_LOAD
1149
&& phdr->p_type != PT_DYNAMIC)
1152
paddr = phdr->p_paddr & 0xFFFFFF;
1154
if (paddr < kern_start)
1157
if (paddr + phdr->p_memsz > kern_end)
1158
kern_end = paddr + phdr->p_memsz;
1164
grub_bsd_elf32_hook (Elf32_Phdr * phdr, grub_addr_t * addr, int *do_load)
1168
if (phdr->p_type != PT_LOAD
1169
&& phdr->p_type != PT_DYNAMIC)
1176
phdr->p_paddr &= 0xFFFFFF;
1177
paddr = phdr->p_paddr;
1179
*addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src);
1181
return GRUB_ERR_NONE;
1184
static int NESTED_FUNC_ATTR
1185
grub_bsd_elf64_size_hook (grub_elf_t elf __attribute__ ((unused)),
1186
Elf64_Phdr *phdr, void *arg __attribute__ ((unused)))
1190
if (phdr->p_type != PT_LOAD
1191
&& phdr->p_type != PT_DYNAMIC)
1194
paddr = phdr->p_paddr & 0xffffff;
1196
if (paddr < kern_start)
1199
if (paddr + phdr->p_memsz > kern_end)
1200
kern_end = paddr + phdr->p_memsz;
1206
grub_bsd_elf64_hook (Elf64_Phdr * phdr, grub_addr_t * addr, int *do_load)
1210
if (phdr->p_type != PT_LOAD
1211
&& phdr->p_type != PT_DYNAMIC)
1218
paddr = phdr->p_paddr & 0xffffff;
1220
*addr = (grub_addr_t) (paddr - kern_start + (grub_uint8_t *) kern_chunk_src);
1222
return GRUB_ERR_NONE;
1226
grub_bsd_load_elf (grub_elf_t elf)
1233
if (grub_elf_is_elf32 (elf))
1235
grub_relocator_chunk_t ch;
1237
entry = elf->ehdr.ehdr32.e_entry & 0xFFFFFF;
1238
err = grub_elf32_phdr_iterate (elf, grub_bsd_elf32_size_hook, NULL);
1241
err = grub_relocator_alloc_chunk_addr (relocator, &ch,
1242
kern_start, kern_end - kern_start);
1246
kern_chunk_src = get_virtual_current_address (ch);
1248
err = grub_elf32_load (elf, grub_bsd_elf32_hook, 0, 0);
1251
if (kernel_type != KERNEL_TYPE_OPENBSD)
1252
return GRUB_ERR_NONE;
1253
return grub_openbsd_find_ramdisk32 (elf->file, kern_start,
1254
kern_chunk_src, &openbsd_ramdisk);
1256
else if (grub_elf_is_elf64 (elf))
1260
if (! grub_cpuid_has_longmode)
1261
return grub_error (GRUB_ERR_BAD_OS, "your CPU does not implement AMD64 architecture");
1263
/* FreeBSD has 64-bit entry point. */
1264
if (kernel_type == KERNEL_TYPE_FREEBSD)
1266
entry = elf->ehdr.ehdr64.e_entry & 0xffffffff;
1267
entry_hi = (elf->ehdr.ehdr64.e_entry >> 32) & 0xffffffff;
1271
entry = elf->ehdr.ehdr64.e_entry & 0x0fffffff;
1275
err = grub_elf64_phdr_iterate (elf, grub_bsd_elf64_size_hook, NULL);
1279
grub_dprintf ("bsd", "kern_start = %lx, kern_end = %lx\n",
1280
(unsigned long) kern_start, (unsigned long) kern_end);
1282
grub_relocator_chunk_t ch;
1284
err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_start,
1285
kern_end - kern_start);
1288
kern_chunk_src = get_virtual_current_address (ch);
1291
err = grub_elf64_load (elf, grub_bsd_elf64_hook, 0, 0);
1294
if (kernel_type != KERNEL_TYPE_OPENBSD)
1295
return GRUB_ERR_NONE;
1296
return grub_openbsd_find_ramdisk64 (elf->file, kern_start,
1297
kern_chunk_src, &openbsd_ramdisk);
1300
return grub_error (GRUB_ERR_BAD_OS, "invalid ELF");
1304
grub_bsd_load (int argc, char *argv[])
1309
grub_dl_ref (my_mod);
1311
grub_loader_unset ();
1313
grub_memset (&openbsd_ramdisk, 0, sizeof (openbsd_ramdisk));
1317
grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
1321
file = grub_file_open (argv[0]);
1325
relocator = grub_relocator_new ();
1327
elf = grub_elf_file (file);
1331
grub_bsd_load_elf (elf);
1332
grub_elf_close (elf);
1338
grub_bsd_load_aout (file);
1339
grub_file_close (file);
1342
kern_end = ALIGN_PAGE (kern_end);
1346
if (grub_errno != GRUB_ERR_NONE)
1347
grub_dl_unref (my_mod);
1352
static grub_uint32_t
1353
grub_bsd_parse_flags (const struct grub_arg_list *state,
1354
const grub_uint32_t * flags)
1356
grub_uint32_t result = 0;
1359
for (i = 0; flags[i]; i++)
1367
grub_cmd_freebsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
1369
kernel_type = KERNEL_TYPE_FREEBSD;
1370
bootflags = grub_bsd_parse_flags (ctxt->state, freebsd_flags);
1372
if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
1374
kern_end = ALIGN_PAGE (kern_end);
1378
grub_uint64_t data = 0;
1380
int len = is_64bit ? 8 : 4;
1382
err = grub_freebsd_add_meta_module (argv[0], is_64bit
1383
? FREEBSD_MODTYPE_KERNEL64
1384
: FREEBSD_MODTYPE_KERNEL,
1387
kern_end - kern_start);
1391
file = grub_file_open (argv[0]);
1396
err = grub_freebsd_load_elf_meta64 (relocator, file, &kern_end);
1398
err = grub_freebsd_load_elf_meta32 (relocator, file, &kern_end);
1402
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
1403
FREEBSD_MODINFOMD_HOWTO, &data, 4);
1407
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
1408
FREEBSD_MODINFOMD_ENVP, &data, len);
1412
err = grub_bsd_add_meta (FREEBSD_MODINFO_METADATA |
1413
FREEBSD_MODINFOMD_KERNEND, &data, len);
1417
grub_loader_set (grub_freebsd_boot, grub_bsd_unload, 0);
1424
grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
1426
grub_uint32_t bootdev;
1428
kernel_type = KERNEL_TYPE_OPENBSD;
1429
bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags);
1431
if (ctxt->state[OPENBSD_ROOT_ARG].set)
1433
const char *arg = ctxt->state[OPENBSD_ROOT_ARG].arg;
1435
if (*(arg++) != 'w' || *(arg++) != 'd')
1436
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1437
"only device specifications of form "
1438
"wd<number><lowercase letter> are supported");
1440
unit = grub_strtoul (arg, (char **) &arg, 10);
1441
if (! (arg && *arg >= 'a' && *arg <= 'z'))
1442
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1443
"only device specifications of form "
1444
"wd<number><lowercase letter> are supported");
1448
bootdev = (OPENBSD_B_DEVMAGIC + (unit << OPENBSD_B_UNITSHIFT) +
1449
(part << OPENBSD_B_PARTSHIFT));
1454
if (ctxt->state[OPENBSD_SERIAL_ARG].set)
1456
struct grub_openbsd_bootarg_console serial;
1459
unsigned speed = 9600;
1461
grub_memset (&serial, 0, sizeof (serial));
1463
if (ctxt->state[OPENBSD_SERIAL_ARG].arg)
1465
ptr = ctxt->state[OPENBSD_SERIAL_ARG].arg;
1466
if (grub_memcmp (ptr, "com", sizeof ("com") - 1) != 0)
1467
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1468
"only com0-com3 are supported");
1469
ptr += sizeof ("com") - 1;
1470
port = grub_strtoul (ptr, &ptr, 0);
1472
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1473
"only com0-com3 are supported");
1477
speed = grub_strtoul (ptr, &ptr, 0);
1483
serial.device = (GRUB_OPENBSD_COM_MAJOR << 8) | port;
1484
serial.speed = speed;
1486
grub_bsd_add_meta (OPENBSD_BOOTARG_CONSOLE, &serial, sizeof (serial));
1487
bootflags |= OPENBSD_RB_SERCONS;
1491
struct grub_openbsd_bootarg_console serial;
1493
grub_memset (&serial, 0, sizeof (serial));
1494
serial.device = (GRUB_OPENBSD_VGA_MAJOR << 8);
1495
grub_bsd_add_meta (OPENBSD_BOOTARG_CONSOLE, &serial, sizeof (serial));
1496
bootflags &= ~OPENBSD_RB_SERCONS;
1499
if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
1501
grub_loader_set (grub_openbsd_boot, grub_bsd_unload, 0);
1502
openbsd_root = bootdev;
1509
grub_cmd_netbsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
1512
kernel_type = KERNEL_TYPE_NETBSD;
1513
bootflags = grub_bsd_parse_flags (ctxt->state, netbsd_flags);
1515
if (grub_bsd_load (argc, argv) == GRUB_ERR_NONE)
1521
file = grub_file_open (argv[0]);
1526
err = grub_netbsd_load_elf_meta64 (relocator, file, &kern_end);
1528
err = grub_netbsd_load_elf_meta32 (relocator, file, &kern_end);
1534
char bootpath[GRUB_NETBSD_MAX_BOOTPATH_LEN];
1536
name = grub_strrchr (argv[0], '/');
1541
grub_memset (bootpath, 0, sizeof (bootpath));
1542
grub_strncpy (bootpath, name, sizeof (bootpath) - 1);
1543
grub_bsd_add_meta (NETBSD_BTINFO_BOOTPATH, bootpath, sizeof (bootpath));
1546
if (ctxt->state[NETBSD_ROOT_ARG].set)
1548
char root[GRUB_NETBSD_MAX_ROOTDEVICE_LEN];
1549
grub_memset (root, 0, sizeof (root));
1550
grub_strncpy (root, ctxt->state[NETBSD_ROOT_ARG].arg,
1552
grub_bsd_add_meta (NETBSD_BTINFO_ROOTDEVICE, root, sizeof (root));
1554
if (ctxt->state[NETBSD_SERIAL_ARG].set)
1556
struct grub_netbsd_btinfo_serial serial;
1559
grub_memset (&serial, 0, sizeof (serial));
1560
grub_strcpy (serial.devname, "com");
1562
serial.addr = grub_ns8250_hw_get_port (0);
1563
serial.speed = 9600;
1565
if (ctxt->state[NETBSD_SERIAL_ARG].arg)
1567
ptr = ctxt->state[NETBSD_SERIAL_ARG].arg;
1568
if (grub_memcmp (ptr, "com", sizeof ("com") - 1) == 0)
1570
ptr += sizeof ("com") - 1;
1572
= grub_ns8250_hw_get_port (grub_strtoul (ptr, &ptr, 0));
1575
serial.addr = grub_strtoul (ptr, &ptr, 0);
1582
serial.speed = grub_strtoul (ptr, &ptr, 0);
1588
grub_bsd_add_meta (NETBSD_BTINFO_CONSOLE, &serial, sizeof (serial));
1592
struct grub_netbsd_btinfo_serial cons;
1594
grub_memset (&cons, 0, sizeof (cons));
1595
grub_strcpy (cons.devname, "pc");
1597
grub_bsd_add_meta (NETBSD_BTINFO_CONSOLE, &cons, sizeof (cons));
1600
grub_loader_set (grub_netbsd_boot, grub_bsd_unload, 0);
1607
grub_cmd_freebsd_loadenv (grub_command_t cmd __attribute__ ((unused)),
1608
int argc, char *argv[])
1610
grub_file_t file = 0;
1611
char *buf = 0, *curr, *next;
1614
if (kernel_type == KERNEL_TYPE_NONE)
1615
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1616
"you need to load the kernel first");
1618
if (kernel_type != KERNEL_TYPE_FREEBSD)
1619
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1620
"only FreeBSD supports environment");
1624
grub_error (GRUB_ERR_BAD_ARGUMENT, "no filename");
1628
file = grub_file_open (argv[0]);
1629
if ((!file) || (!file->size))
1633
buf = grub_malloc (len + 1);
1637
if (grub_file_read (file, buf, len) != len)
1648
next = grub_strchr (curr, '\n');
1655
if ((*p != '\r') && (*p != ' ') && (*p != '\t'))
1660
if ((p > curr) && (*p == '"'))
1670
p = grub_strchr (curr, '=');
1683
name = grub_xasprintf ("kFreeBSD.%s", curr);
1686
if (grub_env_set (name, p))
1699
grub_file_close (file);
1705
grub_cmd_freebsd_module (grub_command_t cmd __attribute__ ((unused)),
1706
int argc, char *argv[])
1708
grub_file_t file = 0;
1715
if (kernel_type != KERNEL_TYPE_FREEBSD)
1716
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no FreeBSD loaded");
1719
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1720
"only ELF kernel supports module");
1722
/* List the current modules if no parameter. */
1725
grub_freebsd_list_modules ();
1729
file = grub_file_open (argv[0]);
1730
if ((!file) || (!file->size))
1734
grub_relocator_chunk_t ch;
1735
err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end,
1739
src = get_virtual_current_address (ch);
1743
grub_file_read (file, src, file->size);
1750
if (modargc && (! grub_memcmp (modargv[0], "type=", 5)))
1752
type = &modargv[0][5];
1757
type = FREEBSD_MODTYPE_RAW;
1759
err = grub_freebsd_add_meta_module (argv[0], type, modargc, modargv,
1760
kern_end, file->size);
1764
kern_end = ALIGN_PAGE (kern_end + file->size);
1768
grub_file_close (file);
1774
grub_netbsd_module_load (char *filename, grub_uint32_t type)
1776
grub_file_t file = 0;
1780
file = grub_file_open (filename);
1781
if ((!file) || (!file->size))
1785
grub_relocator_chunk_t ch;
1786
err = grub_relocator_alloc_chunk_addr (relocator, &ch, kern_end,
1791
src = get_virtual_current_address (ch);
1794
grub_file_read (file, src, file->size);
1798
err = grub_netbsd_add_meta_module (filename, type, kern_end, file->size);
1803
kern_end = ALIGN_PAGE (kern_end + file->size);
1807
grub_file_close (file);
1813
grub_cmd_netbsd_module (grub_command_t cmd,
1814
int argc, char *argv[])
1818
if (kernel_type != KERNEL_TYPE_NETBSD)
1819
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no NetBSD loaded");
1822
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1823
"only ELF kernel supports module");
1825
/* List the current modules if no parameter. */
1828
grub_netbsd_list_modules ();
1832
if (grub_strcmp (cmd->name, "knetbsd_module_elf") == 0)
1833
type = GRUB_NETBSD_MODULE_ELF;
1835
type = GRUB_NETBSD_MODULE_RAW;
1837
return grub_netbsd_module_load (argv[0], type);
1841
grub_cmd_freebsd_module_elf (grub_command_t cmd __attribute__ ((unused)),
1842
int argc, char *argv[])
1844
grub_file_t file = 0;
1847
if (kernel_type == KERNEL_TYPE_NONE)
1848
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1849
"you need to load the kernel first");
1851
if (kernel_type != KERNEL_TYPE_FREEBSD)
1852
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1853
"only FreeBSD supports module");
1855
if (! is_elf_kernel)
1856
return grub_error (GRUB_ERR_BAD_ARGUMENT,
1857
"only ELF kernel supports module");
1859
/* List the current modules if no parameter. */
1862
grub_freebsd_list_modules ();
1866
file = grub_file_open (argv[0]);
1871
grub_file_close (file);
1876
err = grub_freebsd_load_elfmodule_obj64 (relocator, file,
1877
argc, argv, &kern_end);
1879
err = grub_freebsd_load_elfmodule32 (relocator, file,
1880
argc, argv, &kern_end);
1881
grub_file_close (file);
1887
grub_cmd_openbsd_ramdisk (grub_command_t cmd __attribute__ ((unused)),
1888
int argc, char *args[])
1894
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
1896
if (kernel_type != KERNEL_TYPE_OPENBSD)
1897
return grub_error (GRUB_ERR_BAD_OS, "no kOpenBSD loaded");
1899
if (!openbsd_ramdisk.max_size)
1900
return grub_error (GRUB_ERR_BAD_OS, "your kOpenBSD doesn't support ramdisk");
1902
file = grub_file_open (args[0]);
1904
return grub_error (GRUB_ERR_FILE_NOT_FOUND,
1905
"couldn't load ramdisk");
1907
size = grub_file_size (file);
1909
if (size > openbsd_ramdisk.max_size)
1911
grub_file_close (file);
1912
return grub_error (GRUB_ERR_BAD_OS, "your kOpenBSD supports ramdisk only"
1913
" up to %u bytes, however you supplied a %u bytes one",
1914
openbsd_ramdisk.max_size, size);
1917
if (grub_file_read (file, openbsd_ramdisk.target, size)
1918
!= (grub_ssize_t) (size))
1920
grub_file_close (file);
1922
return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[0]);
1924
grub_memset (openbsd_ramdisk.target + size, 0,
1925
openbsd_ramdisk.max_size - size);
1926
*openbsd_ramdisk.size = ALIGN_UP (size, 512);
1928
return GRUB_ERR_NONE;
1931
static grub_extcmd_t cmd_freebsd, cmd_openbsd, cmd_netbsd;
1932
static grub_command_t cmd_freebsd_loadenv, cmd_freebsd_module;
1933
static grub_command_t cmd_netbsd_module, cmd_freebsd_module_elf;
1934
static grub_command_t cmd_netbsd_module_elf, cmd_openbsd_ramdisk;
1938
/* Net and OpenBSD kernels are often compressed. */
1939
grub_dl_load ("gzio");
1941
cmd_freebsd = grub_register_extcmd ("kfreebsd", grub_cmd_freebsd, 0,
1942
N_("FILE"), N_("Load kernel of FreeBSD."),
1944
cmd_openbsd = grub_register_extcmd ("kopenbsd", grub_cmd_openbsd, 0,
1945
N_("FILE"), N_("Load kernel of OpenBSD."),
1947
cmd_netbsd = grub_register_extcmd ("knetbsd", grub_cmd_netbsd, 0,
1948
N_("FILE"), N_("Load kernel of NetBSD."),
1950
cmd_freebsd_loadenv =
1951
grub_register_command ("kfreebsd_loadenv", grub_cmd_freebsd_loadenv,
1952
0, N_("Load FreeBSD env."));
1953
cmd_freebsd_module =
1954
grub_register_command ("kfreebsd_module", grub_cmd_freebsd_module,
1955
0, N_("Load FreeBSD kernel module."));
1957
grub_register_command ("knetbsd_module", grub_cmd_netbsd_module,
1958
0, N_("Load NetBSD kernel module."));
1959
cmd_netbsd_module_elf =
1960
grub_register_command ("knetbsd_module_elf", grub_cmd_netbsd_module,
1961
0, N_("Load NetBSD kernel module (ELF)."));
1962
cmd_freebsd_module_elf =
1963
grub_register_command ("kfreebsd_module_elf", grub_cmd_freebsd_module_elf,
1964
0, N_("Load FreeBSD kernel module (ELF)."));
1966
cmd_openbsd_ramdisk = grub_register_command ("kopenbsd_ramdisk",
1967
grub_cmd_openbsd_ramdisk, 0,
1968
"Load kOpenBSD ramdisk. ");
1975
grub_unregister_extcmd (cmd_freebsd);
1976
grub_unregister_extcmd (cmd_openbsd);
1977
grub_unregister_extcmd (cmd_netbsd);
1979
grub_unregister_command (cmd_freebsd_loadenv);
1980
grub_unregister_command (cmd_freebsd_module);
1981
grub_unregister_command (cmd_netbsd_module);
1982
grub_unregister_command (cmd_freebsd_module_elf);
1983
grub_unregister_command (cmd_netbsd_module_elf);
1984
grub_unregister_command (cmd_openbsd_ramdisk);