1 /* loadbios.c - command to load a bios dump */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 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/>.
21 #include <grub/misc.h>
22 #include <grub/file.h>
23 #include <grub/efi/efi.h>
25 #include <grub/command.h>
26 #include <grub/i18n.h>
28 GRUB_MOD_LICENSE ("GPLv3+");
30 static grub_efi_guid_t acpi_guid
= GRUB_EFI_ACPI_TABLE_GUID
;
31 static grub_efi_guid_t acpi2_guid
= GRUB_EFI_ACPI_20_TABLE_GUID
;
32 static grub_efi_guid_t smbios_guid
= GRUB_EFI_SMBIOS_TABLE_GUID
;
34 #define EBDA_SEG_ADDR 0x40e
35 #define LOW_MEM_ADDR 0x413
36 #define FAKE_EBDA_SEG 0x9fc0
38 #define BLANK_MEM 0xffffffff
39 #define VBIOS_ADDR 0xc0000
40 #define SBIOS_ADDR 0xf0000
43 enable_rom_area (void)
45 grub_pci_address_t addr
;
46 grub_uint32_t
*rom_ptr
;
47 grub_pci_device_t dev
= { .bus
= 0, .device
= 0, .function
= 0};
49 rom_ptr
= (grub_uint32_t
*) VBIOS_ADDR
;
50 if (*rom_ptr
!= BLANK_MEM
)
52 grub_puts_ (N_("ROM image is present."));
56 /* FIXME: should be macroified. */
57 addr
= grub_pci_make_address (dev
, 144);
58 grub_pci_write_byte (addr
++, 0x30);
59 grub_pci_write_byte (addr
++, 0x33);
60 grub_pci_write_byte (addr
++, 0x33);
61 grub_pci_write_byte (addr
++, 0x33);
62 grub_pci_write_byte (addr
++, 0x33);
63 grub_pci_write_byte (addr
++, 0x33);
64 grub_pci_write_byte (addr
++, 0x33);
65 grub_pci_write_byte (addr
, 0);
70 grub_puts_ (N_("Can\'t enable ROM area."));
80 grub_pci_address_t addr
;
81 grub_pci_device_t dev
= { .bus
= 0, .device
= 0, .function
= 0};
83 /* FIXME: should be macroified. */
84 addr
= grub_pci_make_address (dev
, 144);
85 grub_pci_write_byte (addr
++, 0x10);
86 grub_pci_write_byte (addr
++, 0x11);
87 grub_pci_write_byte (addr
++, 0x11);
88 grub_pci_write_byte (addr
++, 0x11);
89 grub_pci_write_byte (addr
, 0x11);
93 fake_bios_data (int use_rom
)
97 grub_uint16_t
*ebda_seg_ptr
, *low_mem_ptr
;
99 ebda_seg_ptr
= (grub_uint16_t
*) EBDA_SEG_ADDR
;
100 low_mem_ptr
= (grub_uint16_t
*) LOW_MEM_ADDR
;
101 if ((*ebda_seg_ptr
) || (*low_mem_ptr
))
106 for (i
= 0; i
< grub_efi_system_table
->num_table_entries
; i
++)
108 grub_efi_packed_guid_t
*guid
=
109 &grub_efi_system_table
->configuration_table
[i
].vendor_guid
;
111 if (! grub_memcmp (guid
, &acpi2_guid
, sizeof (grub_efi_guid_t
)))
113 acpi
= grub_efi_system_table
->configuration_table
[i
].vendor_table
;
114 grub_dprintf ("efi", "ACPI2: %p\n", acpi
);
116 else if (! grub_memcmp (guid
, &acpi_guid
, sizeof (grub_efi_guid_t
)))
120 t
= grub_efi_system_table
->configuration_table
[i
].vendor_table
;
123 grub_dprintf ("efi", "ACPI: %p\n", t
);
125 else if (! grub_memcmp (guid
, &smbios_guid
, sizeof (grub_efi_guid_t
)))
127 smbios
= grub_efi_system_table
->configuration_table
[i
].vendor_table
;
128 grub_dprintf ("efi", "SMBIOS: %p\n", smbios
);
132 *ebda_seg_ptr
= FAKE_EBDA_SEG
;
133 *low_mem_ptr
= (FAKE_EBDA_SEG
>> 6);
135 *((grub_uint16_t
*) (FAKE_EBDA_SEG
<< 4)) = 640 - *low_mem_ptr
;
138 grub_memcpy ((char *) ((FAKE_EBDA_SEG
<< 4) + 16), acpi
, 1024 - 16);
140 if ((use_rom
) && (smbios
))
141 grub_memcpy ((char *) SBIOS_ADDR
, (char *) smbios
+ 16, 16);
145 grub_cmd_fakebios (struct grub_command
*cmd
__attribute__ ((unused
)),
146 int argc
__attribute__ ((unused
)),
147 char *argv
[] __attribute__ ((unused
)))
149 if (enable_rom_area ())
161 grub_cmd_loadbios (grub_command_t cmd
__attribute__ ((unused
)),
162 int argc
, char *argv
[])
168 return grub_error (GRUB_ERR_BAD_ARGUMENT
, N_("filename expected"));
172 file
= grub_file_open (argv
[1]);
177 grub_error (GRUB_ERR_BAD_ARGUMENT
, "invalid int10 dump size");
179 grub_file_read (file
, (void *) 0x40, 4);
181 grub_file_close (file
);
186 file
= grub_file_open (argv
[0]);
191 if ((size
< 0x10000) || (size
> 0x40000))
192 grub_error (GRUB_ERR_BAD_ARGUMENT
, "invalid bios dump size");
193 else if (enable_rom_area ())
195 grub_file_read (file
, (void *) VBIOS_ADDR
, size
);
196 fake_bios_data (size
<= 0x40000);
200 grub_file_close (file
);
204 static grub_command_t cmd_fakebios
, cmd_loadbios
;
206 GRUB_MOD_INIT(loadbios
)
208 cmd_fakebios
= grub_register_command ("fakebios", grub_cmd_fakebios
,
209 0, N_("Create BIOS-like structures for"
210 " backward compatibility with"
213 cmd_loadbios
= grub_register_command ("loadbios", grub_cmd_loadbios
,
214 N_("BIOS_DUMP [INT10_DUMP]"),
215 N_("Load BIOS dump."));
218 GRUB_MOD_FINI(loadbios
)
220 grub_unregister_command (cmd_fakebios
);
221 grub_unregister_command (cmd_loadbios
);