SCRIPTS = $(bin_SCRIPTS) $(sbin_SCRIPTS) $(grub-mkconfig_SCRIPTS)
CLEANFILES =
-MOSTLYCLEANFILES =
+MOSTLYCLEANFILES =
DISTCLEANFILES = config.status config.cache config.log config.h \
Makefile stamp-h include/grub/cpu include/grub/machine \
gensymlist.sh genkernsyms.sh build_env.mk
[whether an absolute indirect call/jump must not be prefixed with an asterisk])
AC_CACHE_VAL(grub_cv_i386_asm_absolute_without_asterisk,
[cat > conftest.s <<\EOF
- lcall *(offset)
+ lcall *(offset)
offset:
.long 0
.word 0
#include <grub/boot.h>
#include <grub/machine/boot.h>
-
+
/*
* defines for the code go here
*/
in real mode. */
.code16
-.globl _start, start;
+.globl _start, start;
_start:
start:
/*
/* scratch space */
mode:
.byte 0
-disk_address_packet:
+disk_address_packet:
sectors:
.long 0
heads:
* End of BIOS parameter block.
*/
-boot_version:
+boot_version:
.byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
kernel_address:
.word GRUB_BOOT_MACHINE_KERNEL_ADDR
.word GRUB_BOOT_MACHINE_KERNEL_SEG
kernel_sector:
.long 1, 0
-boot_drive:
+boot_drive:
.byte 0xff /* the disk to load kernel from */
/* 0xff means use the boot drive */
root_drive:
jnz 1f
movb $0x80, %dl
1:
-
+
/*
* ljmp to the next instruction because some bogus BIOSes
* jump to 07C0:0000 instead of 0000:7C00.
ljmp $0, $ABS(real_start)
#endif
-real_start:
+real_start:
/* set up %ds and %ss as offset from 0 */
xorw %ax, %ax
#else
movw $ABS(disk_address_packet), %si
#endif
-
+
/* do not probe LBA if the drive is a floppy */
testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
jz chs_mode
-
+
/* check if LBA is supported */
movb $0x41, %ah
movw $0x55aa, %bx
int $0x13
- /*
+ /*
* %dl may have been clobbered by INT 13, AH=41H.
* This happens, for example, with AST BIOS 1.04.
*/
andw $1, %cx
jz chs_mode
-
+
lba_mode:
xorw %ax, %ax
movw %ax, 4(%si)
- incw %ax
+ incw %ax
/* set the mode to non-zero */
movb %al, -1(%si)
-
+
/* the blocks */
movw %ax, 2(%si)
movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
jmp copy_buffer
-
-chs_mode:
+
+chs_mode:
/*
* Determine the hard disk geometry from the BIOS!
* We do this first, so that LS-120 IDE floppies work correctly.
/* set the mode to zero */
movzbl %dh, %eax
movb %ah, -1(%si)
-
+
/* save number of heads */
incw %ax
movl %eax, 4(%si)
orl %eax, %eax
jnz geometry_error
-
+
/* load logical sector start (bottom half) */
#ifdef APPLE_CC
movl (kernel_sector_abs), %eax
jc read_error
movw %es, %bx
-
+
copy_buffer:
#ifdef APPLE_CC
kernel_segment_abs = ABS (kernel_segment)
*/
pusha
pushw %ds
-
+
movw $0x100, %cx
movw %bx, %ds
xorw %si, %si
xorw %di, %di
-
+
cld
-
+
rep
movsw
*/
. = _start + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC
-nt_magic:
+nt_magic:
.long 0
.word 0
* sneaky, huh?
*/
-part_start:
+part_start:
. = _start + GRUB_BOOT_MACHINE_PART_START
probe_values:
/* Root drive will default to boot drive */
movb $0xFF, %dh
-
+
ljmp $(DATA_ADDR >> 4), $0
/*
*/
#include <grub/machine/boot.h>
-
+
/*
* defines for the code go here
*/
This makes the assembler generate the address without support
from the linker. (ELF can't relocate 16-bit addresses!) */
#define ABS(x) (x-_start+GRUB_BOOT_MACHINE_KERNEL_ADDR)
-
+
/* Print message string */
#ifdef APPLE_CC
#define MSG(x) x ## _abs = ABS(x); mov $x ## _abs, %esi; call message
.globl start, _start
start:
-_start:
+_start:
/*
* _start is loaded at 0x2000 and is jumped to with
* CS:IP 0:0x2000 in kernel.
*/
- /*
+ /*
* we continue to use the stack for boot.img and assume that
* some registers are set to correct values. See boot.S
* for more information.
*/
-
+
/* save drive reference first thing! */
pushw %dx
pushw %si
MSG(notification_string)
popw %si
-
+
/* this sets up for the first run through "bootloop" */
#ifdef APPLE_CC
firstlist_off_abs = ABS (firstlist - GRUB_BOOT_MACHINE_LIST_SIZE)
/* if zero, go to the start function */
je bootit
-setup_sectors:
+setup_sectors:
/* check if we use LBA or CHS */
cmpb $0, -1(%si)
/* jump to chs_mode if zero */
je chs_mode
-lba_mode:
+lba_mode:
/* load logical sector start */
movl (%di), %ebx
movl 4(%di), %ecx
/* if less than, set to total */
movw 8(%di), %ax
-1:
+1:
/* subtract from total */
subw %ax, 8(%di)
movw $GRUB_BOOT_MACHINE_BUFFER_SEG, %bx
jmp copy_buffer
-
-chs_mode:
+
+chs_mode:
/* load logical sector start (top half) */
movl 4(%di), %eax
orl %eax, %eax
/* if less than, set to total */
movw 8(%di), %ax
-2:
+2:
/* subtract from total */
subw %ax, 8(%di)
/* save source segment */
movw %es, %bx
-
-copy_buffer:
+
+copy_buffer:
/* load addresses for copy from disk buffer to destination */
movw 10(%di), %es /* load destination segment */
rep /* sets a repeat */
movsw /* this runs the actual copy */
- /* restore addressing regs and print a dot with correct DS
+ /* restore addressing regs and print a dot with correct DS
(MSG modifies SI, which is saved, and unused AX and BX) */
popw %ds
MSG(notification_step)
notification_step: .asciz "."
notification_done: .asciz "\r\n"
-
+
geometry_error_string: .asciz "Geom"
read_error_string: .asciz "Read"
general_error_string: .asciz " Error"
.word 0
. = _start + 0x200 - GRUB_BOOT_MACHINE_LIST_SIZE
-
+
/* fill the first data listing with the default */
blocklist_default_start:
/* this is the sector start parameter, in logical sectors from
blocklist_default_seg:
/* this is the segment of the starting address to load the data into */
.word (GRUB_BOOT_MACHINE_KERNEL_SEG + 0x20)
-
+
firstlist: /* this label has to be after the list data!!! */
#include <multiboot.h>
.file "lnxboot.S"
-
+
#ifdef APPLE_CC
#error Building lnxboot.img with Apple's as results in an unusable image
#endif
. = data_start + 0x1F1
setup_sects:
-/* Apple's cc can't fill this value. */
+/* Apple's cc can't fill this value. */
#ifdef APPLE_CC
.byte 0
#else
linux_init:
#ifdef APPLE_CC
- reg_edx_rel = reg_edx - start
- code32_start_rel = code32_start - start
+ reg_edx_rel = reg_edx - start
+ code32_start_rel = code32_start - start
movw %cs:(reg_edx_rel), %dx
movl %cs:(code32_start_rel), %ebp
#else
/* Start with the prehistoric environment... */
.code16
-
+
/* Let's go */
-.globl start, _start;
+.globl start, _start;
_start:
-start:
+start:
/* Root drive will default to boot drive */
movb $0xFF, %dh
movb $0x7F, %dl
-
+
/* Jump to the real world */
ljmp $0, $0x8200
/* Setup the HCCA. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca);
grub_dprintf ("ohci", "OHCI HCCA\n");
-
+
/* Enable the OHCI. */
grub_ohci_writereg32 (o, GRUB_OHCI_REG_CONTROL,
(2 << 6));
grub_dprintf ("ohci", "OHCI enable: 0x%02x\n",
(grub_ohci_readreg32 (o, GRUB_OHCI_REG_CONTROL) >> 6) & 3);
-
+
/* Link to ohci now that initialisation is successful. */
o->next = ohci;
ohci = o;
}
static void
-grub_ohci_transaction (grub_ohci_td_t td,
+grub_ohci_transaction (grub_ohci_td_t td,
grub_transfer_type_t type, unsigned int toggle,
grub_size_t size, char *data)
{
grub_usb_transaction_t tr = &transfer->transactions[i];
grub_ohci_transaction (&td_list[i], tr->pid, tr->toggle,
- tr->size, tr->data);
+ tr->size, tr->data);
td_list[i].next_td = grub_cpu_to_le32 (&td_list[i + 1]);
}
GRUB_MOD_FINI(ohci)
{
- grub_usb_controller_dev_unregister (&usb_controller);
+ grub_usb_controller_dev_unregister (&usb_controller);
}
td = grub_uhci_transaction (u, transfer->endpoint, tr->pid,
transfer->devaddr, tr->toggle,
- tr->size, tr->data);
+ tr->size, tr->data);
if (! td)
{
/* Terminate and free. */
/* Check if a babble error occurred. */
if (errtd->ctrl_status & (1 << 20))
err = GRUB_USB_ERR_BABBLE;
-
+
/* Check if a NAK occurred. */
if (errtd->ctrl_status & (1 << 19))
err = GRUB_USB_ERR_NAK;
/* Skip the configuration descriptor. */
pos = sizeof (struct grub_usb_desc_config);
-
+
/* Read all interfaces. */
for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
{
max = 64;
datablocks = (size + max - 1) / max;
-
+
/* XXX: Discriminate between different types of control
messages. */
transfer->transcnt = datablocks + 2;
transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_OUT;
else
transfer->transactions[datablocks + 1].pid = GRUB_USB_TRANSFER_TYPE_IN;
-
+
transfer->transactions[datablocks + 1].toggle = 1;
err = dev->controller.dev->transfer (&dev->controller, transfer);
tr->data = &data[i * max];
size -= tr->size;
}
-
+
err = dev->controller.dev->transfer (&dev->controller, transfer);
grub_dprintf ("usb", "toggle=%d\n", toggle);
dev->toggle[endpoint] = toggle;
#endif
static const struct grub_arg_option options[] = {
- {"exclude", 'x', 0,
- "Don't load host tables specified by comma-separated list",
+ {"exclude", 'x', 0,
+ "Don't load host tables specified by comma-separated list",
0, ARG_TYPE_STRING},
- {"load-only", 'n', 0,
+ {"load-only", 'n', 0,
"Load only tables specified by comma-separated list", 0, ARG_TYPE_STRING},
{"v1", '1', 0, "Expose v1 tables", 0, ARG_TYPE_NONE},
{"v2", '2', 0, "Expose v2 and v3 tables", 0, ARG_TYPE_NONE},
{"oemid", 'o', 0, "Set OEMID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
- {"oemtable", 't', 0,
- "Set OEMTABLE ID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
- {"oemtablerev", 'r', 0,
- "Set OEMTABLE revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
- {"oemtablecreator", 'c', 0,
- "Set creator field of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
- {"oemtablecreatorrev", 'd', 0,
- "Set creator revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
+ {"oemtable", 't', 0,
+ "Set OEMTABLE ID of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+ {"oemtablerev", 'r', 0,
+ "Set OEMTABLE revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
+ {"oemtablecreator", 'c', 0,
+ "Set creator field of RSDP, XSDT and RSDT", 0, ARG_TYPE_STRING},
+ {"oemtablecreatorrev", 'd', 0,
+ "Set creator revision of RSDP, XSDT and RSDT", 0, ARG_TYPE_INT},
{"no-ebda", 'e', 0, "Don't update EBDA. May fix failures or hangs on some"
" BIOSes but makes it ineffective with OS not receiving RSDP from GRUB",
0, ARG_TYPE_NONE},
};
/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */
-grub_uint8_t
+grub_uint8_t
grub_byte_checksum (void *base, grub_size_t size)
{
grub_uint8_t *ptr;
return ret;
}
-/* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise.
+/* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise.
rev2 contains the revision of ACPIv2+ to generate or 0 if none. */
static int rev1, rev2;
/* OEMID of RSDP, RSDT and XSDT. */
return grub_machine_acpi_get_rsdpv1 ();
}
-static inline int
+static inline int
iszero (grub_uint8_t *reg, int size)
{
int i;
return 1;
}
-grub_err_t
+grub_err_t
grub_acpi_create_ebda (void)
{
int ebda_kb_len;
grub_uint8_t *targetebda, *target;
struct grub_acpi_rsdp_v10 *v1;
struct grub_acpi_rsdp_v20 *v2;
- auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
+ auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
grub_uint32_t);
- int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size,
+ int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t size,
grub_uint32_t type)
{
grub_uint64_t end = start + size;
highestlow = (end - ebda_len) & (~0xf);
return 0;
}
-
+
ebda = (grub_uint8_t *) UINT_TO_PTR ((*((grub_uint16_t *)0x40e)) << 4);
ebda_kb_len = *(grub_uint16_t *) ebda;
if (! ebda || ebda_kb_len > 16)
grub_dprintf ("acpi", "creating ebda @%llx\n",
(unsigned long long) highestlow);
if (! highestlow)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't find space for the new EBDA");
- mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len,
+ mmapregion = grub_mmap_register (PTR_TO_UINT64 (targetebda), ebda_len,
GRUB_MACHINE_MEMORY_RESERVED);
if (! mmapregion)
return grub_errno;
if (v2 && v2->length > 40)
v2 = 0;
- /* First try to replace already existing rsdp. */
+ /* First try to replace already existing rsdp. */
if (v2)
{
grub_dprintf ("acpi", "Scanning EBDA for old rsdpv2\n");
for (; target < targetebda + 0x400 - v2->length; target += 0x10)
if (grub_memcmp (target, "RSD PTR ", 8) == 0
- && grub_byte_checksum (target,
+ && grub_byte_checksum (target,
sizeof (struct grub_acpi_rsdp_v10)) == 0
&& ((struct grub_acpi_rsdp_v10 *) target)->revision != 0
&& ((struct grub_acpi_rsdp_v20 *) target)->length <= v2->length)
if (v1)
{
grub_dprintf ("acpi", "Scanning EBDA for old rsdpv1\n");
- for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+ for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
target += 0x10)
if (grub_memcmp (target, "RSD PTR ", 8) == 0
- && grub_byte_checksum (target,
+ && grub_byte_checksum (target,
sizeof (struct grub_acpi_rsdp_v10)) == 0)
{
grub_memcpy (target, v1, sizeof (struct grub_acpi_rsdp_v10));
if (v1)
{
grub_dprintf ("acpi", "Scanning EBDA for block of zeros\n");
- for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+ for (; target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
target += 0x10)
if (iszero (target, sizeof (struct grub_acpi_rsdp_v10)))
{
if (v1 || v2)
{
grub_mmap_unregister (mmapregion);
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Couldn't find suitable spot in EBDA");
}
/* Remove any other RSDT. */
- for (target = targetebda;
- target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
+ for (target = targetebda;
+ target < targetebda + 0x400 - sizeof (struct grub_acpi_rsdp_v10);
target += 0x10)
if (grub_memcmp (target, "RSD PTR ", 8) == 0
- && grub_byte_checksum (target,
+ && grub_byte_checksum (target,
sizeof (struct grub_acpi_rsdp_v10)) == 0
&& target != v1inebda && target != v2inebda)
*target = 0;
grub_free (table_dsdt);
table_dsdt = playground_ptr;
playground_ptr += dsdt_size;
-
+
/* Treat other tables. */
for (cur = acpi_tables; cur; cur = cur->next)
{
fadt->hdr.checksum = 1 + ~grub_byte_checksum (fadt, fadt->hdr.length);
}
}
-
+
/* Fill RSDT entries. */
numoftables = 0;
for (cur = acpi_tables; cur; cur = cur->next)
for (cur = acpi_tables; cur; cur = cur->next)
*(rsdt_entry++) = PTR_TO_UINT32 (cur->addr);
-
+
/* Recompute checksum. */
rsdt->checksum = 0;
rsdt->checksum = 1 + ~grub_byte_checksum (rsdt, rsdt->length);
rsdpv1_new->revision = 0;
rsdpv1_new->rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
rsdpv1_new->checksum = 0;
- rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new,
- sizeof (*rsdpv1_new));
+ rsdpv1_new->checksum = 1 + ~grub_byte_checksum (rsdpv1_new,
+ sizeof (*rsdpv1_new));
grub_dprintf ("acpi", "Generated ACPIv1 tables\n");
}
/* Create RSDPv2. */
rsdpv2_new = (struct grub_acpi_rsdp_v20 *) playground_ptr;
playground_ptr += sizeof (struct grub_acpi_rsdp_v20);
- grub_memcpy (&(rsdpv2_new->rsdpv1.signature), "RSD PTR ",
+ grub_memcpy (&(rsdpv2_new->rsdpv1.signature), "RSD PTR ",
sizeof (rsdpv2_new->rsdpv1.signature));
- grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
+ grub_memcpy (&(rsdpv2_new->rsdpv1.oemid), root_oemid,
sizeof (rsdpv2_new->rsdpv1.oemid));
rsdpv2_new->rsdpv1.revision = rev2;
rsdpv2_new->rsdpv1.rsdt_addr = PTR_TO_UINT32 (rsdt_addr);
rsdpv2_new->rsdpv1.checksum = 0;
- rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum
+ rsdpv2_new->rsdpv1.checksum = 1 + ~grub_byte_checksum
(&(rsdpv2_new->rsdpv1), sizeof (rsdpv2_new->rsdpv1));
rsdpv2_new->length = sizeof (*rsdpv2_new);
rsdpv2_new->xsdt_addr = PTR_TO_UINT64 (xsdt);
rsdpv2_new->checksum = 0;
- rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new,
+ rsdpv2_new->checksum = 1 + ~grub_byte_checksum (rsdpv2_new,
rsdpv2_new->length);
grub_dprintf ("acpi", "Generated ACPIv2 tables\n");
}
grub_err_t err;
int i, mmapregion;
int numoftables;
-
+
/* Default values if no RSDP is found. */
rev1 = 1;
rev2 = 3;
facs_addr = 0;
playground = playground_ptr = 0;
playground_size = 0;
-
+
rsdp = (struct grub_acpi_rsdp_v10 *) grub_machine_acpi_get_rsdpv2 ();
if (! rsdp)
rsdt = (struct grub_acpi_table_header *) UINT_TO_PTR (rsdp->rsdt_addr);
/* Load host tables. */
for (entry_ptr = (grub_uint32_t *) (rsdt + 1);
- entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
+ entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt)
+ rsdt->length);
entry_ptr++)
{
char signature[5];
struct efiemu_acpi_table *table;
- struct grub_acpi_table_header *curtable
+ struct grub_acpi_table_header *curtable
= (struct grub_acpi_table_header *) UINT_TO_PTR (*entry_ptr);
signature[4] = 0;
for (i = 0; i < 4;i++)
signature[i] = grub_tolower (curtable->signature[i]);
-
+
/* If it's FADT it contains addresses of DSDT and FACS. */
if (grub_strcmp (signature, "facp") == 0)
{
struct grub_acpi_table_header *dsdt;
struct grub_acpi_fadt *fadt = (struct grub_acpi_fadt *) curtable;
- /* Set root header variables to the same values
+ /* Set root header variables to the same values
as FACP by default. */
- grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
+ grub_memcpy (&root_oemid, &(fadt->hdr.oemid),
sizeof (root_oemid));
- grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
+ grub_memcpy (&root_oemtable, &(fadt->hdr.oemtable),
sizeof (root_oemtable));
root_oemrev = fadt->hdr.oemrev;
- grub_memcpy (&root_creator_id, &(fadt->hdr.creator_id),
+ grub_memcpy (&root_creator_id, &(fadt->hdr.creator_id),
sizeof (root_creator_id));
root_creator_rev = fadt->hdr.creator_rev;
/* Load DSDT if not excluded. */
- dsdt = (struct grub_acpi_table_header *)
+ dsdt = (struct grub_acpi_table_header *)
UINT_TO_PTR (fadt->dsdt_addr);
if (dsdt && (! exclude || ! grub_strword (exclude, "dsdt"))
&& (! load_only || grub_strword (load_only, "dsdt"))
free_tables ();
grub_free (exclude);
grub_free (load_only);
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table");
}
grub_memcpy (table_dsdt, dsdt, dsdt->length);
/* Save FACS address. FACS shouldn't be overridden. */
facs_addr = fadt->facs_addr;
}
-
+
/* Skip excluded tables. */
if (exclude && grub_strword (exclude, signature))
continue;
/* Sanity check. */
if (curtable->length < sizeof (*curtable))
continue;
-
- table = (struct efiemu_acpi_table *) grub_malloc
+
+ table = (struct efiemu_acpi_table *) grub_malloc
(sizeof (struct efiemu_acpi_table));
if (! table)
{
free_tables ();
grub_free (exclude);
grub_free (load_only);
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table structure");
}
table->size = curtable->length;
if (! table->addr)
{
free_tables ();
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table");
}
table->next = acpi_tables;
grub_memcpy (table->addr, curtable, table->size);
}
grub_free (exclude);
- grub_free (load_only);
+ grub_free (load_only);
}
/* Does user specify versions to generate? */
{
grub_file_close (file);
free_tables ();
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't read file %s", args[i]);
}
free_tables ();
return grub_error (GRUB_ERR_BAD_OS, "couldn't read file %s", args[i]);
}
- grub_file_close (file);
+ grub_file_close (file);
- if (grub_memcmp (((struct grub_acpi_table_header *) buf)->signature,
+ if (grub_memcmp (((struct grub_acpi_table_header *) buf)->signature,
"DSDT", 4) == 0)
{
grub_free (table_dsdt);
else
{
struct efiemu_acpi_table *table;
- table = (struct efiemu_acpi_table *) grub_malloc
+ table = (struct efiemu_acpi_table *) grub_malloc
(sizeof (struct efiemu_acpi_table));
if (! table)
{
free_tables ();
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could allocate table structure");
}
playground_size += sizeof (struct grub_acpi_table_header) + 8 * numoftables;
/* RSDPv2. */
playground_size += sizeof (struct grub_acpi_rsdp_v20);
-
- playground = playground_ptr
+
+ playground = playground_ptr
= grub_mmap_malign_and_register (1, playground_size, &mmapregion,
GRUB_MACHINE_MEMORY_ACPI, 0);
if (! playground)
{
free_tables ();
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Couldn't allocate space for ACPI tables");
}
struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
- grub_efi_system_table->boot_services->install_configuration_table
+ grub_efi_system_table->boot_services->install_configuration_table
(&acpi20, grub_acpi_get_rsdpv2 ());
- grub_efi_system_table->boot_services->install_configuration_table
+ grub_efi_system_table->boot_services->install_configuration_table
(&acpi, grub_acpi_get_rsdpv1 ());
}
#endif
GRUB_MOD_INIT(acpi)
{
- cmd = grub_register_extcmd ("acpi", grub_cmd_acpi,
+ cmd = grub_register_extcmd ("acpi", grub_cmd_acpi,
GRUB_COMMAND_FLAG_BOTH,
"acpi [-1|-2] [--exclude=table1,table2|"
"--load-only=table1,table2] filename1 "
" [filename2] [...]",
"Load host acpi tables and tables "
- "specified by arguments",
+ "specified by arguments",
options);
}
unsigned length);
auto void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
unsigned offset, unsigned length);
-
+
void NESTED_FUNC_ATTR read_blocklist (grub_disk_addr_t sector, unsigned offset,
unsigned length)
{
num_sectors++;
return;
}
-
+
print_blocklist (start_sector, num_sectors, 0, 0);
num_sectors = 0;
}
else
print_blocklist (sector, 0, offset, length);
}
-
+
void NESTED_FUNC_ATTR print_blocklist (grub_disk_addr_t sector, unsigned num,
unsigned offset, unsigned length)
{
if (offset != 0 || length != 0)
grub_printf ("[%u-%u]", offset, offset + length);
}
-
+
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
if (file->device->disk->partition)
part_start = grub_partition_get_start (file->device->disk->partition);
-
+
file->read_hook = read_blocklist;
while (grub_file_read (file, buf, sizeof (buf)) > 0)
if (num_sectors > 0)
print_blocklist (start_sector, num_sectors, 0, 0);
-
+
grub_file_close (file);
return grub_errno;
};
static int grub_loader_loaded;
-static struct grub_preboot_t *preboots_head = 0,
+static struct grub_preboot_t *preboots_head = 0,
*preboots_tail = 0;
int
if (! preboot_func && ! preboot_rest_func)
return 0;
- new_preboot = (struct grub_preboot_t *)
+ new_preboot = (struct grub_preboot_t *)
grub_malloc (sizeof (struct grub_preboot_t));
if (! new_preboot)
{
return new_preboot;
}
-void
+void
grub_loader_unregister_preboot_hook (void *hnd)
{
struct grub_preboot_t *preb = hnd;
{
if (grub_loader_loaded && grub_loader_unload_func)
grub_loader_unload_func ();
-
+
grub_loader_boot_func = boot;
grub_loader_unload_func = unload;
grub_loader_noreturn = noreturn;
-
+
grub_loader_loaded = 1;
}
{
if (grub_loader_loaded && grub_loader_unload_func)
grub_loader_unload_func ();
-
+
grub_loader_boot_func = 0;
grub_loader_unload_func = 0;
err = (grub_loader_boot_func) ();
for (cur = preboots_tail; cur; cur = cur->prev)
- if (! err)
+ if (! err)
err = cur->preboot_rest_func ();
else
cur->preboot_rest_func ();
file = grub_gzfile_open (args[0], 1);
if (! file)
return 0;
-
+
while ((size = grub_file_read (file, buf, sizeof (buf))) > 0
&& key != GRUB_TERM_ESC)
{
int i;
-
+
for (i = 0; i < size; i++)
{
unsigned char c = buf[i];
-
+
if ((grub_isprint (c) || grub_isspace (c)) && c != '\r')
grub_putchar (c);
else
grub_putchar ('\n');
grub_refresh ();
grub_file_close (file);
-
+
return 0;
}
goto cleanup;
if (grub_file_size (file1) != grub_file_size (file2))
- grub_printf ("Differ in size: %llu [%s], %llu [%s]\n",
+ grub_printf ("Differ in size: %llu [%s], %llu [%s]\n",
(unsigned long long) grub_file_size (file1), args[0],
(unsigned long long) grub_file_size (file2), args[1]);
else
buf1 = grub_malloc (BUFFER_SIZE);
buf2 = grub_malloc (BUFFER_SIZE);
-
+
if (! buf1 || ! buf2)
goto cleanup;
-
+
do
{
int i;
-
+
rd1 = grub_file_read (file1, buf1, BUFFER_SIZE);
rd2 = grub_file_read (file2, buf2, BUFFER_SIZE);
}
}
pos += BUFFER_SIZE;
-
+
}
while (rd2);
-
+
grub_printf ("The files are identical.\n");
}
cleanup:
-
+
if (buf1)
grub_free (buf1);
if (buf2)
arg++;
continue;
}
-
+
/* This was not an escaped character, or escaping is not
enabled. */
grub_printf ("%c", *arg);
&grub_efi_system_table->configuration_table[i].vendor_guid;
if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_guid_t)))
- return (struct grub_acpi_rsdp_v10 *)
+ return (struct grub_acpi_rsdp_v10 *)
grub_efi_system_table->configuration_table[i].vendor_table;
}
return 0;
&grub_efi_system_table->configuration_table[i].vendor_guid;
if (! grub_memcmp (guid, &acpi20_guid, sizeof (grub_efi_guid_t)))
- return (struct grub_acpi_rsdp_v20 *)
+ return (struct grub_acpi_rsdp_v20 *)
grub_efi_system_table->configuration_table[i].vendor_table;
}
return 0;
/* Convert a LBA address to a CHS address in the INT 13 format. */
/* Taken from grub1. */
-/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
+/* XXX: use hardcoded geometry of C = 1024, H = 255, S = 63.
Is it a problem?
*/
-static void
-lba_to_chs (int lba, grub_uint8_t *cl, grub_uint8_t *ch,
+static void
+lba_to_chs (int lba, grub_uint8_t *cl, grub_uint8_t *ch,
grub_uint8_t *dh)
{
int cylinder, head, sector;
int sectors = 63, heads = 255, cylinders = 1024;
-
+
sector = lba % sectors + 1;
head = (lba / sectors) % heads;
cylinder = lba / (sectors * heads);
-
+
if (cylinder >= cylinders)
{
*cl = *ch = *dh = 0xff;
return;
}
-
+
*cl = sector | ((cylinder & 0x300) >> 2);
*ch = cylinder & 0xFF;
*dh = head;
}
static grub_err_t
-grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
+grub_cmd_gptsync (grub_command_t cmd __attribute__ ((unused)),
int argc, char **args)
{
grub_device_t dev;
if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
{
args[0][grub_strlen (args[0]) - 1] = 0;
- dev = grub_device_open (args[0] + 1);
+ dev = grub_device_open (args[0] + 1);
args[0][grub_strlen (args[0])] = ')';
}
else
- dev = grub_device_open (args[0]);
+ dev = grub_device_open (args[0]);
if (! dev)
return grub_errno;
/* Check if it is valid. */
if (mbr.signature != grub_cpu_to_le16 (GRUB_PC_PARTITION_SIGNATURE))
{
- grub_device_close (dev);
+ grub_device_close (dev);
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no signature");
}
grub_device_close (dev);
return grub_error (GRUB_ERR_BAD_PART_TABLE, "no GPT partition map found");
}
-
+
int i;
first_sector = dev->disk->total_sectors;
for (i = 1; i < argc; i++)
if (separator)
*separator = csep;
if (! partition)
- {
+ {
grub_device_close (dev);
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such partition");
}
if (partition->start + partition->len > 0xffffffff)
- {
+ {
grub_device_close (dev);
- return grub_error (GRUB_ERR_OUT_OF_RANGE,
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
"only partitions resding in the first 2TB "
"can be presen in hybrid MBR");
}
-
+
if (first_sector > partition->start)
first_sector = partition->start;
if (numactive == 2)
{
grub_device_close (dev);
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
"only one partition can be active");
}
}
mbr.entries[i].type = type;
mbr.entries[i].start = grub_cpu_to_le32 (partition->start);
- lba_to_chs (partition->start,
+ lba_to_chs (partition->start,
&(mbr.entries[i].start_sector),
&(mbr.entries[i].start_cylinder),
&(mbr.entries[i].start_head));
- lba_to_chs (partition->start + partition->len - 1,
+ lba_to_chs (partition->start + partition->len - 1,
&(mbr.entries[i].end_sector),
&(mbr.entries[i].end_cylinder),
&(mbr.entries[i].end_head));
mbr.entries[0].flag = 0;
mbr.entries[0].type = GRUB_PC_PARTITION_TYPE_GPT_DISK;
mbr.entries[0].start = grub_cpu_to_le32 (1);
- lba_to_chs (1,
+ lba_to_chs (1,
&(mbr.entries[0].start_sector),
&(mbr.entries[0].start_cylinder),
&(mbr.entries[0].start_head));
- lba_to_chs (first_sector,
+ lba_to_chs (first_sector,
&(mbr.entries[0].end_sector),
&(mbr.entries[0].end_cylinder),
&(mbr.entries[0].end_head));
GRUB_MOD_INIT(gptsync)
{
(void) mod; /* To stop warning. */
- cmd = grub_register_command ("gptsync", grub_cmd_gptsync,
- "gptsync DEVICE [PARTITION[+/-[TYPE]]] ...",
+ cmd = grub_register_command ("gptsync", grub_cmd_gptsync,
+ "gptsync DEVICE [PARTITION[+/-[TYPE]]] ...",
"Fill hybrid MBR of GPT drive DEVICE. "
"specified partitions will be a part "
"of hybrid mbr. Up to 3 partitions are "
{
int cnt = 0;
char *currarg;
-
+
auto int print_command_info (grub_command_t cmd);
auto int print_command_help (grub_command_t cmd);
{
if (cnt++ > 0)
grub_printf ("\n\n");
-
+
if (cmd->flags & GRUB_COMMAND_FLAG_EXTCMD)
grub_arg_show_help ((grub_extcmd_t) cmd->data);
else
}
return 0;
}
-
+
if (argc == 0)
grub_command_iterate (print_command_info);
else
{
int i;
-
+
for (i = 0; i < argc; i++)
{
currarg = args[i];
grub_command_iterate (print_command_help);
}
}
-
+
return 0;
}
int ebda_len;
grub_uint8_t *ebda, *ptr;
- grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
ebda_len = * (grub_uint16_t *) ebda;
if (! ebda_len)
&& ((struct grub_acpi_rsdp_v10 *) ptr)->revision == 0)
return (struct grub_acpi_rsdp_v10 *) ptr;
- grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
ptr += 16)
if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
int ebda_len;
grub_uint8_t *ebda, *ptr;
- grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n");
ebda = (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4);
ebda_len = * (grub_uint16_t *) ebda;
if (! ebda_len)
== 0)
return (struct grub_acpi_rsdp_v20 *) ptr;
- grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
+ grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n");
for (ptr = (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000;
ptr += 16)
if (grub_memcmp (ptr, "RSD PTR ", 8) == 0
{
grub_printf ("%cD #%-3u (0x%02x) %cd%d\n",
(curnode->newdrive & 0x80) ? 'H' : 'F',
- curnode->newdrive & 0x7F, curnode->newdrive,
+ curnode->newdrive & 0x7F, curnode->newdrive,
(curnode->redirto & 0x80) ? 'h' : 'f',
curnode->redirto & 0x7F
);
sizeof (struct note)) == sizeof (struct note)
&& buf.pitch != T_FINE && grub_checkkey () < 0)
{
-
+
grub_dprintf ("play", "pitch = %d, duration = %d\n", buf.pitch,
buf.duration);
p = video_mode_list = real2pm (controller_info.video_mode_ptr);
while (*p++ != 0xFFFF)
;
-
+
video_mode_list_size = (grub_addr_t) p - (grub_addr_t) video_mode_list;
saved_video_mode_list = grub_malloc (video_mode_list_size);
if (! saved_video_mode_list)
return grub_errno;
grub_memcpy (saved_video_mode_list, video_mode_list, video_mode_list_size);
-
+
grub_printf ("List of compatible video modes:\n");
grub_printf ("Legend: P=Packed pixel, D=Direct color, "
"mask/pos=R/G/B/reserved\n");
{
const char *memory_model = 0;
grub_uint32_t mode = (grub_uint32_t) *p;
-
+
err = grub_vbe_get_video_mode_info (mode, &mode_info_tmp);
if (err != GRUB_ERR_NONE)
{
if (! memory_model)
continue;
- grub_printf ("0x%03x: %4d x %4d x %2d %s",
+ grub_printf ("0x%03x: %4d x %4d x %2d %s",
mode,
mode_info_tmp.x_resolution,
mode_info_tmp.y_resolution,
}
grub_free (saved_video_mode_list);
-
+
/* Check existence of vbe_mode environment variable. */
modevar = grub_env_get ("vbe_mode");
grub_printf ("Old video mode = %04x\n", old_mode);
else
grub_errno = GRUB_ERR_NONE;
-
+
/* Check existence of vbe_mode environment variable. */
modevar = grub_env_get ("vbe_mode");
if (modevar != 0)
err = grub_vbe_get_video_mode_info (use_mode, &mode_info);
if (err != GRUB_ERR_NONE)
return err;
-
+
/* Dump out details about the mode being tested. */
grub_printf ("mode: 0x%03x\n",
use_mode);
filename = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG));
if (! filename)
return 0;
-
+
grub_strcpy (filename, prefix);
filename[len] = '/';
grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG);
buf = grub_malloc (size);
if (! buf)
return 0;
-
+
while (size > 0)
{
grub_ssize_t ret;
grub_env_set (name, value);
return 0;
}
-
+
file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
if (! file)
return grub_errno;
grub_envblk_iterate (envblk, set_var);
grub_envblk_close (envblk);
-
+
fail:
grub_file_close (file);
return grub_errno;
grub_printf ("%s=%s\n", name, value);
return 0;
}
-
+
file = open_envblk_file ((state[0].set) ? state[0].arg : 0);
if (! file)
return grub_errno;
grub_envblk_iterate (envblk, print_var);
grub_envblk_close (envblk);
-
+
fail:
grub_file_close (file);
return grub_errno;
grub_disk_addr_t part_start;
struct blocklist *p;
char *buf;
-
+
/* Sanity checks. */
total_length = 0;
for (p = blocklists; p; p = p->next)
return 0;
}
}
-
+
total_length += p->length;
}
-
+
if (total_length != grub_file_size (file))
{
/* Maybe sparse, unallocated sectors. No way in GRUB. */
for (p = blocklists, index = 0; p; p = p->next, index += p->length)
{
char blockbuf[GRUB_DISK_SECTOR_SIZE];
-
+
if (grub_disk_read (disk, p->sector - part_start,
p->offset, p->length, blockbuf))
return 0;
grub_disk_addr_t part_start;
struct blocklist *p;
grub_size_t index;
-
+
buf = grub_envblk_buffer (envblk);
disk = file->device->disk;
if (disk->partition)
grub_envblk_t envblk;
struct blocklist *head = 0;
struct blocklist *tail = 0;
-
+
/* Store blocklists in a linked list. */
auto void NESTED_FUNC_ATTR read_hook (grub_disk_addr_t sector,
unsigned offset,
if (offset + length > GRUB_DISK_SECTOR_SIZE)
/* Seemingly a bug. */
return;
-
+
block = grub_malloc (sizeof (*block));
if (! block)
return;
if (! check_blocklists (envblk, head, file))
goto fail;
-
+
while (argc)
{
char *value;
}
write_blocklists (envblk, head, file);
-
+
fail:
if (envblk)
grub_envblk_close (envblk);
grub_normal_print_device_info (name);
else
grub_printf ("(%s) ", name);
-
+
return 0;
}
-
+
grub_device_iterate (grub_ls_print_devices);
grub_putchar ('\n');
grub_refresh ();
const char *path;
grub_device_t dev;
- auto int print_files (const char *filename,
+ auto int print_files (const char *filename,
const struct grub_dirhook_info *info);
- auto int print_files_long (const char *filename,
+ auto int print_files_long (const char *filename,
const struct grub_dirhook_info *info);
-
+
int print_files (const char *filename, const struct grub_dirhook_info *info)
{
if (all || filename[0] != '.')
grub_printf ("%s%s ", filename, info->dir ? "/" : "");
-
+
return 0;
}
-
- int print_files_long (const char *filename,
+
+ int print_files_long (const char *filename,
const struct grub_dirhook_info *info)
{
char pathname[grub_strlen (dirname) + grub_strlen (filename) + 1];
if (! info->dir)
{
grub_file_t file;
-
+
if (dirname[grub_strlen (dirname) - 1] == '/')
grub_sprintf (pathname, "%s%s", dirname, filename);
else
int fsz = file->size;
int units = 0;
char buf[20];
-
+
while (fsz / 1024)
{
fsize = (fsize + 512) / 1024;
}
else
grub_printf ("%-12llu", (unsigned long long) file->size);
-
+
}
grub_file_close (file);
}
if (human)
grub_printf (" %d-%02d-%02d %02d:%02d:%02d %-11s ",
datetime.year, datetime.month, datetime.day,
- datetime.hour, datetime.minute,
+ datetime.hour, datetime.minute,
datetime.second,
grub_get_weekday_name (&datetime));
else
grub_printf (" %04d%02d%02d%02d%02d%02d ",
- datetime.year, datetime.month,
- datetime.day, datetime.hour,
+ datetime.year, datetime.month,
+ datetime.day, datetime.hour,
datetime.minute, datetime.second);
}
grub_printf ("%s%s\n", filename, info->dir ? "/" : "");
path = dirname;
else
path++;
-
+
if (! path && ! device_name)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid argument");
goto fail;
}
-
+
if (! *path)
{
if (grub_errno == GRUB_ERR_UNKNOWN_FS)
grub_file_t file;
struct grub_dirhook_info info;
grub_errno = 0;
-
+
file = grub_file_open (dirname);
if (! file)
goto fail;
-
+
grub_file_close (file);
-
+
p = grub_strrchr (dirname, '/') + 1;
dirname = grub_strndup (dirname, p - dirname);
if (! dirname)
if (grub_errno == GRUB_ERR_NONE)
grub_putchar ('\n');
-
+
grub_refresh ();
}
fail:
if (dev)
grub_device_close (dev);
-
+
grub_free (device_name);
return 0;
"Use \"parttool PARTITION help\" for the list "
"of available commands";
-int
-grub_parttool_register(const char *part_name,
+int
+grub_parttool_register(const char *part_name,
const grub_parttool_function_t func,
const struct grub_parttool_argdesc *args)
{
cur->handle = curhandle++;
for (nargs = 0; args[nargs].name != 0; nargs++);
cur->nargs = nargs;
- cur->args = (struct grub_parttool_argdesc *)
+ cur->args = (struct grub_parttool_argdesc *)
grub_malloc ((nargs + 1) * sizeof (struct grub_parttool_argdesc));
- grub_memcpy (cur->args, args,
+ grub_memcpy (cur->args, args,
(nargs + 1) * sizeof (struct grub_parttool_argdesc));
-
+
cur->func = func;
parts = cur;
return cur->handle;
for (curarg = cur->args; curarg->name; curarg++)
{
int spacing = 20;
-
+
spacing -= grub_strlen (curarg->name);
grub_printf ("%s", curarg->name);
-
+
switch (curarg->type)
{
case GRUB_PARTTOOL_ARG_BOOL:
grub_printf ("+/-");
spacing -= 3;
break;
-
- case GRUB_PARTTOOL_ARG_VAL:
+
+ case GRUB_PARTTOOL_ARG_VAL:
grub_printf ("=VAL");
spacing -= 4;
break;
-
+
case GRUB_PARTTOOL_ARG_END:
break;
}
}
}
if (! found)
- grub_printf ("Sorry no parttool is available for %s\n",
+ grub_printf ("Sorry no parttool is available for %s\n",
dev->disk->partition->partmap->name);
return GRUB_ERR_NONE;
}
if (args[0][0] == '(' && args[0][grub_strlen (args[0]) - 1] == ')')
{
args[0][grub_strlen (args[0]) - 1] = 0;
- dev = grub_device_open (args[0] + 1);
+ dev = grub_device_open (args[0] + 1);
args[0][grub_strlen (args[0]) - 1] = ')';
}
else
- dev = grub_device_open (args[0]);
+ dev = grub_device_open (args[0]);
if (! dev)
return grub_errno;
if (filename)
{
grub_file_t file;
-
+
grub_sprintf (filename, "%s/parttool.lst", prefix);
file = grub_file_open (filename);
if (file)
char *p, *name;
buf = grub_file_getline (file);
-
+
if (! buf)
break;
-
+
name = buf;
if (! grub_isgraph (name[0]))
continue;
-
+
p = grub_strchr (name, ':');
if (! p)
continue;
-
+
*p = '\0';
while (*++p == ' ')
;
if (! grub_isgraph (*p))
continue;
-
+
if (grub_strcmp (name, dev->disk->partition->partmap->name)
!= 0)
continue;
-
+
grub_dl_load (p);
}
-
+
grub_file_close (file);
}
-
+
grub_free (filename);
}
}
if (grub_strcmp (dev->disk->partition->partmap->name, cur->name) == 0)
{
for (curarg = cur->args; curarg->name; curarg++)
- if (grub_strncmp (curarg->name, args[i],
+ if (grub_strncmp (curarg->name, args[i],
grub_strlen (curarg->name)) == 0
- && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
- && (args[i][grub_strlen (curarg->name)] == '+'
+ && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+ && (args[i][grub_strlen (curarg->name)] == '+'
|| args[i][grub_strlen (curarg->name)] == '-'
|| args[i][grub_strlen (curarg->name)] == 0))
|| (curarg->type == GRUB_PARTTOOL_ARG_VAL
&& args[i][grub_strlen (curarg->name)] == '=')))
-
+
break;
if (curarg->name)
break;
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unrecognised argument %s",
args[i]);
ptool = cur;
- pargs = (struct grub_parttool_args *)
+ pargs = (struct grub_parttool_args *)
grub_malloc (ptool->nargs * sizeof (struct grub_parttool_args));
- grub_memset (pargs, 0,
+ grub_memset (pargs, 0,
ptool->nargs * sizeof (struct grub_parttool_args));
for (j = i; j < argc; j++)
if (! parsed[j])
{
for (curarg = ptool->args; curarg->name; curarg++)
- if (grub_strncmp (curarg->name, args[i],
+ if (grub_strncmp (curarg->name, args[i],
grub_strlen (curarg->name)) == 0
- && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
- && (args[j][grub_strlen (curarg->name)] == '+'
+ && ((curarg->type == GRUB_PARTTOOL_ARG_BOOL
+ && (args[j][grub_strlen (curarg->name)] == '+'
|| args[j][grub_strlen (curarg->name)] == '-'
|| args[j][grub_strlen (curarg->name)] == 0))
|| (curarg->type == GRUB_PARTTOOL_ARG_VAL
switch (curarg->type)
{
case GRUB_PARTTOOL_ARG_BOOL:
- pargs[curarg - ptool->args].bool
+ pargs[curarg - ptool->args].bool
= (args[j][grub_strlen (curarg->name)] != '-');
break;
case GRUB_PARTTOOL_ARG_VAL:
- pargs[curarg - ptool->args].str
+ pargs[curarg - ptool->args].str
= (args[j] + grub_strlen (curarg->name) + 1);
break;
-
+
case GRUB_PARTTOOL_ARG_END:
break;
}
GRUB_MOD_INIT(parttool)
{
mymod = mod;
- cmd = grub_register_command ("parttool", grub_cmd_parttool,
- "parttool PARTITION COMMANDS",
+ cmd = grub_register_command ("parttool", grub_cmd_parttool,
+ "parttool PARTITION COMMANDS",
helpmsg);
}
{
int count = 0;
auto int iterate_device (const char *name);
-
+
int iterate_device (const char *name)
{
grub_device_t dev;
name[0] == 'f' && name[1] == 'd' &&
name[2] >= '0' && name[2] <= '9')
return 0;
-
+
dev = grub_device_open (name);
if (dev)
{
grub_fs_t fs;
-
+
fs = grub_fs_probe (dev);
#define QUID(x) (is_uuid ? (x)->uuid : (x)->label)
if (fs && QUID(fs))
{
char *quid;
-
+
(QUID(fs)) (dev, &quid);
if (grub_errno == GRUB_ERR_NONE && quid)
{
else
grub_printf (" %s", name);
}
-
+
grub_free (quid);
}
}
-
+
grub_device_close (dev);
}
-
+
grub_errno = GRUB_ERR_NONE;
return abort;
}
-
+
grub_device_iterate (iterate_device);
-
+
if (count == 0)
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key);
}
char *p;
grub_file_t file;
int abort = 0;
-
+
/* Skip floppy drives when requested. */
if (no_floppy &&
name[0] == 'f' && name[1] == 'd' &&
name[2] >= '0' && name[2] <= '9')
return 0;
-
+
len = grub_strlen (name) + 2 + grub_strlen (key) + 1;
p = grub_realloc (buf, len);
if (! p)
buf = p;
grub_sprintf (buf, "(%s)%s", name, key);
-
+
file = grub_file_open (buf);
if (file)
{
grub_file_close (file);
}
-
+
grub_errno = GRUB_ERR_NONE;
return abort;
}
-
+
grub_device_iterate (iterate_device);
-
+
grub_free (buf);
-
+
if (grub_errno == GRUB_ERR_NONE && count == 0)
grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device");
}
{
struct grub_arg_list *state = cmd->state;
const char *var = 0;
-
+
if (argc == 0)
return grub_error (GRUB_ERR_INVALID_COMMAND, "no argument specified");
if (state[3].set)
var = state[3].arg ? state[3].arg : "root";
-
+
if (state[1].set)
search_fs (args[0], var, state[4].set, 0);
else if (state[2].set)
grub_device_t dev;
/* A hook for iterating directories. */
- auto int find_file (const char *cur_filename,
+ auto int find_file (const char *cur_filename,
const struct grub_dirhook_info *info);
- int find_file (const char *cur_filename,
+ int find_file (const char *cur_filename,
const struct grub_dirhook_info *info)
{
if ((info->case_insensitive ? grub_strcasecmp (cur_filename, filename)
}
return 0;
}
-
+
file_exists = 0;
device_name = grub_file_get_device_name (path);
dev = grub_device_open (device_name);
pathname = path;
else
pathname++;
-
+
/* Remove trailing '/'. */
while (*pathname && pathname[grub_strlen (pathname) - 1] == '/')
pathname[grub_strlen (pathname) - 1] = 0;
else
(fs->dir) (dev, path, find_file);
- grub_device_close (dev);
+ grub_device_close (dev);
grub_free (path);
grub_free (device_name);
}
(*argn) += 3;
continue;
}
-
+
/* GRUB extension: lexicographical sorting. */
if (grub_strcmp (args[*argn + 1], "<") == 0)
{
(*argn) += 3;
continue;
}
-
+
if (grub_strcmp (args[*argn + 1], "<=") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) <= 0);
(*argn) += 3;
continue;
}
-
+
if (grub_strcmp (args[*argn + 1], ">") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) > 0);
(*argn) += 3;
continue;
}
-
+
if (grub_strcmp (args[*argn + 1], ">=") == 0)
{
update_val (grub_strcmp (args[*argn], args[*argn + 2]) >= 0);
/* Number tests. */
if (grub_strcmp (args[*argn + 1], "-eq") == 0)
{
- update_val (grub_strtosl (args[*argn], 0, 0)
+ update_val (grub_strtosl (args[*argn], 0, 0)
== grub_strtosl (args[*argn + 2], 0, 0));
(*argn) += 3;
continue;
if (grub_strcmp (args[*argn + 1], "-ge") == 0)
{
- update_val (grub_strtosl (args[*argn], 0, 0)
+ update_val (grub_strtosl (args[*argn], 0, 0)
>= grub_strtosl (args[*argn + 2], 0, 0));
(*argn) += 3;
continue;
}
-
+
if (grub_strcmp (args[*argn + 1], "-gt") == 0)
{
- update_val (grub_strtosl (args[*argn], 0, 0)
+ update_val (grub_strtosl (args[*argn], 0, 0)
> grub_strtosl (args[*argn + 2], 0, 0));
(*argn) += 3;
continue;
if (grub_strcmp (args[*argn + 1], "-le") == 0)
{
- update_val (grub_strtosl (args[*argn], 0, 0)
+ update_val (grub_strtosl (args[*argn], 0, 0)
<= grub_strtosl (args[*argn + 2], 0, 0));
(*argn) += 3;
continue;
}
-
+
if (grub_strcmp (args[*argn + 1], "-lt") == 0)
{
- update_val (grub_strtosl (args[*argn], 0, 0)
+ update_val (grub_strtosl (args[*argn], 0, 0)
< grub_strtosl (args[*argn + 2], 0, 0));
(*argn) += 3;
continue;
}
-
+
if (grub_strcmp (args[*argn + 1], "-ne") == 0)
{
- update_val (grub_strtosl (args[*argn], 0, 0)
+ update_val (grub_strtosl (args[*argn], 0, 0)
!= grub_strtosl (args[*argn + 2], 0, 0));
(*argn) += 3;
continue;
}
- /* GRUB extension: compare numbers skipping prefixes.
+ /* GRUB extension: compare numbers skipping prefixes.
Useful for comparing versions. E.g. vmlinuz-2 -plt vmlinuz-11. */
if (grub_strcmp (args[*argn + 1], "-pgt") == 0
|| grub_strcmp (args[*argn + 1], "-plt") == 0)
{
int i;
/* Skip common prefix. */
- for (i = 0; args[*argn][i] == args[*argn + 2][i]
+ for (i = 0; args[*argn][i] == args[*argn + 2][i]
&& args[*argn][i]; i++);
-
+
/* Go the digits back. */
i--;
while (grub_isdigit (args[*argn][i]) && i > 0)
i--;
i++;
-
+
if (grub_strcmp (args[*argn + 1], "-pgt") == 0)
- update_val (grub_strtoul (args[*argn] + i, 0, 0)
+ update_val (grub_strtoul (args[*argn] + i, 0, 0)
> grub_strtoul (args[*argn + 2] + i, 0, 0));
else
- update_val (grub_strtoul (args[*argn] + i, 0, 0)
+ update_val (grub_strtoul (args[*argn] + i, 0, 0)
< grub_strtoul (args[*argn + 2] + i, 0, 0));
(*argn) += 3;
continue;
}
- /* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
+ /* -nt and -ot tests. GRUB extension: when doing -?t<bias> bias
will be added to the first mtime. */
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0
|| grub_memcmp (args[*argn + 1], "-ot", 3) == 0)
struct grub_dirhook_info file1;
int file1exists;
int bias = 0;
-
+
/* Fetch fileinfo. */
get_fileinfo (args[*argn]);
file1 = file_info;
file1exists = file_exists;
get_fileinfo (args[*argn + 2]);
-
+
if (args[*argn + 1][3])
bias = grub_strtosl (args[*argn + 1] + 3, 0, 0);
-
+
if (grub_memcmp (args[*argn + 1], "-nt", 3) == 0)
update_val ((file1exists && ! file_exists)
|| (file1.mtimeset && file_info.mtimeset
(*argn) += 2;
return ret;
}
-
+
if (grub_strcmp (args[*argn], "-e") == 0)
{
get_fileinfo (args[*argn + 1]);
(*argn) += 2;
return ret;
}
-
+
if (grub_strcmp (args[*argn], "-s") == 0)
{
grub_file_t file;
(*argn) += 2;
return ret;
}
-
+
/* String tests. */
if (grub_strcmp (args[*argn], "-n") == 0)
{
update_val (args[*argn + 1][0]);
-
+
(*argn) += 2;
continue;
}
}
/* Special modifiers. */
-
+
/* End of expression. return to parent. */
if (grub_strcmp (args[*argn], ")") == 0)
{
update_val (test_parse (args, argn, argc));
continue;
}
-
+
if (grub_strcmp (args[*argn], "!") == 0)
{
invert = ! invert;
if (argc >= 1 && grub_strcmp (args[argc - 1], "]") == 0)
argc--;
- return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
+ return test_parse (args, &argn, argc) ? GRUB_ERR_NONE
: grub_error (GRUB_ERR_TEST_FAILURE, "false");
}
"Interrupt"
};
-static const char *usb_devspeed[] =
+static const char *usb_devspeed[] =
{
"",
"Low",
usb_print_str ("Product", dev, descdev->strprod);
usb_print_str ("Vendor", dev, descdev->strvendor);
usb_print_str ("Serial", dev, descdev->strserial);
-
+
if (descdev->class > 0 && descdev->class <= 0x0E)
grub_printf ("Class: (0x%02x) %s, Subclass: 0x%02x, Protocol: 0x%02x\n",
descdev->class, usb_classes[descdev->class],
commands/parttool.c parttool/pcpart.c \
grub_emu_init.c
-grub_emu_LDFLAGS = $(LIBCURSES)
+grub_emu_LDFLAGS = $(LIBCURSES)
ifeq ($(enable_grub_emu_usb), yes)
grub_emu_SOURCES += disk/usbms.c util/usb.c bus/usb/usb.c \
ifeq ($(enable_grub_emu), yes)
sbin_UTILITIES += grub-emu
endif
-
+
# For grub-mkdevicemap.
grub_mkdevicemap_SOURCES = util/grub-mkdevicemap.c util/deviceiter.c \
util/devicemap.c util/misc.c
loader/multiboot2.c \
loader/multiboot_loader.c
multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
-multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
+multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For memdisk.mod.
memdisk_mod_SOURCES = disk/memdisk.c
# For grub-mkimage.
grub_mkimage_SOURCES = util/sparc64/ieee1275/grub-mkimage.c util/misc.c \
- util/resolve.c
+ util/resolve.c
# For grub-setup.
util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
])
if test "x$grub_cv_cc_mcmodel" = xno; then
CFLAGS="$SAVED_CFLAGS -m64 -DMCMODEL_SMALL=1"
- TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1"
+ TARGET_CFLAGS="$TARGET_CFLAGS -DMCMODEL_SMALL=1"
AC_MSG_WARN([-mcmodel=large not supported. You wan't be able to use the memory over 4GiB. Upgrade your gcc])
else
TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
#
# Memory manager debugging.
-AC_ARG_ENABLE([mm-debug],
+AC_ARG_ENABLE([mm-debug],
AS_HELP_STRING([--enable-mm-debug],
[include memory manager debugging]),
[AC_DEFINE([MM_DEBUG], [1],
/* Try to detect if the port is in use by writing to it,
waiting for a while and reading it again. If the value
was preserved, there is a device connected. */
- grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
+ grub_ata_regset (dev, GRUB_ATA_REG_SECTORS, 0x5A);
grub_ata_wait ();
grub_uint8_t sec = grub_ata_regget (dev, GRUB_ATA_REG_SECTORS);
grub_dprintf ("ata", "sectors=0x%x\n", sec);
bar2 = grub_pci_read (addr);
/* Check if the BARs describe an IO region. */
- if ((bar1 & 1) && (bar2 & 1))
+ if ((bar1 & 1) && (bar2 & 1))
{
rega = bar1 & ~3;
regb = bar2 & ~3;
disk->total_sectors = dev->size;
disk->id = (unsigned long) dev;
-
+
disk->has_partitions = 1;
disk->data = dev;
static void
grub_ata_close (grub_disk_t disk __attribute__((unused)))
{
-
+
}
static grub_err_t
.close = grub_atapi_close,
.read = grub_atapi_read,
.write = grub_atapi_write
- };
+ };
\f
grub_disk_firmware_fini ();
grub_disk_firmware_fini = NULL;
}
-
+
/* ATA initialization. */
grub_ata_initialize ();
{
grub_efi_device_path_t *p;
grub_size_t total_size = 0;
-
+
for (p = (grub_efi_device_path_t *) dp;
;
p = GRUB_EFI_NEXT_DEVICE_PATH (p))
if (! dp1 || ! dp2)
/* Return non-zero. */
return 1;
-
+
while (1)
{
grub_efi_uint8_t type1, type2;
grub_efi_uint8_t subtype1, subtype2;
grub_efi_uint16_t len1, len2;
int ret;
-
+
type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
-
+
if (subtype1 != subtype2)
return (int) subtype1 - (int) subtype2;
grub_efi_handle_t *handles;
grub_efi_handle_t *handle;
struct grub_efidisk_data *devices = 0;
-
+
/* Find handles which support the disk io interface. */
handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &disk_io_guid,
0, &num_handles);
struct grub_efidisk_data *d;
grub_efi_block_io_t *bio;
grub_efi_disk_io_t *dio;
-
+
dp = grub_efi_get_device_path (*handle);
if (! dp)
continue;
if (! ldp)
/* This is empty. Why? */
continue;
-
+
bio = grub_efi_open_protocol (*handle, &block_io_guid,
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
dio = grub_efi_open_protocol (*handle, &disk_io_guid,
if (! bio || ! dio)
/* This should not happen... Why? */
continue;
-
+
d = grub_malloc (sizeof (*d));
if (! d)
{
}
grub_free (handles);
-
+
return devices;
}
{
grub_efi_device_path_t *dp, *ldp;
struct grub_efidisk_data *parent;
-
+
dp = duplicate_device_path (d->device_path);
if (! dp)
return 0;
/* Ignore itself. */
if (parent == d)
continue;
-
+
if (compare_device_paths (parent->device_path, dp) == 0)
{
/* Found. */
if (! parent->last_device_path)
parent = 0;
-
+
break;
}
}
int (*hook) (struct grub_efidisk_data *child))
{
struct grub_efidisk_data *p;
-
+
for (p = devices; p; p = p->next)
{
grub_efi_device_path_t *dp, *ldp;
dp = duplicate_device_path (p->device_path);
if (! dp)
return 0;
-
+
ldp = find_last_device_path (dp);
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
ldp->length[0] = sizeof (*ldp);
ldp->length[1] = 0;
-
+
if (compare_device_paths (dp, d->device_path) == 0)
if (hook (p))
{
name_devices (struct grub_efidisk_data *devices)
{
struct grub_efidisk_data *d;
-
+
/* First, identify devices by media device paths. */
for (d = devices; d; d = d->next)
{
dp = d->last_device_path;
if (! dp)
continue;
-
+
if (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
{
int is_hard_drive = 0;
-
+
switch (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp))
{
case GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE:
#endif
add_device (&cd_devices, parent);
}
-
+
/* Mark the parent as used. */
parent->last_device_path = 0;
}
{
grub_efi_device_path_t *dp;
grub_efi_block_io_media_t *m;
-
+
dp = d->last_device_path;
if (! dp)
continue;
free_devices (struct grub_efidisk_data *devices)
{
struct grub_efidisk_data *p, *q;
-
+
for (p = devices; p; p = q)
{
q = p->next;
enumerate_disks (void)
{
struct grub_efidisk_data *devices;
-
+
devices = make_devices ();
if (! devices)
return;
-
+
name_devices (devices);
free_devices (devices);
}
struct grub_efidisk_data *d;
char buf[16];
int count;
-
+
for (d = fd_devices, count = 0; d; d = d->next, count++)
{
grub_sprintf (buf, "fd%d", count);
if (hook (buf))
return 1;
}
-
+
for (d = hd_devices, count = 0; d; d = d->next, count++)
{
grub_sprintf (buf, "hd%d", count);
if (hook (buf))
return 1;
}
-
+
for (d = cd_devices, count = 0; d; d = d->next, count++)
{
grub_sprintf (buf, "cd%d", count);
grub_efi_block_io_media_t *m;
grub_dprintf ("efidisk", "opening %s\n", name);
-
+
num = get_drive_number (name);
if (num < 0)
return grub_errno;
grub_efi_disk_io_t *dio;
grub_efi_block_io_t *bio;
grub_efi_status_t status;
-
+
d = disk->data;
dio = d->disk_io;
bio = d->block_io;
grub_dprintf ("efidisk",
"reading 0x%lx sectors at the sector 0x%llx from %s\n",
(unsigned long) size, (unsigned long long) sector, disk->name);
-
+
status = efi_call_5 (dio->read, dio, bio->media->media_id,
(grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
(grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
buf);
if (status != GRUB_EFI_SUCCESS)
return grub_error (GRUB_ERR_READ_ERROR, "efidisk read error");
-
+
return GRUB_ERR_NONE;
}
grub_efi_disk_io_t *dio;
grub_efi_block_io_t *bio;
grub_efi_status_t status;
-
+
d = disk->data;
dio = d->disk_io;
bio = d->block_io;
-
+
grub_dprintf ("efidisk",
"writing 0x%lx sectors at the sector 0x%llx to %s\n",
(unsigned long) size, (unsigned long long) sector, disk->name);
-
+
status = efi_call_5 (dio->write, dio, bio->media->media_id,
(grub_efi_uint64_t) sector << GRUB_DISK_SECTOR_BITS,
(grub_efi_uintn_t) size << GRUB_DISK_SECTOR_BITS,
(void *) buf);
if (status != GRUB_EFI_SUCCESS)
return grub_error (GRUB_ERR_WRITE_ERROR, "efidisk write error");
-
+
return GRUB_ERR_NONE;
}
{
struct grub_efidisk_data *d;
char type;
-
+
if (disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID)
return 0;
-
+
d = disk->data;
type = disk->name[0];
-
+
switch (type)
{
case 'f':
grub_efi_hard_drive_device_path_t hd;
grub_memcpy (&hd, c->last_device_path, sizeof (hd));
-
+
if ((GRUB_EFI_DEVICE_PATH_TYPE (c->last_device_path)
== GRUB_EFI_MEDIA_DEVICE_PATH_TYPE)
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (c->last_device_path)
handle = c->handle;
return 1;
}
-
+
return 0;
}
-
+
devices = make_devices ();
iterate_child_devices (devices, d, find_partition);
free_devices (devices);
-
+
if (handle != 0)
return handle;
}
default:
break;
}
-
+
return 0;
}
if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
{
struct grub_efidisk_data *d;
-
+
d = disk->data;
if (compare_device_paths (d->device_path, dup_dp) == 0)
{
/* Find a partition which matches the hard drive device path. */
grub_memcpy (&hd, ldp, sizeof (hd));
grub_partition_iterate (parent, find_partition);
-
+
if (! partition_name)
{
grub_disk_close (parent);
/* This should be an entire disk. */
auto int find_disk (const char *name);
char *device_name = 0;
-
+
int find_disk (const char *name)
{
grub_disk_t disk;
-
+
disk = grub_disk_open (name);
if (! disk)
return 1;
if (disk->id == GRUB_DISK_DEVICE_EFIDISK_ID)
{
struct grub_efidisk_data *d;
-
+
d = disk->data;
if (compare_device_paths (d->device_path, dp) == 0)
{
grub_disk_close (disk);
return 0;
-
+
}
-
+
grub_efidisk_iterate (find_disk);
return device_name;
}
if (dev)
{
grub_fs_t fs;
-
+
fs = grub_fs_probe (dev);
if (fs && fs->uuid)
{
char *uuid;
-
+
(fs->uuid) (dev, &uuid);
if (grub_errno == GRUB_ERR_NONE && uuid)
{
grub_free (uuid);
}
}
-
+
grub_device_close (dev);
}
grub_errno = GRUB_ERR_NONE;
return 0;
}
-
+
grub_device_iterate (iterate_device);
-
+
return ret;
}
disk->total_sectors = 0;
disk->id = (unsigned long) "host";
-
+
disk->has_partitions = 0;
disk->data = 0;
if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd')
goto fail;
-
+
drive = grub_strtoul (name + 2, 0, 10);
if (grub_errno != GRUB_ERR_NONE)
goto fail;
if (name[0] == 'h')
drive += 0x80;
-
+
return (int) drive ;
fail:
grub_dprintf ("disk", "Read error when probing drive 0x%2x\n", drive);
break;
}
-
+
if (grub_biosdisk_call_hook (hook, drive))
return 1;
}
disk->has_partitions = ((drive & 0x80) && (drive != cd_drive));
disk->id = drive;
-
+
data = (struct grub_biosdisk_data *) grub_malloc (sizeof (*data));
if (! data)
return grub_errno;
-
+
data->drive = drive;
data->flags = 0;
{
/* HDD */
int version;
-
+
version = grub_biosdisk_check_int13_extensions (drive);
if (version)
{
{
data->sectors = 63;
data->heads = 255;
- data->cylinders
- = grub_divmod64 (total_sectors
- + data->heads * data->sectors - 1,
+ data->cylinders
+ = grub_divmod64 (total_sectors
+ + data->heads * data->sectors - 1,
data->heads * data->sectors, 0);
}
else
disk->total_sectors = total_sectors;
disk->data = data;
-
+
return GRUB_ERR_NONE;
}
unsigned segment)
{
struct grub_biosdisk_data *data = disk->data;
-
+
if (data->flags & GRUB_BIOSDISK_FLAG_LBA)
{
struct grub_biosdisk_dap *dap;
-
+
dap = (struct grub_biosdisk_dap *) (GRUB_MEMORY_MACHINE_SCRATCH_ADDR
+ (data->sectors
<< GRUB_DISK_SECTOR_BITS));
{
unsigned coff, hoff, soff;
unsigned head;
-
+
/* It is impossible to reach over 8064 MiB (a bit less than LBA24) with
the traditional CHS access. */
if (sector >
if (actual != actual)
return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %llu",
(long long) sector);
-
+
return 0;
}
struct grub_loopback *next;
};
-static struct grub_loopback *loopback_list;
+static struct grub_loopback *loopback_list;
static const struct grub_arg_option options[] =
{
prev = &dev->next, dev = dev->next)
if (grub_strcmp (dev->devname, name) == 0)
break;
-
+
if (! dev)
return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found");
-
+
/* Remove the device from the list. */
*prev = dev->next;
grub_free (dev->devname);
grub_free (dev->filename);
grub_free (dev);
-
+
return 0;
}
struct grub_arg_list *state = state = cmd->state;
grub_file_t file;
struct grub_loopback *newdev;
-
+
if (argc < 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
-
+
/* Check if `-d' was used. */
if (state[0].set)
return delete_loopback (args[0]);
-
+
if (argc < 2)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
file = grub_file_open (args[1]);
if (! file)
return grub_errno;
-
+
/* Close the file, the only reason for opening it is validation. */
grub_file_close (file);
-
+
/* First try to replace the old device. */
for (newdev = loopback_list; newdev; newdev = newdev->next)
if (grub_strcmp (newdev->devname, args[0]) == 0)
break;
-
+
if (newdev)
{
char *newname = grub_strdup (args[1]);
if (! newname)
return grub_errno;
-
+
grub_free (newdev->filename);
newdev->filename = newname;
-
+
/* Set has_partitions when `--partitions' was used. */
newdev->has_partitions = state[1].set;
-
+
return 0;
}
-
+
/* Unable to replace it, make a new entry. */
newdev = grub_malloc (sizeof (struct grub_loopback));
if (! newdev)
return grub_errno;
-
+
newdev->devname = grub_strdup (args[0]);
if (! newdev->devname)
{
grub_free (newdev);
return grub_errno;
}
-
+
newdev->filename = grub_strdup (args[1]);
if (! newdev->filename)
{
grub_free (newdev);
return grub_errno;
}
-
+
/* Set has_partitions when `--partitions' was used. */
newdev->has_partitions = state[1].set;
-
+
/* Add the new entry to the list. */
newdev->next = loopback_list;
loopback_list = newdev;
-
+
return 0;
}
{
grub_file_t file;
struct grub_loopback *dev;
-
+
for (dev = loopback_list; dev; dev = dev->next)
if (grub_strcmp (dev->devname, name) == 0)
break;
-
+
if (! dev)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "Can't open device");
file = grub_file_open (dev->filename);
if (! file)
return grub_errno;
-
+
/* Use the filesize for the disk size, round up to a complete sector. */
disk->total_sectors = ((file->size + GRUB_DISK_SECTOR_SIZE - 1)
/ GRUB_DISK_SECTOR_SIZE);
disk->id = (unsigned long) dev;
-
+
disk->has_partitions = dev->has_partitions;
disk->data = file;
-
+
return 0;
}
grub_loopback_close (grub_disk_t disk)
{
grub_file_t file = (grub_file_t) disk->data;
-
+
grub_file_close (file);
}
{
grub_file_t file = (grub_file_t) disk->data;
grub_off_t pos;
-
+
grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS);
-
+
grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS);
if (grub_errno)
return grub_errno;
-
+
/* In case there is more data read than there is available, in case
of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill
the rest with zeros. */
grub_size_t amount = pos - file->size;
grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount);
}
-
+
return 0;
}
disk->id = lv->number;
disk->data = lv;
disk->total_sectors = lv->size;
-
+
return 0;
}
stripe += stripenr;
pv = stripe->pv;
-
+
seg_offset = ((grub_uint64_t) stripe->start
* (grub_uint64_t) vg->extent_size) + pv->start;
else
err = grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"Physical volume %s not found", pv->name);
-
+
return err;
}
unsigned int i, j, vgname_len;
struct grub_lvm_vg *vg;
struct grub_lvm_pv *pv;
-
+
disk = grub_disk_open (name);
if (!disk)
return 0;
err = grub_disk_read (disk, i, 0, sizeof(buf), buf);
if (err)
goto fail;
-
+
if ((! grub_strncmp ((char *)lh->id, GRUB_LVM_LABEL_ID,
sizeof (lh->id)))
&& (! grub_strncmp ((char *)lh->type, GRUB_LVM_LVM2_LABEL,
/* Return if we didn't find a label. */
if (i == GRUB_LVM_LABEL_SCAN_SECTORS)
goto fail;
-
+
pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"We don't support multiple LVM data areas");
-
+
goto fail;
}
mda_offset = grub_le_to_cpu64 (dlocn->offset);
mda_size = grub_le_to_cpu64 (dlocn->size);
dlocn++;
-
+
if (dlocn->offset)
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"We don't support multiple LVM metadata areas");
-
+
goto fail;
}
if (p)
{
p += sizeof ("physical_volumes {") - 1;
-
+
/* Add all the pvs to the volume group. */
while (1)
{
int s;
while (grub_isspace (*p))
p++;
-
+
if (*p == '}')
break;
-
+
pv = grub_malloc (sizeof (*pv));
q = p;
while (*q != ' ')
q++;
-
+
s = q - p;
pv->name = grub_malloc (s + 1);
grub_memcpy (pv->name, p, s);
pv->name[s] = '\0';
-
+
p = grub_strstr (p, "id = \"");
if (p == NULL)
goto pvs_fail;
p += sizeof("id = \"") - 1;
-
+
grub_memcpy (pv->id, p, GRUB_LVM_ID_STRLEN);
pv->id[GRUB_LVM_ID_STRLEN] = '\0';
-
+
pv->start = grub_lvm_getvalue (&p, "pe_start = ");
if (p == NULL)
goto pvs_fail;
-
+
p = grub_strchr (p, '}');
if (p == NULL)
goto pvs_fail;
pv->disk = NULL;
pv->next = vg->pvs;
vg->pvs = pv;
-
+
continue;
pvs_fail:
grub_free (pv->name);
if (p)
{
p += 18;
-
+
/* And add all the lvs to the volume group. */
while (1)
{
int s;
struct grub_lvm_lv *lv;
struct grub_lvm_segment *seg;
-
+
while (grub_isspace (*p))
p++;
-
+
if (*p == '}')
break;
-
+
lv = grub_malloc (sizeof (*lv));
-
+
q = p;
while (*q != ' ')
q++;
-
+
s = q - p;
lv->name = grub_malloc (vgname_len + 1 + s + 1);
grub_memcpy (lv->name, vgname, vgname_len);
lv->name[vgname_len] = '-';
grub_memcpy (lv->name + vgname_len + 1, p, s);
lv->name[vgname_len + 1 + s] = '\0';
-
+
lv->size = 0;
-
+
lv->segment_count = grub_lvm_getvalue (&p, "segment_count = ");
if (p == NULL)
goto lvs_fail;
lv->segments = grub_malloc (sizeof (*seg) * lv->segment_count);
seg = lv->segments;
-
+
for (i = 0; i < lv->segment_count; i++)
{
struct grub_lvm_stripe *stripe;
-
+
p = grub_strstr (p, "segment");
if (p == NULL)
goto lvs_segment_fail;
-
+
seg->start_extent = grub_lvm_getvalue (&p, "start_extent = ");
if (p == NULL)
goto lvs_segment_fail;
seg->stripe_count = grub_lvm_getvalue (&p, "stripe_count = ");
if (p == NULL)
goto lvs_segment_fail;
-
+
lv->size += seg->extent_count * vg->extent_size;
-
+
if (seg->stripe_count != 1)
seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
-
+
seg->stripes = grub_malloc (sizeof (*stripe)
* seg->stripe_count);
stripe = seg->stripes;
-
+
p = grub_strstr (p, "stripes = [");
if (p == NULL)
goto lvs_segment_fail2;
p += sizeof("stripes = [") - 1;
-
+
for (j = 0; j < seg->stripe_count; j++)
{
char *pvname;
-
+
p = grub_strchr (p, '"');
if (p == NULL)
continue;
q++;
s = q - p;
-
+
pvname = grub_malloc (s + 1);
if (pvname == NULL)
goto lvs_segment_fail2;
-
+
grub_memcpy (pvname, p, s);
pvname[s] = '\0';
-
+
if (vg->pvs)
for (pv = vg->pvs; pv; pv = pv->next)
{
break;
}
}
-
+
grub_free(pvname);
-
+
stripe->start = grub_lvm_getvalue (&p, ",");
if (p == NULL)
continue;
-
+
stripe++;
}
-
+
seg++;
continue;
if (p == NULL)
goto lvs_fail;
p += 3;
-
+
lv->number = lv_count++;
lv->vg = vg;
lv->next = vg->lvs;
return 0;
}
-
+
grub_module_iterate (hook);
}
grub_raid_iterate (int (*hook) (const char *name))
{
struct grub_raid_array *array;
-
+
for (array = array_list; array != NULL; array = array->next)
{
if (grub_is_array_readable (array))
struct grub_raid_array *array = disk->data;
grub_disk_memberlist_t list = NULL, tmp;
unsigned int i;
-
+
for (i = 0; i < array->total_devs; i++)
if (array->device[i])
{
tmp->next = list;
list = tmp;
}
-
+
return list;
}
#endif
{
struct grub_raid_array *array;
unsigned n;
-
+
for (array = array_list; array != NULL; array = array->next)
{
if (!grub_strcmp (array->name, name))
grub_dprintf ("raid", "%s: level=%d, total_sectors=%lld\n", name,
array->level, (unsigned long long) disk->total_sectors);
-
+
return 0;
}
p = array->total_devs - n;
read_sector *= array->chunk_size;
-
+
while (1)
{
grub_size_t read_size;
if (err)
break;
}
-
+
buf += read_size << GRUB_DISK_SECTOR_BITS;
size -= read_size;
if (! size)
}
break;
}
-
+
return err;
}
const char *scanner_name)
{
struct grub_raid_array *array = 0, *p;
-
+
/* See whether the device is part of an array we have already seen a
device from. */
for (p = array_list; p != NULL; p = p->next)
*array = *new_array;
array->nr_devs = 0;
grub_memset (&array->device, 0, sizeof (array->device));
-
+
/* Check whether we don't have multiple arrays with the same number. */
for (p = array_list; p != NULL; p = p->next)
{
return 0;
}
-
+
grub_device_iterate (&hook);
}
{
struct grub_raid_array *p;
int i;
-
+
p = array;
array = array->next;
array_list = 0;
}
-
+
void
grub_raid_register (grub_raid_t raid)
{
<< GRUB_DISK_SECTOR_BITS);
grub_dprintf ("scsi", "capacity=%llu, blksize=%d\n",
- (unsigned long long) disk->total_sectors,
+ (unsigned long long) disk->total_sectors,
scsi->blocksize);
return GRUB_ERR_NONE;
"can't read from USB Mass Storage device");
}
}
- else
+ else
{
err = grub_usb_bulk_write (dev->dev, dev->in->endp_addr & 15, size, buf);
grub_dprintf ("usb", "write: %d %d\n", err, GRUB_USB_ERR_STALL);
.close = grub_usbms_close,
.read = grub_usbms_read,
.write = grub_usbms_write
- };
+ };
GRUB_MOD_INIT(usbms)
{
which can cause compatibility problems.
For booting from a CD-ROM, GRUB uses a special Stage 2 called
-@file{stage2_eltorito}. The only GRUB files you need to have in your
+@file{stage2_eltorito}. The only GRUB files you need to have in your
bootable CD-ROM are this @file{stage2_eltorito} and optionally a config file
@file{menu.lst}. You don't need to use @file{stage1} or @file{stage2},
because El Torito is quite different from the standard boot process.
This produces a file named @file{grub.iso}, which then can be burned
into a CD (or a DVD). @kbd{mkisofs} has already set up the disc to boot
-from the @kbd{boot/grub/stage2_eltorito} file, so there is no need to
+from the @kbd{boot/grub/stage2_eltorito} file, so there is no need to
setup GRUB on the disc. (Note that the @kbd{-boot-load-size 4} bit is
required for compatibility with the BIOS on many older machines.)
You can use the device @samp{(cd)} to access a CD-ROM in your
-config file. This is not required; GRUB automatically sets the root device
-to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to
+config file. This is not required; GRUB automatically sets the root device
+to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to
@samp{(cd)} if you want to access other drives as well.
be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data
bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd},
@samp{even} and defaults to @samp{no}. The option @option{--device}
-can only be used in the grub shell and is used to specify the
+can only be used in the grub shell and is used to specify the
tty device to be used in the host operating system (@pxref{Invoking the
grub shell}).
@deffn Command setkey [to_key from_key]
Change the keyboard map. The key @var{from_key} is mapped to the key
-@var{to_key}. If no argument is specified, reset key mappings. Note that
-this command @emph{does not} exchange the keys. If you want to exchange
+@var{to_key}. If no argument is specified, reset key mappings. Note that
+this command @emph{does not} exchange the keys. If you want to exchange
the keys, run this command again with the arguments exchanged, like this:
@example
% We don't want .vr (or whatever) entries like this:
% \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
% "\acronym" won't work when it's read back in;
- % it needs to be
+ % it needs to be
% {\code {{\tt \backslashcurfont }acronym}
\shipout\vbox{%
% Do this early so pdf references go to the beginning of the page.
\def\?{?\spacefactor=\endofsentencespacefactor\space}
% @frenchspacing on|off says whether to put extra space after punctuation.
-%
+%
\def\onword{on}
\def\offword{off}
%
% that's what we do).
% double active backslashes.
-%
+%
{\catcode`\@=0 \catcode`\\=\active
@gdef@activebackslashdouble{%
@catcode`@\=@active
% us) handles it with this amazing macro to replace tokens, with minor
% changes for Texinfo. It is included here under the GPL by permission
% from the author, Heiko Oberdiek.
-%
+%
% #1 is the tokens to replace.
% #2 is the replacement.
% #3 is the control sequence with the string.
-%
+%
\def\HyPsdSubst#1#2#3{%
\def\HyPsdReplace##1#1##2\END{%
##1%
% tried to figure out what each command should do in the context
% of @url. for now, just make @/ a no-op, that's the only one
% people have actually reported a problem with.
- %
+ %
\normalturnoffactive
\def\@{@}%
\let\/=\empty
% Definitions for a main text size of 11pt. This is the default in
% Texinfo.
-%
+%
\def\definetextfontsizexi{%
% Text fonts (11.2pt, magstep1).
\def\textnominalsize{11pt}
% section, chapter, etc., sizes following suit. This is for the GNU
% Press printing of the Emacs 22 manual. Maybe other manuals in the
% future. Used with @smallbook, which sets the leading to 12pt.
-%
+%
\def\definetextfontsizex{%
% Text fonts (10pt).
\def\textnominalsize{10pt}
\setfont\secsf\sfbshape{12}{1000}{OT1}
\let\secbf\secrm
\setfont\secsc\scbshape{10}{\magstep1}{OT1}
-\font\seci=cmmi12
+\font\seci=cmmi12
\font\secsy=cmsy10 scaled \magstep1
\def\sececsize{1200}
% We provide the user-level command
% @fonttextsize 10
% (or 11) to redefine the text font size. pt is assumed.
-%
+%
\def\xword{10}
\def\xiword{11}
%
%
% Set \globaldefs so that documents can use this inside @tex, since
% makeinfo 4.8 does not support it, but we need it nonetheless.
- %
+ %
\begingroup \globaldefs=1
\ifx\textsizearg\xword \definetextfontsizex
\else \ifx\textsizearg\xiword \definetextfontsizexi
% each of the four underscores in __typeof__. This is undesirable in
% some manuals, especially if they don't have long identifiers in
% general. @allowcodebreaks provides a way to control this.
-%
+%
\newif\ifallowcodebreaks \allowcodebreakstrue
\def\keywordtrue{true}
% @acronym for "FBI", "NATO", and the like.
% We print this one point size smaller, since it's intended for
% all-uppercase.
-%
+%
\def\acronym#1{\doacronym #1,,\finish}
\def\doacronym#1,#2,#3\finish{%
{\selectfonts\lsize #1}%
% @abbr for "Comput. J." and the like.
% No font change, but don't do end-of-sentence spacing.
-%
+%
\def\abbr#1{\doabbr #1,,\finish}
\def\doabbr#1,#2,#3\finish{%
{\plainfrenchspacing #1}%
% Theiling, which support regular, slanted, bold and bold slanted (and
% "outlined" (blackboard board, sort of) versions, which we don't need).
% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
-%
+%
% Although only regular is the truly official Euro symbol, we ignore
% that. The Euro is designed to be slightly taller than the regular
% font height.
-%
+%
% feymr - regular
% feymo - slanted
% feybr - bold
% feybo - bold slanted
-%
+%
% There is no good (free) typewriter version, to my knowledge.
% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
% Hmm.
-%
+%
% Also doesn't work in math. Do we need to do math with euro symbols?
% Hope not.
-%
-%
+%
+%
\def\euro{{\eurofont e}}
\def\eurofont{%
% We set the font at each command, rather than predefining it in
% \textfonts and the other font-switching commands, so that
% installations which never need the symbol don't have to have the
% font installed.
- %
+ %
% There is only one designed size (nominal 10pt), so we always scale
% that to the current nominal size.
- %
+ %
% By the way, simply using "at 1em" works for cmr10 and the like, but
% does not work for cmbx10 and other extended/shrunken fonts.
- %
+ %
\def\eurosize{\csname\curfontsize nominalsize\endcsname}%
%
- \ifx\curfontstyle\bfstylename
+ \ifx\curfontstyle\bfstylename
% bold:
\font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
- \else
+ \else
% regular:
\font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
\fi
% Laurent Siebenmann reports \Orb undefined with:
% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
% so we'll define it if necessary.
-%
+%
\ifx\Orb\undefined
\def\Orb{\mathhexbox20D}
\fi
% cause the example and the item to crash together. So we use this
% bizarre value of 10001 as a signal to \aboveenvbreak to insert
% \parskip glue after all. Section titles are handled this way also.
- %
+ %
\penalty 10001
\endgroup
\itemxneedsnegativevskipfalse
% processing continues to some further point. On the other hand, it
% seems \endinput does not hurt in the printed index arg, since that
% is still getting written without apparent harm.
- %
+ %
% Sample source (mac-idx3.tex, reported by Graham Percival to
% help-texinfo, 22may06):
% @macro funindex {WORD}
% @end macro
% ...
% @funindex commtest
- %
+ %
% The above is not enough to reproduce the bug, but it gives the flavor.
- %
+ %
% Sample whatsit resulting:
% .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
- %
+ %
% So:
\let\endinput = \empty
%
% makeinfo does not expand macros in the argument to @deffn, which ends up
% writing an index entry, and texindex isn't prepared for an index sort entry
% that starts with \.
- %
+ %
% Since macro invocations are followed by braces, we can just redefine them
% to take a single TeX argument. The case of a macro invocation that
% goes to end-of-line is not handled.
- %
+ %
\macrolist
}
% to re-insert the same penalty (values >10000 are used for various
% signals); since we just inserted a non-discardable item, any
% following glue (such as a \parskip) would be a breakpoint. For example:
- %
+ %
% @deffn deffn-whatever
% @vindex index-whatever
% Description.
% glue accumulate. (Not a breakpoint because it's preceded by a
% discardable item.)
\vskip-\parskip
- %
+ %
% This is purely so the last item on the list is a known \penalty >
% 10000. This is so \startdefun can avoid allowing breakpoints after
% section headings. Otherwise, it would insert a valid breakpoint between:
- %
+ %
% @section sec-whatever
% @deffn def-whatever
\penalty 10001
% These characters do not print properly in the Computer Modern roman
% fonts, so we must take special care. This is more or less redundant
% with the Texinfo input format setup at the end of this file.
-%
+%
\def\activecatcodes{%
\catcode`\"=\active
\catcode`\$=\active
% redefined for the two-volume lispref. We always output on
% \jobname.toc even if this is redefined.
-%
+%
\def\tocreadfilename{\jobname.toc}
% Normal (long) toc.
% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it
% the default, but it works for pasting with more pdf viewers (at least
% evince), the lilypond developers report. xpdf does work with the
-% regular 0x27.
-%
+% regular 0x27.
+%
\def\codequoteright{%
\expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax
\expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
% and a similar option for the left quote char vs. a grave accent.
% Modern fonts display ASCII 0x60 as a grave accent, so some people like
% the code environments to do likewise.
-%
+%
\def\codequoteleft{%
\expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax
\expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
% This does \let #1 = #2, with \csnames; that is,
% \let \csname#1\endcsname = \csname#2\endcsname
% (except of course we have to play expansion games).
-%
+%
\def\cslet#1#2{%
\expandafter\let
\csname#1\expandafter\endcsname
%
% If they passed de_DE, and txi-de_DE.tex doesn't exist,
% try txi-de.tex.
-%
+%
\def\documentlanguagetrywithoutunderscore#1_#2\finish{%
\openin 1 txi-#1.tex
\ifeof 1
\setnonasciicharscatcode\active
\lattwochardefs
%
- \else \ifx \declaredencoding \latone
+ \else \ifx \declaredencoding \latone
\setnonasciicharscatcode\active
\latonechardefs
%
\setnonasciicharscatcode\active
\utfeightchardefs
%
- \else
+ \else
\message{Unknown document encoding #1, ignoring.}%
%
\fi % utfeight
% A message to be logged when using a character that isn't available
% the default font encoding (OT1).
-%
+%
\def\missingcharmsg#1{\message{Character missing in OT1 encoding: #1.}}
% Take account of \c (plain) vs. \, (Texinfo) difference.
%
% Latin1 (ISO-8859-1) character definitions.
\def\latonechardefs{%
- \gdef^^a0{~}
+ \gdef^^a0{~}
\gdef^^a1{\exclamdown}
- \gdef^^a2{\missingcharmsg{CENT SIGN}}
+ \gdef^^a2{\missingcharmsg{CENT SIGN}}
\gdef^^a3{{\pounds}}
\gdef^^a4{\missingcharmsg{CURRENCY SIGN}}
\gdef^^a5{\missingcharmsg{YEN SIGN}}
- \gdef^^a6{\missingcharmsg{BROKEN BAR}}
+ \gdef^^a6{\missingcharmsg{BROKEN BAR}}
\gdef^^a7{\S}
- \gdef^^a8{\"{}}
- \gdef^^a9{\copyright}
+ \gdef^^a8{\"{}}
+ \gdef^^a9{\copyright}
\gdef^^aa{\ordf}
- \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
+ \gdef^^ab{\missingcharmsg{LEFT-POINTING DOUBLE ANGLE QUOTATION MARK}}
\gdef^^ac{$\lnot$}
- \gdef^^ad{\-}
- \gdef^^ae{\registeredsymbol}
+ \gdef^^ad{\-}
+ \gdef^^ae{\registeredsymbol}
\gdef^^af{\={}}
%
\gdef^^b0{\textdegree}
\gdef^^c2{\^A}
\gdef^^c3{\~A}
\gdef^^c4{\"A}
- \gdef^^c5{\ringaccent A}
+ \gdef^^c5{\ringaccent A}
\gdef^^c6{\AE}
\gdef^^c7{\cedilla C}
\gdef^^c8{\`E}
\gdef^^d6{\"O}
\gdef^^d7{$\times$}
\gdef^^d8{\v R}
- \gdef^^d9{\ringaccent U}
+ \gdef^^d9{\ringaccent U}
\gdef^^da{\'U}
\gdef^^db{\H U}
\gdef^^dc{\"U}
}
% UTF-8 character definitions.
-%
+%
% This code to support UTF-8 is based on LaTeX's utf8.def, with some
% changes for Texinfo conventions. It is included here under the GPL by
% permission from Frank Mittelbach and the LaTeX team.
-%
+%
\newcount\countUTFx
\newcount\countUTFy
\newcount\countUTFz
% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
% the literal character `\'.
-%
+%
@def@normalturnoffactive{%
@let\=@normalbackslash
@let"=@normaldoublequote
/* Relocate symbols. */
grub_err_t
-grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
+grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
struct grub_efiemu_elf_sym *elfsyms,
void *ehdr)
{
if (seg)
{
Elf32_Rel *rel, *max;
-
+
for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
-
- addr = (Elf32_Word *)
- ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+
+ addr = (Elf32_Word *)
+ ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+ seg->off + rel->r_offset);
sym = elfsyms[ELF32_R_SYM (rel->r_info)];
-
+
switch (ELF32_R_TYPE (rel->r_info))
{
case R_386_32:
- if ((err = grub_efiemu_write_value
- (addr, sym.off + *addr, sym.handle, 0,
+ if ((err = grub_efiemu_write_value
+ (addr, sym.off + *addr, sym.handle, 0,
seg->ptv_rel_needed, sizeof (grub_uint32_t))))
return err;
-
+
break;
case R_386_PC32:
if ((err = grub_efiemu_write_value
- (addr, sym.off + *addr - rel->r_offset
- - seg->off, sym.handle, seg->handle,
+ (addr, sym.off + *addr - rel->r_offset
+ - seg->off, sym.handle, seg->handle,
seg->ptv_rel_needed, sizeof (grub_uint32_t))))
return err;
break;
default:
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"unrecognised relocation");
}
}
/* Relocate symbols. */
grub_err_t
-grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
+grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
struct grub_efiemu_elf_sym *elfsyms,
void *ehdr)
{
if (seg)
{
Elf64_Rela *rel, *max;
-
+
for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
- max = rel + (unsigned long) s->sh_size
+ max = rel + (unsigned long) s->sh_size
/ (unsigned long)s->sh_entsize;
rel < max;
rel++)
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
-
+
addr =
- ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+ ((char *) grub_efiemu_mm_obtain_request (seg->handle)
+ seg->off + rel->r_offset);
addr32 = (grub_uint32_t *) addr;
addr64 = (grub_uint64_t *) addr;
sym = elfsyms[ELF64_R_SYM (rel->r_info)];
-
+
switch (ELF64_R_TYPE (rel->r_info))
{
case R_X86_64_64:
- if ((err = grub_efiemu_write_value
- (addr, *addr64 + rel->r_addend + sym.off, sym.handle,
+ if ((err = grub_efiemu_write_value
+ (addr, *addr64 + rel->r_addend + sym.off, sym.handle,
0, seg->ptv_rel_needed, sizeof (grub_uint64_t))))
return err;
break;
case R_X86_64_PC32:
if ((err = grub_efiemu_write_value
- (addr, *addr32 + rel->r_addend + sym.off
- - rel->r_offset - seg->off, sym.handle, seg->handle,
+ (addr, *addr32 + rel->r_addend + sym.off
+ - rel->r_offset - seg->off, sym.handle, seg->handle,
seg->ptv_rel_needed, sizeof (grub_uint32_t))))
return err;
break;
case R_X86_64_32:
case R_X86_64_32S:
- if ((err = grub_efiemu_write_value
- (addr, *addr32 + rel->r_addend + sym.off, sym.handle,
+ if ((err = grub_efiemu_write_value
+ (addr, *addr32 + rel->r_addend + sym.off, sym.handle,
0, seg->ptv_rel_needed, sizeof (grub_uint32_t))))
return err;
break;
default:
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"unrecognised relocation");
}
}
return err;
}
- for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
+ for (ptr = (grub_uint8_t *) 0xf0000; ptr < (grub_uint8_t *) 0x100000;
ptr += 16)
if (grub_memcmp (ptr, "_SM_", 4) == 0
&& grub_byte_checksum (ptr, *(ptr + 5)) == 0)
if (seg->section == n)
{
*handle = seg->handle;
- *off = seg->off;
+ *off = seg->off;
return GRUB_ERR_NONE;
}
grub_efiemu_segment_t cur;
grub_dprintf ("efiemu", "loading segments\n");
-
+
for (cur=segs; cur; cur = cur->next)
{
s = (Elf_Shdr *)cur->srcptr;
if ((s->sh_flags & SHF_ALLOC) && s->sh_size)
{
void *addr;
-
- addr = (grub_uint8_t *) grub_efiemu_mm_obtain_request (cur->handle)
+
+ addr = (grub_uint8_t *) grub_efiemu_mm_obtain_request (cur->handle)
+ cur->off;
-
+
switch (s->sh_type)
{
case SHT_PROGBITS:
seg = (grub_efiemu_segment_t) grub_malloc (sizeof (*seg));
if (! seg)
return grub_errno;
-
+
if (s->sh_size)
{
- seg->handle
- = grub_efiemu_request_memalign
+ seg->handle
+ = grub_efiemu_request_memalign
(s->sh_addralign, s->sh_size,
s->sh_flags & SHF_EXECINSTR ? GRUB_EFI_RUNTIME_SERVICES_CODE
: GRUB_EFI_RUNTIME_SERVICES_DATA);
return grub_errno;
seg->off = 0;
}
-
- /*
+
+ /*
.text-physical doesn't need to be relocated when switching to
virtual mode
*/
- if (!grub_strcmp (grub_efiemu_get_string (s->sh_name, e),
+ if (!grub_strcmp (grub_efiemu_get_string (s->sh_name, e),
".text-physical"))
seg->ptv_rel_needed = 0;
else
*segs = seg;
}
}
-
+
return GRUB_ERR_NONE;
}
unsigned i;
Elf_Shdr *s;
int num = 0;
-
+
/* Symbols */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
return grub_error (GRUB_ERR_BAD_OS, "no symbol table");
grub_efiemu_nelfsyms = (unsigned) s->sh_size / (unsigned) s->sh_entsize;
- grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
+ grub_efiemu_elfsyms = (struct grub_efiemu_elf_sym *)
grub_malloc (sizeof (struct grub_efiemu_elf_sym) * grub_efiemu_nelfsyms);
/* Relocators */
Elf_Sym *sym;
const char *str;
Elf_Word size, entsize;
-
+
grub_dprintf ("efiemu", "resolving symbols\n");
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
break;
case STT_OBJECT:
- if ((err = grub_efiemu_get_section_addr
+ if ((err = grub_efiemu_get_section_addr
(segs, sym->st_shndx, &handle, &off)))
return err;
break;
case STT_FUNC:
- if ((err = grub_efiemu_get_section_addr
+ if ((err = grub_efiemu_get_section_addr
(segs, sym->st_shndx, &handle, &off)))
return err;
break;
case STT_SECTION:
- if ((err = grub_efiemu_get_section_addr
+ if ((err = grub_efiemu_get_section_addr
(segs, sym->st_shndx, &handle, &off)))
{
grub_efiemu_elfsyms[i].handle = 0;
grub_efiemu_elfsyms[i].off = 0;
- grub_errno = GRUB_ERR_NONE;
+ grub_errno = GRUB_ERR_NONE;
break;
}
/* Load runtime definitively */
grub_err_t
-SUFFIX (grub_efiemu_loadcore_load) (void *core,
- grub_size_t core_size
+SUFFIX (grub_efiemu_loadcore_load) (void *core,
+ grub_size_t core_size
__attribute__ ((unused)),
grub_efiemu_segment_t segments)
{
return err;
if ((err = grub_efiemu_resolve_symbols (segments, core)))
return err;
- if ((err = SUFFIX (grub_arch_efiemu_relocate_symbols) (segments,
+ if ((err = SUFFIX (grub_arch_efiemu_relocate_symbols) (segments,
grub_efiemu_elfsyms,
core)))
return err;
-
+
return GRUB_ERR_NONE;
}
/* Check the header and set mode */
static grub_err_t
-grub_efiemu_check_header (void *ehdr, grub_size_t size,
+grub_efiemu_check_header (void *ehdr, grub_size_t size,
grub_efiemu_mode_t *mode)
{
/* Check the magic numbers. */
case GRUB_EFIEMU64:
grub_efiemu_loadcore_unload64 ();
break;
-
+
default:
break;
}
return GRUB_ERR_NONE;
}
-/* Load runtime file and do some initial preparations */
+/* Load runtime file and do some initial preparations */
grub_err_t
grub_efiemu_loadcore_init (grub_file_t file)
{
if (! efiemu_core)
return grub_errno;
- if (grub_file_read (file, efiemu_core, efiemu_core_size)
+ if (grub_file_read (file, efiemu_core, efiemu_core_size)
!= (int) efiemu_core_size)
{
grub_free (efiemu_core);
return grub_errno;
}
- if (grub_efiemu_check_header (efiemu_core, efiemu_core_size,
+ if (grub_efiemu_check_header (efiemu_core, efiemu_core_size,
&grub_efiemu_mode))
{
grub_free (efiemu_core);
return err;
}
break;
-
+
default:
return grub_error (GRUB_ERR_BAD_OS, "unknown EFI runtime");
}
*/
/* This is an emulation of EFI runtime services.
- This allows a more uniform boot on i386 machines.
- As it emulates only runtime service it isn't able
+ This allows a more uniform boot on i386 machines.
+ As it emulates only runtime service it isn't able
to chainload EFI bootloader on non-EFI system. */
grub_err_t
grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
- void (*unload) (void *data),
+ void (*unload) (void *data),
void *data)
{
struct grub_efiemu_prepare_hook *nhook;
return GRUB_ERR_NONE;
}
-/* Register a configuration table either supplying the address directly
+/* Register a configuration table either supplying the address directly
or with a hook
*/
grub_err_t
-grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
void * (*get_table) (void *data),
- void (*unload) (void *data),
+ void (*unload) (void *data),
void *data)
{
struct grub_efiemu_configuration_table *tbl;
grub_err_t err;
-
+
if (! get_table && ! data)
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
"you must set at least get_table or data");
if ((err = grub_efiemu_unregister_configuration_table (guid)))
return err;
static grub_err_t
grub_cmd_efiemu_unload (grub_command_t cmd __attribute__ ((unused)),
- int argc __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
char *args[] __attribute__ ((unused)))
{
return grub_efiemu_unload ();
static grub_err_t
grub_cmd_efiemu_prepare (grub_command_t cmd __attribute__ ((unused)),
- int argc __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
char *args[] __attribute__ ((unused)))
{
return grub_efiemu_prepare ();
\f
-int
-grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
+int
+grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key
__attribute__ ((unused)))
{
/* Nothing to do here yet */
return 1;
}
-int
+int
grub_efiemu_finish_boot_services (void)
{
/* Nothing to do here yet */
{
grub_file_t file;
grub_err_t err;
-
+
file = grub_file_open (filename);
if (! file)
return 0;
-
+
err = grub_efiemu_mm_init ();
if (err)
{
return GRUB_ERR_NONE;
prefix = grub_env_get ("prefix");
-
+
if (! prefix)
- return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"couldn't find efiemu core because prefix "
"isn't set");
-
+
suffix = grub_efiemu_get_default_core_name ();
-
+
filename = grub_malloc (grub_strlen (prefix) + grub_strlen (suffix) + 2);
if (! filename)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate temporary space");
-
+
grub_sprintf (filename, "%s/%s", prefix, suffix);
err = grub_efiemu_load_file (filename);
{
grub_err_t err;
- grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n",
+ grub_dprintf ("efiemu", "Preparing %d-bit efiemu\n",
8 * grub_efiemu_sizeof_uintn_t ());
err = grub_efiemu_autocore ();
GRUB_MOD_INIT(efiemu)
{
- cmd_loadcore = grub_register_command ("efiemu_loadcore",
- grub_cmd_efiemu_load,
- "efiemu_loadcore FILE",
+ cmd_loadcore = grub_register_command ("efiemu_loadcore",
+ grub_cmd_efiemu_load,
+ "efiemu_loadcore FILE",
"Load and initialize EFI emulator");
- cmd_prepare = grub_register_command ("efiemu_prepare",
- grub_cmd_efiemu_prepare,
- "efiemu_prepare",
+ cmd_prepare = grub_register_command ("efiemu_prepare",
+ grub_cmd_efiemu_prepare,
+ "efiemu_prepare",
"Finalize loading of EFI emulator");
- cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
- "efiemu_unload",
+ cmd_unload = grub_register_command ("efiemu_unload", grub_cmd_efiemu_unload,
+ "efiemu_unload",
"Unload EFI emulator");
grub_efiemu_pnvram_cmd_register ();
}
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
/*
- To keep efiemu runtime contiguous this mm is special.
+ To keep efiemu runtime contiguous this mm is special.
It uses deferred allocation.
In the first stage you may request memory with grub_efiemu_request_memalign
- It will give you a handle with which in the second phase you can access your
+ It will give you a handle with which in the second phase you can access your
memory with grub_efiemu_mm_obtain_request (handle). It's guaranteed that
subsequent calls with the same handle return the same result. You can't request any additional memory once you're in the second phase
*/
#include <grub/machine/memory.h>
#include <grub/efiemu/efiemu.h>
-struct grub_efiemu_memrequest
+struct grub_efiemu_memrequest
{
struct grub_efiemu_memrequest *next;
grub_efi_memory_type_t type;
/* Add a memory region to map*/
static grub_err_t
-grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size,
+grub_efiemu_add_to_mmap (grub_uint64_t start, grub_uint64_t size,
grub_efi_memory_type_t type)
{
grub_uint64_t page_start, npages;
if (mmap_num >= mmap_reserved_size)
{
efiemu_mmap = (grub_efi_memory_descriptor_t *)
- grub_realloc (efiemu_mmap, (++mmap_reserved_size)
+ grub_realloc (efiemu_mmap, (++mmap_reserved_size)
* sizeof (grub_efi_memory_descriptor_t));
if (!efiemu_mmap)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Not enough space for memory map");
}
page_start = start - (start % GRUB_EFIEMU_PAGESIZE);
npages = (size + (start % GRUB_EFIEMU_PAGESIZE) + GRUB_EFIEMU_PAGESIZE - 1)
/ GRUB_EFIEMU_PAGESIZE;
- efiemu_mmap[mmap_num].physical_start = page_start;
- efiemu_mmap[mmap_num].virtual_start = page_start;
- efiemu_mmap[mmap_num].num_pages = npages;
+ efiemu_mmap[mmap_num].physical_start = page_start;
+ efiemu_mmap[mmap_num].virtual_start = page_start;
+ efiemu_mmap[mmap_num].num_pages = npages;
efiemu_mmap[mmap_num].type = type;
mmap_num++;
}
/* Request a resident memory of type TYPE of size SIZE aligned at ALIGN
- ALIGN must be a divisor of page size (if it's a divisor of 4096
+ ALIGN must be a divisor of page size (if it's a divisor of 4096
it should be ok on all platforms)
*/
int
-grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
grub_efi_memory_type_t type)
{
grub_size_t align_overhead;
ret->val = 0;
ret->next = 0;
prev = 0;
-
- /* Add request to the end of the chain.
+
+ /* Add request to the end of the chain.
It should be at the end because otherwise alignment isn't guaranteed */
for (cur = memrequests; cur; prev = cur, cur = cur->next);
if (prev)
GRUB_EFI_RUNTIME_SERVICES_CODE,
GRUB_EFI_RUNTIME_SERVICES_DATA,
GRUB_EFI_ACPI_MEMORY_NVS,
-
- /* And then unavailable memory types. This is more for a completeness.
+
+ /* And then unavailable memory types. This is more for a completeness.
You should double think before allocating memory of any of these types
*/
GRUB_EFI_UNUSABLE_MEMORY,
GRUB_EFI_MEMORY_MAPPED_IO,
GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE,
- GRUB_EFI_PAL_CODE
+ GRUB_EFI_PAL_CODE
};
/* Compute total memory needed */
for (i = 0; i < sizeof (reqorder) / sizeof (reqorder[0]); i++)
{
- align_overhead = GRUB_EFIEMU_PAGESIZE
+ align_overhead = GRUB_EFIEMU_PAGESIZE
- (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
if (align_overhead == GRUB_EFIEMU_PAGESIZE)
align_overhead = 0;
/* Allocate the whole memory in one block */
resident_memory = grub_memalign (GRUB_EFIEMU_PAGESIZE, total_alloc);
if (!resident_memory)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate resident memory");
/* Split the memory into blocks by type */
}
/* Ensure that the regions are page-aligned */
- align_overhead = GRUB_EFIEMU_PAGESIZE
+ align_overhead = GRUB_EFIEMU_PAGESIZE
- (requested_memory[reqorder[i]] % GRUB_EFIEMU_PAGESIZE);
if (align_overhead == GRUB_EFIEMU_PAGESIZE)
align_overhead = 0;
curptr = ((grub_uint8_t *)curptr) + align_overhead;
-
+
/* Add the region to memory map */
- grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart),
+ grub_efiemu_add_to_mmap (PTR_TO_UINT64 (typestart),
curptr - typestart, reqorder[i]);
}
static grub_err_t
grub_efiemu_mmap_init (void)
{
- auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
+ auto int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t, grub_uint64_t,
grub_uint32_t);
int NESTED_FUNC_ATTR bounds_hook (grub_uint64_t addr __attribute__ ((unused)),
grub_uint64_t size __attribute__ ((unused)),
{
if (!efiemu_mmap)
{
- grub_error (GRUB_ERR_INVALID_COMMAND,
+ grub_error (GRUB_ERR_INVALID_COMMAND,
"you need to first launch efiemu_prepare");
return -1;
}
switch (type)
{
case GRUB_MACHINE_MEMORY_AVAILABLE:
- return grub_efiemu_add_to_mmap (addr, size,
+ return grub_efiemu_add_to_mmap (addr, size,
GRUB_EFI_CONVENTIONAL_MEMORY);
#ifdef GRUB_MACHINE_MEMORY_ACPI
case GRUB_MACHINE_MEMORY_ACPI:
- return grub_efiemu_add_to_mmap (addr, size,
+ return grub_efiemu_add_to_mmap (addr, size,
GRUB_EFI_ACPI_RECLAIM_MEMORY);
#endif
#ifdef GRUB_MACHINE_MEMORY_NVS
case GRUB_MACHINE_MEMORY_NVS:
- return grub_efiemu_add_to_mmap (addr, size,
+ return grub_efiemu_add_to_mmap (addr, size,
GRUB_EFI_ACPI_MEMORY_NVS);
#endif
default:
grub_printf ("Unknown memory type %d. Marking as unusable\n", type);
case GRUB_MACHINE_MEMORY_RESERVED:
- return grub_efiemu_add_to_mmap (addr, size,
- GRUB_EFI_UNUSABLE_MEMORY);
+ return grub_efiemu_add_to_mmap (addr, size,
+ GRUB_EFI_UNUSABLE_MEMORY);
}
}
}
grub_err_t
-grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
- grub_uint64_t,
+grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+ grub_uint64_t,
grub_uint32_t))
{
unsigned i;
switch (efiemu_mmap[i].type)
{
case GRUB_EFI_RUNTIME_SERVICES_CODE:
- hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+ hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_EFIEMU_MEMORY_CODE);
break;
-
+
case GRUB_EFI_RESERVED_MEMORY_TYPE:
case GRUB_EFI_RUNTIME_SERVICES_DATA:
case GRUB_EFI_UNUSABLE_MEMORY:
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
case GRUB_EFI_PAL_CODE:
case GRUB_EFI_MAX_MEMORY_TYPE:
- hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+ hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_EFIEMU_MEMORY_RESERVED);
break;
-
+
case GRUB_EFI_LOADER_CODE:
case GRUB_EFI_LOADER_DATA:
case GRUB_EFI_BOOT_SERVICES_CODE:
case GRUB_EFI_BOOT_SERVICES_DATA:
case GRUB_EFI_CONVENTIONAL_MEMORY:
- hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+ hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_EFIEMU_MEMORY_AVAILABLE);
break;
-
+
case GRUB_EFI_ACPI_RECLAIM_MEMORY:
- hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+ hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_EFIEMU_MEMORY_ACPI);
break;
-
+
case GRUB_EFI_ACPI_MEMORY_NVS:
- hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
+ hook (efiemu_mmap[i].physical_start, efiemu_mmap[i].num_pages * 4096,
GRUB_EFIEMU_MEMORY_NVS);
break;
}
-
+
return 0;
}
static grub_err_t
grub_efiemu_mmap_sort_and_uniq (void)
{
- /* If same page is used by multiple types it's resolved
- according to priority
+ /* If same page is used by multiple types it's resolved
+ according to priority
0 - free memory
1 - memory immediately usable after ExitBootServices
2 - memory usable after loading ACPI tables
/* Initialize variables*/
grub_memset (present, 0, sizeof (int) * GRUB_EFI_MAX_MEMORY_TYPE);
- scanline_events = (struct grub_efiemu_mmap_scan *)
+ scanline_events = (struct grub_efiemu_mmap_scan *)
grub_malloc (sizeof (struct grub_efiemu_mmap_scan) * 2 * mmap_num);
/* Number of chunks can't increase more than by factor of 2 */
- result = (grub_efi_memory_descriptor_t *)
+ result = (grub_efi_memory_descriptor_t *)
grub_malloc (sizeof (grub_efi_memory_descriptor_t) * 2 * mmap_num);
if (!result || !scanline_events)
{
grub_free (result);
grub_free (scanline_events);
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate space for new memory map");
}
-
+
/* Register scanline events */
for (i = 0; i < mmap_num; i++)
{
scanline_events[2 * i + 1].memtype = efiemu_mmap[i].type;
}
- /* Primitive bubble sort. It has complexity O(n^2) but since we're
- unlikely to have more than 100 chunks it's probably one of the
+ /* Primitive bubble sort. It has complexity O(n^2) but since we're
+ unlikely to have more than 100 chunks it's probably one of the
fastest for one purpose */
done = 1;
while (done)
curtype = k;
/* Add memory region to resulting map if necessary */
- if ((curtype == -1 || curtype != lasttype)
+ if ((curtype == -1 || curtype != lasttype)
&& lastaddr != scanline_events[i].pos
&& lasttype != -1)
{
result[j].virtual_start = result[j].physical_start = lastaddr;
- result[j].num_pages = (scanline_events[i].pos - lastaddr)
+ result[j].num_pages = (scanline_events[i].pos - lastaddr)
/ GRUB_EFIEMU_PAGESIZE;
result[j].type = lasttype;
/* We set runtime attribute on pages we need to be mapped */
- result[j].attribute
+ result[j].attribute
= (lasttype == GRUB_EFI_RUNTIME_SERVICES_CODE
|| lasttype == GRUB_EFI_RUNTIME_SERVICES_DATA)
? GRUB_EFI_MEMORY_RUNTIME : 0;
- grub_dprintf ("efiemu",
- "mmap entry: type %d start 0x%llx 0x%llx pages\n",
+ grub_dprintf ("efiemu",
+ "mmap entry: type %d start 0x%llx 0x%llx pages\n",
result[j].type,
result[j].physical_start, result[j].num_pages);
j++;
}
/* Update last values if necessary */
- if (curtype == -1 || curtype != lasttype)
+ if (curtype == -1 || curtype != lasttype)
{
lasttype = curtype;
lastaddr = scanline_events[i].pos;
grub_free (scanline_events);
- /* Shrink resulting memory map to really used size and replace efiemu_mmap
+ /* Shrink resulting memory map to really used size and replace efiemu_mmap
by new value */
grub_free (efiemu_mmap);
efiemu_mmap = grub_realloc (result, j * sizeof (*result));
grub_err_t err;
/* Preallocate mmap */
- efiemu_mmap = (grub_efi_memory_descriptor_t *)
+ efiemu_mmap = (grub_efi_memory_descriptor_t *)
grub_malloc (mmap_reserved_size * sizeof (grub_efi_memory_descriptor_t));
if (!efiemu_mmap)
{
if ((err = grub_efiemu_mmap_fill ()))
return err;
return grub_efiemu_mmap_sort_and_uniq ();
-}
+}
static const struct grub_arg_option options[] = {
{"size", 's', 0, "number of bytes to reserve for pseudo NVRAM", 0,
ARG_TYPE_INT},
- {"high-monotonic-count", 'm', 0,
+ {"high-monotonic-count", 'm', 0,
"Initial value of high monotonic count", 0, ARG_TYPE_INT},
- {"timezone", 't', 0,
+ {"timezone", 't', 0,
"Timezone, offset in minutes from GMT", 0, ARG_TYPE_INT},
- {"accuracy", 'a', 0,
+ {"accuracy", 'a', 0,
"Accuracy of clock, in 1e-12 units", 0, ARG_TYPE_INT},
- {"daylight", 'd', 0,
+ {"daylight", 'd', 0,
"Daylight value, as per EFI specifications", 0, ARG_TYPE_INT},
{0, 0, 0, 0, 0, 0}
};
/* Export stuff for efiemu */
static grub_err_t
nvram_set (void * data __attribute__ ((unused)))
-{
+{
/* Take definitive pointers */
grub_uint8_t *nvram_def = grub_efiemu_mm_obtain_request (nvram_handle);
- grub_uint32_t *nvramsize_def
+ grub_uint32_t *nvramsize_def
= grub_efiemu_mm_obtain_request (nvramsize_handle);
grub_uint32_t *high_monotonic_count_def
= grub_efiemu_mm_obtain_request (high_monotonic_count_handle);
- grub_int16_t *timezone_def
+ grub_int16_t *timezone_def
= grub_efiemu_mm_obtain_request (timezone_handle);
grub_uint8_t *daylight_def
= grub_efiemu_mm_obtain_request (daylight_handle);
/* Register symbols */
grub_efiemu_register_symbol ("efiemu_variables", nvram_handle, 0);
grub_efiemu_register_symbol ("efiemu_varsize", nvramsize_handle, 0);
- grub_efiemu_register_symbol ("efiemu_high_monotonic_count",
+ grub_efiemu_register_symbol ("efiemu_high_monotonic_count",
high_monotonic_count_handle, 0);
grub_efiemu_register_symbol ("efiemu_time_zone", timezone_handle, 0);
grub_efiemu_register_symbol ("efiemu_time_daylight", daylight_handle, 0);
- grub_efiemu_register_symbol ("efiemu_time_accuracy",
+ grub_efiemu_register_symbol ("efiemu_time_accuracy",
accuracy_handle, 0);
return GRUB_ERR_NONE;
struct efi_variable *efivar;
grub_size_t guidlen, datalen;
unsigned i, j;
-
+
file = grub_file_open (filename);
if (!file)
return grub_error (GRUB_ERR_BAD_OS, "couldn't read pnvram");
efivar = (struct efi_variable *) nvramptr;
if (nvramptr - nvram + sizeof (struct efi_variable) > nvramsize)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"file is too large for reserved variable space");
nvramptr += sizeof (struct efi_variable);
/* look ahow long guid field is*/
- guidlen = 0;
- for (ptr2 = ptr; (grub_isspace (*ptr2)
+ guidlen = 0;
+ for (ptr2 = ptr; (grub_isspace (*ptr2)
|| (*ptr2 >= '0' && *ptr2 <= '9')
|| (*ptr2 >= 'a' && *ptr2 <= 'f')
- || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+ || (*ptr2 >= 'A' && *ptr2 <= 'F'));
ptr2++)
if (!grub_isspace (*ptr2))
guidlen++;
/* Read guid */
if (guidlen != sizeof (efivar->guid))
- {
+ {
grub_free (buf);
return grub_error (GRUB_ERR_BAD_OS, "can't parse %s", filename);
}
hex = *ptr - 'a' + 10;
if (*ptr >= 'A' && *ptr <= 'F')
hex = *ptr - 'A' + 10;
-
+
if (i%2 == 0)
((grub_uint8_t *)&(efivar->guid))[i/2] = hex << 4;
else
((grub_uint8_t *)&(efivar->guid))[i/2] |= hex;
ptr++;
}
-
+
while (grub_isspace (*ptr))
ptr++;
if (*ptr != ':')
{
/* Look the length */
datalen = 0;
- for (ptr2 = ptr; *ptr2 && (grub_isspace (*ptr2)
+ for (ptr2 = ptr; *ptr2 && (grub_isspace (*ptr2)
|| (*ptr2 >= '0' && *ptr2 <= '9')
|| (*ptr2 >= 'a' && *ptr2 <= 'f')
- || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+ || (*ptr2 >= 'A' && *ptr2 <= 'F'));
ptr2++)
if (!grub_isspace (*ptr2))
datalen++;
datalen /= 2;
-
+
if (nvramptr - nvram + datalen > nvramsize)
{
grub_free (buf);
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"file is too large for reserved "
" variable space");
}
-
+
for (i = 0; i < 2 * datalen; i++)
{
int hex = 0;
hex = *ptr - 'a' + 10;
if (*ptr >= 'A' && *ptr <= 'F')
hex = *ptr - 'A' + 10;
-
+
if (i%2 == 0)
nvramptr[i/2] = hex << 4;
else
efivar->size = datalen;
else
efivar->namelen = datalen;
-
+
ptr++;
}
}
grub_free (nvram);
return err;
}
- nvram_handle
- = grub_efiemu_request_memalign (1, nvramsize,
+ nvram_handle
+ = grub_efiemu_request_memalign (1, nvramsize,
GRUB_EFI_RUNTIME_SERVICES_DATA);
- nvramsize_handle
- = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+ nvramsize_handle
+ = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
GRUB_EFI_RUNTIME_SERVICES_DATA);
high_monotonic_count_handle
- = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+ = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
GRUB_EFI_RUNTIME_SERVICES_DATA);
timezone_handle
- = grub_efiemu_request_memalign (1, sizeof (grub_uint16_t),
+ = grub_efiemu_request_memalign (1, sizeof (grub_uint16_t),
GRUB_EFI_RUNTIME_SERVICES_DATA);
daylight_handle
- = grub_efiemu_request_memalign (1, sizeof (grub_uint8_t),
+ = grub_efiemu_request_memalign (1, sizeof (grub_uint8_t),
GRUB_EFI_RUNTIME_SERVICES_DATA);
accuracy_handle
- = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
+ = grub_efiemu_request_memalign (1, sizeof (grub_uint32_t),
GRUB_EFI_RUNTIME_SERVICES_DATA);
grub_efiemu_request_symbols (6);
nvram = grub_malloc (nvramsize);
if (!nvram)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Couldn't allocate space for temporary pnvram storage");
grub_memset (nvram, 0, nvramsize);
nvramsize = state[0].set ? grub_strtoul (state[0].arg, 0, 0) : 2048;
high_monotonic_count = state[1].set ? grub_strtoul (state[1].arg, 0, 0) : 1;
- timezone = state[2].set ? grub_strtosl (state[2].arg, 0, 0)
+ timezone = state[2].set ? grub_strtosl (state[2].arg, 0, 0)
: GRUB_EFI_UNSPECIFIED_TIMEZONE;
accuracy = state[3].set ? grub_strtoul (state[3].arg, 0, 0) : 50000000;
daylight = state[4].set ? grub_strtoul (state[4].arg, 0, 0) : 0;
-
+
nvram = grub_malloc (nvramsize);
if (!nvram)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Couldn't allocate space for temporary pnvram storage");
- grub_memset (nvram, 0, nvramsize);
+ grub_memset (nvram, 0, nvramsize);
if (argc == 1 && (err = read_pnvram (args[0])))
{
void
grub_efiemu_pnvram_cmd_register (void)
{
- cmd = grub_register_extcmd ("efiemu_pnvram", grub_cmd_efiemu_pnvram,
+ cmd = grub_register_extcmd ("efiemu_pnvram", grub_cmd_efiemu_pnvram,
GRUB_COMMAND_FLAG_BOTH,
"efiemu_pnvram [FILENAME]",
"Initialise pseudo-NVRAM and load variables "
- "from FILE",
+ "from FILE",
options);
}
-/* Prepare efiemu. E.g. allocate memory, load the runtime
+/* Prepare efiemu. E.g. allocate memory, load the runtime
to appropriate place, etc */
/*
* GRUB -- GRand Unified Bootloader
grub_err_t
SUFFIX (grub_efiemu_prepare) (struct grub_efiemu_prepare_hook *prepare_hooks,
- struct grub_efiemu_configuration_table
+ struct grub_efiemu_configuration_table
*config_tables)
{
grub_err_t err;
/* Request space for the list of configuration tables */
for (cur = config_tables; cur; cur = cur->next)
cntconftables++;
- conftable_handle
- = grub_efiemu_request_memalign (GRUB_EFIEMU_PAGESIZE,
+ conftable_handle
+ = grub_efiemu_request_memalign (GRUB_EFIEMU_PAGESIZE,
cntconftables * sizeof (*conftables),
GRUB_EFI_RUNTIME_SERVICES_DATA);
return err;
}
- if ((err = grub_efiemu_resolve_symbol ("efiemu_system_table",
+ if ((err = grub_efiemu_resolve_symbol ("efiemu_system_table",
&handle, &off)))
{
grub_efiemu_unload ();
return err;
}
- SUFFIX (grub_efiemu_system_table)
- = (TYPE (grub_efi_system_table) *)
+ SUFFIX (grub_efiemu_system_table)
+ = (TYPE (grub_efi_system_table) *)
((grub_uint8_t *)grub_efiemu_mm_obtain_request (handle) + off);
/* compute CRC32 of runtime_services */
- if ((err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
+ if ((err = grub_efiemu_resolve_symbol ("efiemu_runtime_services",
&handle, &off)))
return err;
runtime_services = (TYPE (grub_efiemu_runtime_services) *)
((grub_uint8_t *)grub_efiemu_mm_obtain_request (handle) + off);
runtime_services->hdr.crc32 = 0;
- runtime_services->hdr.crc32 = grub_getcrc32
+ runtime_services->hdr.crc32 = grub_getcrc32
(0, runtime_services, runtime_services->hdr.header_size);
/* Put pointer to the list of configuration tables in system table */
grub_efiemu_write_value
- (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
- conftable_handle, 0, 1,
+ (&(SUFFIX (grub_efiemu_system_table)->configuration_table), 0,
+ conftable_handle, 0, 1,
sizeof (SUFFIX (grub_efiemu_system_table)->configuration_table));
SUFFIX(grub_efiemu_system_table)->num_table_entries = cntconftables;
i = 0;
for (cur = config_tables; cur; cur = cur->next, i++)
{
- grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
+ grub_memcpy (&(conftables[i].vendor_guid), &(cur->guid),
sizeof (cur->guid));
if (cur->get_table)
conftables[i].vendor_table
/* compute CRC32 of system table */
SUFFIX (grub_efiemu_system_table)->hdr.crc32 = 0;
- SUFFIX (grub_efiemu_system_table)->hdr.crc32
- = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table),
+ SUFFIX (grub_efiemu_system_table)->hdr.crc32
+ = grub_getcrc32 (0, SUFFIX (grub_efiemu_system_table),
SUFFIX (grub_efiemu_system_table)->hdr.header_size);
grub_dprintf ("efiemu","system_table = %p, runtime_services = %p,"
" conftables = %p (%d entries)\n",
- SUFFIX (grub_efiemu_system_table), runtime_services,
+ SUFFIX (grub_efiemu_system_table), runtime_services,
conftables, cntconftables);
return GRUB_ERR_NONE;
* %rcx, %rdx, %r8, %r9, 32(%rsp), 40(%rsp), 48(%rsp), ...
*
*/
-
+
.file "efiemu.S"
.text
-
+
FUNCTION (efiemu_get_time)
push %rdi
push %rsi
mov %rcx, %rdi
mov %rdx, %rsi
mov %r8, %rdx
- mov %r9, %rcx
+ mov %r9, %rcx
mov 56(%rsp), %r8
call efiemu_set_variable_real
pop %rsi
ret
/* The following functions are always called in physical mode */
- .section ".text-physical", "ax"
-
+ .section ".text-physical", "ax"
+
FUNCTION (efiemu_set_virtual_address_map)
push %rdi
push %rsi
*/
/* This is an emulation of EFI runtime services.
- This allows a more uniform boot on i386 machines.
- As it emulates only runtime serviceit isn't able
+ This allows a more uniform boot on i386 machines.
+ As it emulates only runtime serviceit isn't able
to chainload EFI bootloader on non-EFI system (TODO) */
#include <grub/symbol.h>
#include <grub/efi/api.h>
#include <grub/efiemu/runtime.h>
-grub_efi_status_t
+grub_efi_status_t
efiemu_get_time (grub_efi_time_t *time,
grub_efi_time_capabilities_t *capabilities);
grub_efi_status_t
PHYSICAL_ATTRIBUTE;
grub_efi_status_t
-efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
+efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
void **address)
PHYSICAL_ATTRIBUTE;
grub_efi_uintn_t data_size,
grub_efi_char16_t *reset_data);
-grub_efi_status_t
+grub_efi_status_t
EFI_FUNC (efiemu_set_virtual_address_map) (grub_efi_uintn_t,
grub_efi_uintn_t,
grub_efi_uint32_t,
grub_efi_memory_descriptor_t *)
PHYSICAL_ATTRIBUTE;
grub_efi_status_t
-EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
+EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
void **address)
PHYSICAL_ATTRIBUTE;
static grub_uint32_t
static void
init_crc32_table (void)
PHYSICAL_ATTRIBUTE;
-static grub_uint32_t
+static grub_uint32_t
reflect (grub_uint32_t ref, int len)
PHYSICAL_ATTRIBUTE;
-
+
/*
The log. It's used when examining memory dump
-*/
+*/
static grub_uint8_t loge[1000] = "EFIEMULOG";
-static int logn = 9;
+static int logn = 9;
#define LOG(x) { if (logn<900) loge[logn++]=x; }
static int ptv_relocated = 0;
return 0;
}
-/* The function that implement runtime services as specified in
+/* The function that implement runtime services as specified in
EFI specification */
static inline grub_uint8_t
bcd_to_hex (grub_uint8_t in)
return 10 * ((in & 0xf0) >> 4) + (in & 0x0f);
}
-grub_efi_status_t
+grub_efi_status_t
EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time,
grub_efi_time_capabilities_t *capabilities)
{
static grub_uint32_t crc32_table [256];
-static grub_uint32_t
+static grub_uint32_t
reflect (grub_uint32_t ref, int len)
{
grub_uint32_t result = 0;
int i;
-
+
for (i = 1; i <= len; i++)
{
if (ref & 1)
result |= 1 << (len - i);
ref >>= 1;
}
-
+
return result;
}
}
-grub_efi_status_t EFI_FUNC
+grub_efi_status_t EFI_FUNC
(efiemu_set_virtual_address_map) (grub_efi_uintn_t memory_map_size,
grub_efi_uintn_t descriptor_size,
grub_efi_uint32_t descriptor_version,
struct grub_efiemu_ptv_rel *cur_relloc;
LOG ('e');
-
+
/* Ensure that we are called only once */
if (ptv_relocated)
return GRUB_EFI_UNSUPPORTED;
ptv_relocated = 1;
-
+
/* Correct addresses using information supplied by grub */
for (cur_relloc = efiemu_ptv_relloc; cur_relloc->size;cur_relloc++)
{
grub_efi_memory_descriptor_t *descptr;
/* Compute correction */
- for (descptr = virtual_map;
- ((grub_uint8_t *) descptr - (grub_uint8_t *) virtual_map)
+ for (descptr = virtual_map;
+ ((grub_uint8_t *) descptr - (grub_uint8_t *) virtual_map)
< memory_map_size;
descptr = (grub_efi_memory_descriptor_t *)
((grub_uint8_t *) descptr + descriptor_size))
/* Recompute crc32 of system table and runtime services */
efiemu_system_table.hdr.crc32 = 0;
- efiemu_system_table.hdr.crc32 = efiemu_getcrc32
+ efiemu_system_table.hdr.crc32 = efiemu_getcrc32
(0, &efiemu_system_table, sizeof (efiemu_system_table));
efiemu_runtime_services.hdr.crc32 = 0;
- efiemu_runtime_services.hdr.crc32 = efiemu_getcrc32
+ efiemu_runtime_services.hdr.crc32 = efiemu_getcrc32
(0, &efiemu_runtime_services, sizeof (efiemu_runtime_services));
return GRUB_EFI_SUCCESS;
}
-/* since efiemu_set_virtual_address_map corrects all the pointers
+/* since efiemu_set_virtual_address_map corrects all the pointers
we don't need efiemu_convert_pointer */
grub_efi_status_t
-EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
+EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
void **address)
{
LOG ('f');
return GRUB_EFI_UNSUPPORTED;
}
-/* Next comes variable services. Because we have no vendor-independent
+/* Next comes variable services. Because we have no vendor-independent
way to store these variables we have no non-volatility */
/* Find variable by name and GUID. */
if (!efivar->namelen)
return 0;
if (efiemu_str16equal((grub_efi_char16_t *)(efivar + 1), variable_name)
- && efiemu_memequal (&(efivar->guid), vendor_guid,
+ && efiemu_memequal (&(efivar->guid), vendor_guid,
sizeof (efivar->guid)))
return efivar;
ptr += efivar->namelen + efivar->size + sizeof (*efivar);
efiemu_memcpy (data, (grub_uint8_t *)(efivar + 1) + efivar->namelen,
efivar->size);
*attributes = efivar->attributes;
-
+
return GRUB_EFI_SUCCESS;
}
-grub_efi_status_t EFI_FUNC
+grub_efi_status_t EFI_FUNC
(efiemu_get_next_variable_name) (grub_efi_uintn_t *variable_name_size,
grub_efi_char16_t *variable_name,
grub_efi_guid_t *vendor_guid)
efivar = find_variable (vendor_guid, variable_name);
if (!efivar)
return GRUB_EFI_NOT_FOUND;
- efivar = (struct efi_variable *)((grub_uint8_t *)efivar
- + efivar->namelen
+ efivar = (struct efi_variable *)((grub_uint8_t *)efivar
+ + efivar->namelen
+ efivar->size + sizeof (*efivar));
}
else
efivar = (struct efi_variable *) (efiemu_variables);
LOG ('m');
- if ((grub_uint8_t *)efivar >= efiemu_variables + efiemu_varsize
+ if ((grub_uint8_t *)efivar >= efiemu_variables + efiemu_varsize
|| !efivar->namelen)
return GRUB_EFI_NOT_FOUND;
if (*variable_name_size < efivar->namelen)
}
efiemu_memcpy (variable_name, efivar + 1, efivar->namelen);
- efiemu_memcpy (vendor_guid, &(efivar->guid),
+ efiemu_memcpy (vendor_guid, &(efivar->guid),
sizeof (efivar->guid));
LOG('h');
/* Delete variable if any */
if (efivar)
{
- efiemu_memcpy (efivar, (grub_uint8_t *)(efivar + 1)
- + efivar->namelen + efivar->size,
+ efiemu_memcpy (efivar, (grub_uint8_t *)(efivar + 1)
+ + efivar->namelen + efivar->size,
(efiemu_variables + efiemu_varsize)
- - ((grub_uint8_t *)(efivar + 1)
+ - ((grub_uint8_t *)(efivar + 1)
+ efivar->namelen + efivar->size));
- efiemu_memset (efiemu_variables + efiemu_varsize
+ efiemu_memset (efiemu_variables + efiemu_varsize
- (sizeof (*efivar) + efivar->namelen + efivar->size),
0, (sizeof (*efivar) + efivar->namelen + efivar->size));
}
if (!efivar->namelen)
break;
}
- if ((grub_uint8_t *)(efivar + 1) + data_size
- + 2 * (efiemu_str16len (variable_name) + 1)
+ if ((grub_uint8_t *)(efivar + 1) + data_size
+ + 2 * (efiemu_str16len (variable_name) + 1)
>= efiemu_variables + efiemu_varsize)
return GRUB_EFI_OUT_OF_RESOURCES;
efivar->namelen = 2 * (efiemu_str16len (variable_name) + 1);
efivar->size = data_size;
efivar->attributes = attributes;
- efiemu_memcpy (efivar + 1, variable_name,
+ efiemu_memcpy (efivar + 1, variable_name,
2 * (efiemu_str16len (variable_name) + 1));
- efiemu_memcpy ((grub_uint8_t *)(efivar + 1)
- + 2 * (efiemu_str16len (variable_name) + 1),
+ efiemu_memcpy ((grub_uint8_t *)(efivar + 1)
+ + 2 * (efiemu_str16len (variable_name) + 1),
data, data_size);
return GRUB_EFI_SUCCESS;
}
-grub_efi_status_t EFI_FUNC
+grub_efi_status_t EFI_FUNC
(efiemu_get_next_high_monotonic_count) (grub_efi_uint32_t *high_count)
{
LOG ('j');
LOG ('k');
}
-struct grub_efi_runtime_services efiemu_runtime_services =
+struct grub_efi_runtime_services efiemu_runtime_services =
{
- .hdr =
+ .hdr =
{
.signature = GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE,
.revision = 0x0001000a,
.get_next_variable_name = efiemu_get_next_variable_name,
.set_variable = efiemu_set_variable,
.get_next_high_monotonic_count = efiemu_get_next_high_monotonic_count,
-
+
.reset_system = efiemu_reset_system
};
-static grub_uint16_t efiemu_vendor[] =
+static grub_uint16_t efiemu_vendor[] =
{'G', 'R', 'U', 'B', ' ', 'E', 'F', 'I', ' ',
'R', 'U', 'N', 'T', 'I', 'M', 'E', 0};
struct grub_efi_system_table efiemu_system_table =
{
- .hdr =
+ .hdr =
{
.signature = GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE,
.revision = 0x0001000a,
gcc -c -m32 -DELF32 -o efiemu32.o ./efiemu.c -Wall -Werror -nostdlib -O2 -I. -I../../include
gcc -c -m64 -DELF64 -o efiemu64_c.o ./efiemu.c -Wall -Werror -mcmodel=large -O2 -I. -I../../include
gcc -c -m64 -DELF64 -o efiemu64_s.o ./efiemu.S -Wall -Werror -mcmodel=large -O2 -I. -I../../include
-ld -o efiemu64.o -r efiemu64_s.o efiemu64_c.o -nostdlib
+ld -o efiemu64.o -r efiemu64_s.o efiemu64_c.o -nostdlib
}
/* Announce that the module will need NUM allocators */
-/* Because of deferred memory allocation all the relocators have to be
+/* Because of deferred memory allocation all the relocators have to be
announced during phase 1*/
grub_err_t
grub_efiemu_request_symbols (int num)
{
if (ptv_alloc)
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
"symbols have already been allocated");
if (num < 0)
- return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
"can't request negative symbols");
ptv_requested += num;
return GRUB_ERR_NONE;
grub_efiemu_alloc_syms (void)
{
ptv_alloc = ptv_requested;
- ptv_handle = grub_efiemu_request_memalign
- (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel),
+ ptv_handle = grub_efiemu_request_memalign
+ (1, (ptv_requested + 1) * sizeof (struct grub_efiemu_ptv_rel),
GRUB_EFI_RUNTIME_SERVICES_DATA);
grub_efiemu_register_symbol ("efiemu_ptv_relloc", ptv_handle, 0);
return grub_errno;
}
-/* Write value (pointer to memory PLUS_HANDLE)
- - (pointer to memory MINUS_HANDLE) + VALUE to ADDR assuming that the
+/* Write value (pointer to memory PLUS_HANDLE)
+ - (pointer to memory MINUS_HANDLE) + VALUE to ADDR assuming that the
size SIZE bytes. If PTV_NEEDED is 1 then announce it to runtime that this
value needs to be recomputed before going to virtual mode
*/
/* Announce relocator to runtime */
if (ptv_needed)
{
- struct grub_efiemu_ptv_rel *ptv_rels
+ struct grub_efiemu_ptv_rel *ptv_rels
= grub_efiemu_mm_obtain_request (ptv_handle);
if (ptv_needed && ptv_written >= ptv_alloc)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"your module didn't declare efiemu "
" relocators correctly");
if (minus_handle)
- ptv_rels[ptv_written].minustype
+ ptv_rels[ptv_written].minustype
= grub_efiemu_mm_get_type (minus_handle);
else
ptv_rels[ptv_written].minustype = 0;
if (plus_handle)
- ptv_rels[ptv_written].plustype
+ ptv_rels[ptv_written].plustype
= grub_efiemu_mm_get_type (plus_handle);
else
ptv_rels[ptv_written].plustype = 0;
ptv_rels[ptv_written].addr = PTR_TO_UINT64 (addr);
ptv_rels[ptv_written].size = size;
ptv_written++;
-
+
/* memset next value to zero to mark the end */
grub_memset (&ptv_rels[ptv_written], 0, sizeof (ptv_rels[ptv_written]));
}
grub_uint32_t code;
grub_uint8_t storage_flags;
grub_uint32_t offset;
-
+
/* Glyph if loaded, or NULL otherwise. */
struct grub_font_glyph *glyph;
};
{
/* The file this section is in. */
grub_file_t file;
-
+
/* FOURCC name of the section. */
char name[4];
-
+
/* Length of the section contents. */
grub_uint32_t length;
-
+
/* Set by open_section() on EOF. */
int eof;
};
font->family = 0;
font->point_size = 0;
font->weight = 0;
-
+
/* Default leading value, not in font file yet. */
font->leading = 1;
-
+
font->max_char_width = 0;
font->max_char_height = 0;
font->ascent = 0;
if (! font->file)
/* No open file, can't load any glyphs. */
- return 0;
+ return 0;
/* Make sure we can find glyphs for error messages. Push active
error message to error stack and reset error message. */
else
/* Penalty for missing attributes. */
d += 50;
-
+
/* Weight is a minor factor. */
d += (a->weight != b->weight) ? 5 : 0;
| GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
glyph_bitmap.mode_info.bpp = 1;
-
+
/* Really 1 bit per pixel. */
glyph_bitmap.mode_info.bytes_per_pixel = 0;
-
+
/* Packed densely as bits. */
glyph_bitmap.mode_info.pitch = glyph->width;
-
+
glyph_bitmap.mode_info.number_of_colors = 2;
glyph_bitmap.mode_info.bg_red = 0;
glyph_bitmap.mode_info.bg_green = 0;
GRUB_MOD_FINI(font_manager)
{
- /* TODO: Determine way to free allocated resources.
+ /* TODO: Determine way to free allocated resources.
Warning: possible pointer references could be in use. */
grub_unregister_command (cmd_loadfont);
sizeof (file), &file);
if (grub_errno)
return 0;
-
+
block = grub_be_to_cpu32 (file.extension);
}
sizeof (pos), &pos);
if (grub_errno)
return 0;
-
+
return grub_be_to_cpu32 (pos);
}
sizeof (file), (char *) &file);
if (grub_errno)
goto fail;
-
+
file.name[file.namelen] = '\0';
if ((int) grub_be_to_cpu32 (file.type) == GRUB_AFFS_FILETYPE_DIR)
return 1;
next = grub_be_to_cpu32 (file.next);
- }
+ }
}
grub_free (hashtable);
{
struct grub_affs_data *data;
struct grub_fshelp_node *fdiro = 0;
-
+
grub_dl_ref (my_mod);
-
+
data = grub_affs_mount (file->device->disk);
if (!data)
goto fail;
-
+
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_affs_iterate_dir,
grub_affs_read_symlink, GRUB_FSHELP_REG);
if (grub_errno)
goto fail;
-
+
file->size = fdiro->size;
data->diropen = *fdiro;
grub_free (fdiro);
if (data && fdiro != &data->diropen)
grub_free (fdiro);
grub_free (data);
-
+
grub_dl_unref (my_mod);
return grub_errno;
static grub_ssize_t
grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_affs_data *data =
+ struct grub_affs_data *data =
(struct grub_affs_data *) file->data;
int size = grub_affs_read_file (&data->diropen, file->read_hook,
static grub_err_t
-grub_affs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_affs_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_affs_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
-
+
auto int NESTED_FUNC_ATTR iterate (const char *filename,
enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node);
}
grub_dl_ref (my_mod);
-
+
data = grub_affs_mount (device->disk);
if (!data)
goto fail;
-
+
grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_affs_iterate_dir,
grub_affs_read_symlink, GRUB_FSHELP_DIR);
if (grub_errno)
goto fail;
grub_affs_iterate_dir (fdiro, iterate);
-
+
fail:
if (data && fdiro != &data->diropen)
grub_free (fdiro);
static grub_err_t
grub_afs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_afs_data *data = 0;;
static grub_err_t
grub_cpio_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_cpio_data *data;
{
if (name[i] != fn[j])
goto no_match;
-
+
if (name[i] == '\0')
break;
-
+
if (name[i] == '/' && name[i+1] == '/')
i++;
-
+
i++;
j++;
}
return GRUB_ERR_NONE;
no_match:
-
+
grub_free (fn);
data->hofs = ofs;
}
/* Log2 size of ext2 block in 512 blocks. */
#define LOG2_EXT2_BLOCK_SIZE(data) \
(grub_le_to_cpu32 (data->sblock.log2_block_size) + 1)
-
+
/* Log2 size of ext2 block in bytes. */
#define LOG2_BLOCK_SIZE(data) \
(grub_le_to_cpu32 (data->sblock.log2_block_size) + 10)
/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
the mounted filesystem DATA. */
inline static grub_err_t
-grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
+grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
struct grub_ext2_block_group *blkgrp)
{
return grub_disk_read (data->disk,
int blknr = -1;
unsigned int blksz = EXT2_BLOCK_SIZE (data);
int log2_blksz = LOG2_EXT2_BLOCK_SIZE (data);
-
+
if (grub_le_to_cpu32(inode->flags) & EXT4_EXTENTS_FLAG)
{
char buf[EXT2_BLOCK_SIZE(data)];
<< log2_blksz,
0, blksz, indir))
return grub_errno;
-
+
blknr = grub_le_to_cpu32 (indir[fileblock - INDIRECT_BLOCKS]);
}
/* Double indirect. */
else if (fileblock < INDIRECT_BLOCKS + blksz / 4 * (blksz / 4 + 1))
{
unsigned int perblock = blksz / 4;
- unsigned int rblock = fileblock - (INDIRECT_BLOCKS
+ unsigned int rblock = fileblock - (INDIRECT_BLOCKS
+ blksz / 4);
grub_uint32_t indir[blksz / 4];
0, blksz, indir))
return grub_errno;
-
+
blknr = grub_le_to_cpu32 (indir[rblock % perblock]);
}
/* triple indirect. */
pos, len, buf, grub_ext2_read_block,
node->inode.size,
LOG2_EXT2_BLOCK_SIZE (node->data));
-
+
}
/* It is easier to calculate if the first inode is 0. */
ino--;
-
+
grub_ext2_blockgroup (data,
ino / grub_le_to_cpu32 (sblock->inodes_per_group),
&blkgrp);
EXT2_INODE_SIZE (data) * blkoff,
sizeof (struct grub_ext2_inode), inode))
return grub_errno;
-
+
return 0;
}
grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
goto fail;
}
-
+
/* Check the FS doesn't have feature bits enabled that we don't support. */
if (grub_le_to_cpu32 (data->sblock.feature_incompat)
& ~(EXT2_DRIVER_SUPPORTED_INCOMPAT | EXT2_DRIVER_IGNORED_INCOMPAT))
grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features");
goto fail;
}
-
-
+
+
data->disk = disk;
data->diropen.data = data;
grub_ext2_read_inode (data, 2, data->inode);
if (grub_errno)
goto fail;
-
+
return data;
fail:
{
char *symlink;
struct grub_fshelp_node *diro = node;
-
+
if (! diro->inode_read)
{
grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
if (grub_errno)
return 0;
}
-
+
symlink = grub_malloc (grub_le_to_cpu32 (diro->inode.size) + 1);
if (! symlink)
return 0;
-
+
/* If the filesize of the symlink is bigger than
60 the symlink is stored in a separate block,
otherwise it is stored in the inode. */
if (grub_le_to_cpu32 (diro->inode.size) <= 60)
- grub_strncpy (symlink,
+ grub_strncpy (symlink,
diro->inode.symlink,
grub_le_to_cpu32 (diro->inode.size));
else
return 0;
}
}
-
+
symlink[grub_le_to_cpu32 (diro->inode.size)] = '\0';
return symlink;
}
{
unsigned int fpos = 0;
struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
-
+
if (! diro->inode_read)
{
grub_ext2_read_inode (diro->data, diro->ino, &diro->inode);
if (grub_errno)
return 0;
}
-
+
/* Search the file. */
while (fpos < grub_le_to_cpu32 (diro->inode.size))
{
(char *) &dirent);
if (grub_errno)
return 0;
-
+
if (dirent.namelen != 0)
{
char filename[dirent.namelen + 1];
struct grub_fshelp_node *fdiro;
enum grub_fshelp_filetype type = GRUB_FSHELP_UNKNOWN;
-
+
grub_ext2_read_file (diro, 0, fpos + sizeof (struct ext2_dirent),
dirent.namelen, filename);
if (grub_errno)
return 0;
-
+
fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
if (! fdiro)
return 0;
-
+
fdiro->data = diro->data;
fdiro->ino = grub_le_to_cpu32 (dirent.inode);
-
+
filename[dirent.namelen] = '\0';
if (dirent.filetype != FILETYPE_UNKNOWN)
grub_free (fdiro);
return 0;
}
-
+
fdiro->inode_read = 1;
-
+
if ((grub_le_to_cpu16 (fdiro->inode.mode)
& FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY)
type = GRUB_FSHELP_DIR;
& FILETYPE_INO_MASK) == FILETYPE_INO_REG)
type = GRUB_FSHELP_REG;
}
-
+
if (hook (filename, type, fdiro))
return 1;
}
-
+
fpos += grub_le_to_cpu16 (dirent.direntlen);
}
-
+
return 0;
}
{
struct grub_ext2_data *data;
struct grub_fshelp_node *fdiro = 0;
-
+
grub_dl_ref (my_mod);
-
+
data = grub_ext2_mount (file->device->disk);
if (! data)
goto fail;
-
+
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_ext2_iterate_dir,
grub_ext2_read_symlink, GRUB_FSHELP_REG);
if (grub_errno)
goto fail;
-
+
if (! fdiro->inode_read)
{
grub_ext2_read_inode (data, fdiro->ino, &fdiro->inode);
if (grub_errno)
goto fail;
}
-
+
grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_ext2_inode));
grub_free (fdiro);
if (fdiro != &data->diropen)
grub_free (fdiro);
grub_free (data);
-
+
grub_dl_unref (my_mod);
return grub_errno;
grub_ext2_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_ext2_data *data = (struct grub_ext2_data *) file->data;
-
+
return grub_ext2_read_file (&data->diropen, file->read_hook,
file->offset, len, buf);
}
static grub_err_t
-grub_ext2_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_ext2_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_ext2_data *data = 0;;
struct grub_fshelp_node *fdiro = 0;
-
+
auto int NESTED_FUNC_ATTR iterate (const char *filename,
enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node);
}
grub_dl_ref (my_mod);
-
+
data = grub_ext2_mount (device->disk);
if (! data)
goto fail;
-
+
grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_ext2_iterate_dir,
grub_ext2_read_symlink, GRUB_FSHELP_DIR);
if (grub_errno)
goto fail;
-
+
grub_ext2_iterate_dir (fdiro, iterate);
-
+
fail:
if (fdiro != &data->diropen)
grub_free (fdiro);
}
/* Get mtime. */
-static grub_err_t
+static grub_err_t
grub_ext2_mtime (grub_device_t device, grub_int32_t *tm)
{
struct grub_ext2_data *data;
data = grub_ext2_mount (disk);
if (!data)
*tm = 0;
- else
+ else
*tm = grub_le_to_cpu32 (data->sblock.utime);
grub_dl_unref (my_mod);
{
int logical_sector_bits;
grub_uint32_t num_sectors;
-
+
grub_uint16_t fat_sector;
grub_uint32_t sectors_per_fat;
int fat_size;
-
+
grub_uint32_t root_cluster;
grub_uint32_t root_sector;
grub_uint32_t num_root_sectors;
-
+
int cluster_bits;
grub_uint32_t cluster_eof_mark;
grub_uint32_t cluster_sector;
fat_log2 (unsigned x)
{
int i;
-
+
if (x == 0)
return -1;
&& grub_strncmp((const char *) bpb.version_specific.fat12_or_fat16.fstype, "FAT16", 5)
&& grub_strncmp((const char *) bpb.version_specific.fat32.fstype, "FAT32", 5))
goto fail;
-
+
/* Get the sizes of logical sectors and clusters. */
data->logical_sector_bits =
fat_log2 (grub_le_to_cpu16 (bpb.bytes_per_sector));
if (data->logical_sector_bits < GRUB_DISK_SECTOR_BITS)
goto fail;
data->logical_sector_bits -= GRUB_DISK_SECTOR_BITS;
-
+
data->cluster_bits = fat_log2 (bpb.sectors_per_cluster);
if (data->cluster_bits < 0)
goto fail;
{
/* FAT32. */
grub_uint16_t flags = grub_le_to_cpu16 (bpb.version_specific.fat32.extended_flags);
-
+
data->root_cluster = grub_le_to_cpu32 (bpb.version_specific.fat32.root_cluster);
data->fat_size = 32;
data->cluster_eof_mark = 0x0ffffff8;
-
+
if (flags & 0x80)
{
/* Get an active FAT. */
unsigned active_fat = flags & 0xf;
-
+
if (active_fat > bpb.num_fats)
goto fail;
data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat12_or_fat16.num_serial);
else
data->uuid = grub_le_to_cpu32 (bpb.version_specific.fat32.num_serial);
-
+
/* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
descriptor, even if it is a so-called superfloppy (e.g. an USB key).
The check may be too strict for this kind of stupid BIOSes, as
unsigned logical_cluster_bits;
grub_ssize_t ret = 0;
unsigned long sector;
-
+
/* This is a special case. FAT12 and FAT16 doesn't have the root directory
in clusters. */
if (data->file_cluster == ~0U)
case 12:
if (data->cur_cluster & 1)
next_cluster >>= 4;
-
+
next_cluster &= 0x0FFF;
break;
}
grub_printf ("%s:%d: fat_size=%d, next_cluster=%u\n",
__FILE__, __LINE__, data->fat_size, next_cluster);
#endif
-
+
/* Check the end. */
if (next_cluster >= data->cluster_eof_mark)
return ret;
static grub_err_t
grub_fat_iterate_dir (grub_disk_t disk, struct grub_fat_data *data,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
struct grub_fat_dir_entry *dir))
{
struct grub_fat_dir_entry dir;
int slot = -1, slots = -1;
int checksum = -1;
grub_ssize_t offset = -sizeof(dir);
-
+
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
+
/* Allocate space enough to hold a long name. */
filename = grub_malloc (0x40 * 13 * 4 + 1);
unibuf = (grub_uint16_t *) grub_malloc (0x40 * 13 * 2);
grub_free (unibuf);
return 0;
}
-
+
while (1)
{
unsigned i;
struct grub_fat_long_name_entry *long_name
= (struct grub_fat_long_name_entry *) &dir;
grub_uint8_t id = long_name->id;
-
+
if (id & 0x40)
{
id &= 0x3f;
/* This is a workaround for Japanese. */
if (dir.name[0] == 0x05)
dir.name[0] = 0xe5;
-
+
if (checksum != -1 && slot == 0)
{
grub_uint8_t sum;
-
+
for (sum = 0, i = 0; i < sizeof (dir.name); i++)
sum = ((sum >> 1) | (sum << 7)) + dir.name[i];
for (u = 0; u < slots * 13; u++)
unibuf[u] = grub_le_to_cpu16 (unibuf[u]);
-
+
*grub_utf16_to_utf8 ((grub_uint8_t *) filename, unibuf,
slots * 13) = '\0';
-
+
if (hook (filename, &dir))
break;
-
+
checksum = -1;
continue;
}
filep = filename;
if (dir.attr & GRUB_FAT_ATTR_VOLUME_ID)
{
- for (i = 0; i < sizeof (dir.name) && dir.name[i]
+ for (i = 0; i < sizeof (dir.name) && dir.name[i]
&& ! grub_isspace (dir.name[i]); i++)
*filep++ = dir.name[i];
}
{
for (i = 0; i < 8 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
*filep++ = grub_tolower (dir.name[i]);
-
+
*filep = '.';
-
+
for (i = 8; i < 11 && dir.name[i] && ! grub_isspace (dir.name[i]); i++)
*++filep = grub_tolower (dir.name[i]);
static char *
grub_fat_find_dir (grub_disk_t disk, struct grub_fat_data *data,
const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
char *dirname, *dirp;
if (call_hook)
hook (filename, &info);
-
+
return 1;
}
return 0;
}
-
+
if (! (data->attr & GRUB_FAT_ATTR_DIRECTORY))
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
return 0;
}
-
+
/* Extract a directory name. */
while (*path == '/')
path++;
if (dirp)
{
unsigned len = dirp - path;
-
+
dirname = grub_malloc (len + 1);
if (! dirname)
return 0;
dirname = grub_strdup (path);
call_hook = (! dirp && hook);
-
+
grub_fat_iterate_dir (disk, data, iter_hook);
if (grub_errno == GRUB_ERR_NONE && ! found && !call_hook)
grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
static grub_err_t
grub_fat_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_fat_data *data = 0;
char *p;
grub_dl_ref (my_mod);
-
+
data = grub_fat_mount (disk);
if (! data)
goto fail;
*p++ = '/';
*p = '\0';
p = dirname;
-
+
do
{
p = grub_fat_find_dir (disk, data, p, hook);
grub_free (dirname);
grub_free (data);
-
+
grub_dl_unref (my_mod);
-
+
return grub_errno;
}
char *p = (char *) name;
grub_dl_ref (my_mod);
-
+
data = grub_fat_mount (file->device->disk);
if (! data)
goto fail;
file->data = data;
file->size = data->file_size;
-
+
return GRUB_ERR_NONE;
fail:
-
+
grub_free (data);
-
+
grub_dl_unref (my_mod);
-
+
return grub_errno;
}
grub_fat_close (grub_file_t file)
{
grub_free (file->data);
-
+
grub_dl_unref (my_mod);
-
+
return grub_errno;
}
}
grub_dl_ref (my_mod);
-
+
data = grub_fat_mount (disk);
if (! data)
goto fail;
}
*label = 0;
-
+
grub_fat_iterate_dir (disk, data, iter_hook);
fail:
grub_err_t err;
enum grub_fshelp_filetype foundtype = GRUB_FSHELP_DIR;
int symlinknest = 0;
-
+
auto grub_err_t NESTED_FUNC_ATTR find_file (const char *currpath,
grub_fshelp_node_t currroot,
grub_fshelp_node_t *currfound);
grub_fshelp_node_t node);
auto void free_node (grub_fshelp_node_t node);
-
+
void free_node (grub_fshelp_node_t node)
{
if (node != rootnode && node != currroot)
grub_free (node);
}
-
+
int NESTED_FUNC_ATTR iterate (const char *filename,
enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node)
grub_free (node);
return 0;
}
-
+
/* The node is found, stop iterating over the nodes. */
type = filetype & ~GRUB_FSHELP_CASE_INSENSITIVE;
oldnode = currnode;
currnode = node;
-
+
return 1;
}
-
+
grub_strncpy (fpath, currpath, grub_strlen (currpath) + 1);
-
+
/* Remove all leading slashes. */
while (*name == '/')
name++;
-
+
if (! *name)
{
*currfound = currnode;
return 0;
}
-
+
for (;;)
{
int found;
-
+
/* Extract the actual part from the pathname. */
next = grub_strchr (name, '/');
if (next)
while (*next == '/')
*(next++) = '\0';
}
-
+
/* At this point it is expected that the current node is a
directory, check if this is true. */
if (type != GRUB_FSHELP_DIR)
free_node (currnode);
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
}
-
+
/* Iterate over the directory. */
found = iterate_dir (currnode, iterate);
if (! found)
{
if (grub_errno)
return grub_errno;
-
+
break;
}
-
+
/* Read in the symlink and follow it. */
if (type == GRUB_FSHELP_SYMLINK)
{
char *symlink;
-
+
/* Test if the symlink does not loop. */
if (++symlinknest == 8)
{
return grub_error (GRUB_ERR_SYMLINK_LOOP,
"too deep nesting of symlinks");
}
-
+
symlink = read_symlink (currnode);
free_node (currnode);
-
+
if (!symlink)
{
free_node (oldnode);
return grub_errno;
}
-
+
/* The symlink is an absolute path, go back to the root inode. */
if (symlink[0] == '/')
{
free_node (oldnode);
oldnode = rootnode;
- }
-
+ }
+
/* Lookup the node the symlink points to. */
find_file (symlink, oldnode, &currnode);
type = foundtype;
grub_free (symlink);
-
+
if (grub_errno)
{
free_node (oldnode);
return grub_errno;
}
}
-
+
free_node (oldnode);
-
+
/* Found the node! */
if (! next || *next == '\0')
{
foundtype = type;
return 0;
}
-
+
name = next;
}
-
+
return grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
}
grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
return grub_errno;
}
-
+
err = find_file (path, rootnode, foundnode);
if (err)
return err;
-
+
/* Check if the node that was found was of the expected type. */
if (expecttype == GRUB_FSHELP_REG && foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
else if (expecttype == GRUB_FSHELP_DIR && foundtype != expecttype)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
+
return 0;
}
blknr = get_block (node, i);
if (grub_errno)
return -1;
-
+
blknr = blknr << log2blocksize;
/* Last block. */
if (i == blockcnt - 1)
{
blockend = (len + pos) & (blocksize - 1);
-
+
/* The last portion is exactly blocksize. */
if (! blockend)
blockend = blocksize;
skipfirst = blockoff;
blockend -= skipfirst;
}
-
+
/* If the block number is 0 this block is not stored on disk but
is zero filled instead. */
if (blknr)
{
- disk->read_hook = read_hook;
+ disk->read_hook = read_hook;
grub_disk_read (disk, blknr, skipfirst,
blockend, buf);
grub_fshelp_log2blksize (unsigned int blksize, unsigned int *pow)
{
int mod;
-
+
*pow = 0;
while (blksize > 1)
{
{
grub_uint8_t unused;
grub_uint32_t parent_dir;
-
+
/* Filename length. */
grub_uint8_t strlen;
grub_hfs_datarecord_t dr;
int pos = 0;
struct grub_hfs_extent_key key;
-
+
int tree = 0;
static int cache_file = 0;
- static int cache_pos = 0;
+ static int cache_pos = 0;
static grub_hfs_datarecord_t cache_dr;
-
+
grub_memcpy (dr, dat, sizeof (dr));
-
+
key.forktype = 0;
key.fileid = grub_cpu_to_be32 (file);
-
+
if (cache && cache_file == file && block > cache_pos)
{
pos = cache_pos;
key.first_block = grub_cpu_to_be16 (pos);
grub_memcpy (dr, cache_dr, sizeof (cache_dr));
}
-
+
for (;;)
{
int i;
-
+
/* Try all 3 extents. */
for (i = 0; i < 3; i++)
{
if (grub_be_to_cpu16 (dr[i].count) + pos > block)
{
int first = grub_be_to_cpu16 (dr[i].first_block);
-
+
/* If the cache is enabled, store the current position
in the tree. */
if (tree && cache)
cache_pos = pos;
grub_memcpy (cache_dr, dr, sizeof (cache_dr));
}
-
+
return (grub_be_to_cpu16 (data->sblock.first_block)
+ (first + block - pos) * GRUB_HFS_BLKS);
}
-
+
/* Try the next extent. */
pos += grub_be_to_cpu16 (dr[i].count);
}
-
+
/* Lookup the block in the extent overflow file. */
key.first_block = grub_cpu_to_be16 (pos);
tree = 1;
if (len > grub_le_to_cpu32 (data->size))
len = grub_le_to_cpu32 (data->size);
- blockcnt = ((len + pos)
+ blockcnt = ((len + pos)
+ data->blksz - 1) / data->blksz;
for (i = pos / data->blksz; i < blockcnt; i++)
int blockend = data->blksz;
int skipfirst = 0;
-
+
blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
if (grub_errno)
return -1;
-
+
/* Last block. */
if (i == blockcnt - 1)
{
blockend = (len + pos) % data->blksz;
-
+
/* The last portion is exactly EXT2_BLOCK_SIZE (data). */
if (! blockend)
blockend = data->blksz;
is zero filled instead. */
if (blknr)
{
- data->disk->read_hook = read_hook;
+ data->disk->read_hook = read_hook;
grub_disk_read (data->disk, blknr, skipfirst,
blockend, buf);
data->disk->read_hook = 0;
if (grub_errno)
return -1;
}
-
+
buf += data->blksz - skipfirst;
}
-
+
return len;
}
struct grub_hfs_catalog_key key;
struct grub_hfs_dirrec dir;
int first_block;
-
+
struct
{
struct grub_hfs_node node;
struct grub_hfs_treeheader head;
} treehead;
-
+
data = grub_malloc (sizeof (struct grub_hfs_data));
if (!data)
return 0;
if (grub_disk_read (disk, GRUB_HFS_SBLOCK, 0,
sizeof (struct grub_hfs_sblock), &data->sblock))
goto fail;
-
+
/* Check if this is a HFS filesystem. */
if (grub_be_to_cpu16 (data->sblock.magic) != GRUB_HFS_MAGIC)
{
grub_error (GRUB_ERR_BAD_FS, "embedded HFS+ filesystem");
goto fail;
}
-
+
data->blksz = grub_be_to_cpu32 (data->sblock.blksz);
data->disk = disk;
-
+
/* Lookup the root node of the extent overflow tree. */
- first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block)
+ first_block = ((grub_be_to_cpu16 (data->sblock.extent_recs[0].first_block)
* GRUB_HFS_BLKS)
+ grub_be_to_cpu16 (data->sblock.first_block));
-
+
if (grub_disk_read (data->disk, first_block, 0,
sizeof (treehead), &treehead))
goto fail;
data->ext_root = grub_be_to_cpu32 (treehead.head.root_node);
data->ext_size = grub_be_to_cpu16 (treehead.head.node_size);
-
+
/* Lookup the root node of the catalog tree. */
- first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block)
+ first_block = ((grub_be_to_cpu16 (data->sblock.catalog_recs[0].first_block)
* GRUB_HFS_BLKS)
+ grub_be_to_cpu16 (data->sblock.first_block));
if (grub_disk_read (data->disk, first_block, 0,
goto fail;
data->cat_root = grub_be_to_cpu32 (treehead.head.root_node);
data->cat_size = grub_be_to_cpu16 (treehead.head.node_size);
-
+
/* Lookup the root directory node in the catalog tree using the
volume name. */
key.parent_dir = grub_cpu_to_be32 (1);
key.strlen = data->sblock.volname[0];
grub_strcpy ((char *) key.str, (char *) (data->sblock.volname + 1));
-
+
if (grub_hfs_find_node (data, (char *) &key, data->cat_root,
0, (char *) &dir, sizeof (dir)) == 0)
{
grub_error (GRUB_ERR_BAD_FS, "can not find the hfs root directory");
goto fail;
}
-
+
if (grub_errno)
goto fail;
data->rootdir = grub_be_to_cpu32 (dir.dirid);
-
+
return data;
fail:
grub_free (data);
-
+
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not a hfs filesystem");
-
+
return 0;
}
if (cmp == 0)
cmp = grub_be_to_cpu32 (k1->fileid) - grub_be_to_cpu32 (k2->fileid);
if (cmp == 0)
- cmp = (grub_be_to_cpu16 (k1->first_block)
+ cmp = (grub_be_to_cpu16 (k1->first_block)
- grub_be_to_cpu16 (k2->first_block));
return cmp;
}
struct grub_hfs_record *))
{
int nodesize = type == 0 ? data->cat_size : data->ext_size;
-
+
union
{
struct grub_hfs_node node;
char rawnode[nodesize];
grub_uint16_t offsets[nodesize / 2];
} node;
-
+
do
{
int i;
struct grub_hfs_extent *dat;
int blk;
-
- dat = (struct grub_hfs_extent *) (type == 0
+
+ dat = (struct grub_hfs_extent *) (type == 0
? (&data->sblock.catalog_recs)
: (&data->sblock.extent_recs));
-
+
/* Read the node into memory. */
blk = grub_hfs_block (data, dat,
(type == 0) ? GRUB_HFS_CNID_CAT : GRUB_HFS_CNID_EXT,
blk += (idx % (data->blksz / nodesize));
if (grub_errno)
return grub_errno;
-
+
if (grub_disk_read (data->disk, blk, 0,
sizeof (node), &node))
return grub_errno;
-
+
/* Iterate over all records in this node. */
for (i = 0; i < grub_be_to_cpu16 (node.node.reccnt); i++)
{
} __attribute__ ((packed)) *pnt;
pnt = (struct pointer *) (grub_be_to_cpu16 (node.offsets[pos])
+ node.rawnode);
-
- struct grub_hfs_record rec =
+
+ struct grub_hfs_record rec =
{
&pnt->key,
pnt->keylen,
&pnt->key + pnt->keylen +(pnt->keylen + 1) % 2,
- nodesize - grub_be_to_cpu16 (node.offsets[pos])
+ nodesize - grub_be_to_cpu16 (node.offsets[pos])
- pnt->keylen - 1
};
-
+
if (node_hook (&node.node, &rec))
return 0;
}
-
+
idx = grub_be_to_cpu32 (node.node.next);
} while (idx && this);
-
+
return 0;
}
int found = -1;
int isleaf = 0;
int done = 0;
-
+
auto int node_found (struct grub_hfs_node *, struct grub_hfs_record *);
-
+
int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
{
int cmp = 1;
-
+
if (type == 0)
cmp = grub_hfs_cmp_catkeys (rec->key, (void *) key);
else
cmp = grub_hfs_cmp_extkeys (rec->key, (void *) key);
-
+
/* If the key is smaller or equal to the current node, mark the
entry. In case of a non-leaf mode it will be used to lookup
the rest of the tree. */
}
else /* The key can not be found in the tree. */
return 1;
-
+
/* Check if this node is a leaf node. */
if (hnd->type == GRUB_HFS_NODE_LEAF)
{
isleaf = 1;
-
+
/* Found it!!!! */
if (cmp == 0)
{
return 1;
}
}
-
+
return 0;
}
-
+
do
{
found = -1;
if (grub_hfs_iterate_records (data, type, idx, 0, node_found))
return 0;
-
+
if (found == -1)
return 0;
idx = found;
} while (! isleaf);
-
+
return done;
}
int found = -1;
int isleaf = 0;
int next = 0;
-
+
/* The lowest key possible with DIR as root directory. */
struct grub_hfs_catalog_key key = {0, grub_cpu_to_be32 (dir), 0, ""};
auto int it_dir (struct grub_hfs_node * __attribute ((unused)),
struct grub_hfs_record *);
-
+
int node_found (struct grub_hfs_node *hnd, struct grub_hfs_record *rec)
{
struct grub_hfs_catalog_key *ckey = rec->key;
-
+
if (grub_hfs_cmp_catkeys (rec->key, (void *) &key) <= 0)
found = grub_be_to_cpu32 (*(grub_uint32_t *) rec->data);
-
+
if (hnd->type == 0xFF && ckey->strlen > 0)
{
isleaf = 1;
next = grub_be_to_cpu32 (hnd->next);
-
+
/* An entry was found. */
if (grub_be_to_cpu32 (ckey->parent_dir) == dir)
return hook (rec);
}
-
+
return 0;
}
-
+
int it_dir (struct grub_hfs_node *hnd __attribute ((unused)),
struct grub_hfs_record *rec)
{
struct grub_hfs_catalog_key *ckey = rec->key;
struct grub_hfs_catalog_key *origkey = &key;
-
+
/* Stop when the entries do not match anymore. */
- if (grub_be_to_cpu32 (ckey->parent_dir)
+ if (grub_be_to_cpu32 (ckey->parent_dir)
!= grub_be_to_cpu32 ((origkey)->parent_dir))
return 1;
-
+
return hook (rec);
}
-
+
do
{
found = -1;
if (grub_hfs_iterate_records (data, 0, root_idx, 0, node_found))
return grub_errno;
-
+
if (found == -1)
return 0;
-
+
root_idx = found;
} while (! isleaf);
} fdrec;
fdrec.frec.type = GRUB_HFS_FILETYPE_DIR;
-
+
if (path[0] != '/')
{
grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
return 0;
}
-
+
origpath = grub_strdup (path);
if (!origpath)
return grub_errno;
-
+
path = origpath;
while (*path == '/')
path++;
-
+
while (path && grub_strlen (path))
{
if (fdrec.frec.type != GRUB_HFS_FILETYPE_DIR)
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
goto fail;
}
-
+
/* Isolate a part of the path. */
next = grub_strchr (path, '/');
if (next)
while (*next == '/')
*(next++) = '\0';
}
-
+
struct grub_hfs_catalog_key key;
-
+
key.parent_dir = grub_cpu_to_be32 (inode);
key.strlen = grub_strlen (path);
grub_strcpy ((char *) (key.str), path);
-
+
/* Lookup this node. */
if (! grub_hfs_find_node (data, (char *) &key, data->cat_root,
0, (char *) &fdrec.frec, sizeof (fdrec.frec)))
if (grub_errno)
goto fail;
-
+
inode = grub_be_to_cpu32 (fdrec.dir.dirid);
path = next;
}
if (retdata)
grub_memcpy (retdata, &fdrec.frec, sizeof (fdrec.frec));
-
+
if (retinode)
*retinode = inode;
-
+
fail:
grub_free (origpath);
return grub_errno;
\f
static grub_err_t
-grub_hfs_dir (grub_device_t device, const char *path,
+grub_hfs_dir (grub_device_t device, const char *path,
int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_hfs_catalog_key *ckey = rec->key;
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
-
+
grub_strncpy (fname, (char *) (ckey->str), ckey->strlen);
-
- if (*filetype == GRUB_HFS_FILETYPE_DIR
+
+ if (*filetype == GRUB_HFS_FILETYPE_DIR
|| *filetype == GRUB_HFS_FILETYPE_FILE)
{
info.dir = (*filetype == GRUB_HFS_FILETYPE_DIR);
}
return 0;
}
-
+
struct grub_hfs_data *data;
struct grub_hfs_filerec frec;
grub_dl_ref (my_mod);
-
+
data = grub_hfs_mount (device->disk);
if (!data)
goto fail;
-
+
/* First the directory ID for the directory. */
if (grub_hfs_find_dir (data, path, &frec, &inode))
goto fail;
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
goto fail;
}
-
+
grub_hfs_iterate_dir (data, data->cat_root, inode, dir_hook);
-
+
fail:
grub_free (data);
grub_dl_unref (my_mod);
-
+
return grub_errno;
}
{
struct grub_hfs_data *data;
struct grub_hfs_filerec frec;
-
+
grub_dl_ref (my_mod);
data = grub_hfs_mount (file->device->disk);
-
+
if (grub_hfs_find_dir (data, name, &frec, 0))
{
grub_free (data);
grub_dl_unref (my_mod);
return grub_errno;
}
-
+
if (frec.type != GRUB_HFS_FILETYPE_FILE)
{
grub_free (data);
grub_dl_unref (my_mod);
return grub_errno;
}
-
+
grub_memcpy (data->extents, frec.extents, sizeof (grub_hfs_datarecord_t));
file->size = grub_be_to_cpu32 (frec.size);
data->size = grub_be_to_cpu32 (frec.size);
file->offset = 0;
file->data = data;
-
+
return 0;
}
static grub_ssize_t
grub_hfs_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_hfs_data *data =
+ struct grub_hfs_data *data =
(struct grub_hfs_data *) file->data;
-
+
return grub_hfs_read_file (data, file->read_hook, file->offset, len, buf);
}
struct grub_hfs_data *data;
data = grub_hfs_mount (device->disk);
-
+
if (data)
*label = grub_strndup ((char *) (data->sblock.volname + 1),
*data->sblock.volname);
code above used this memory, it can be freed now. */
grub_free (nnode);
nnode = 0;
-
+
if (blk != -1)
return (blk
+ (node->data->embedded_offset >> (node->data->log2blksize
grub_memcpy (&data->catalog_tree.file.extents,
data->volheader.catalog_file.extents,
sizeof data->volheader.catalog_file.extents);
- data->catalog_tree.file.size =
+ data->catalog_tree.file.size =
grub_be_to_cpu64 (data->volheader.catalog_file.size);
/* Make a new node for the extent overflow file. */
data->volheader.extents_file.extents,
sizeof data->volheader.catalog_file.extents);
- data->extoverflow_tree.file.size =
+ data->extoverflow_tree.file.size =
grub_be_to_cpu64 (data->volheader.extents_file.size);
/* Read the essential information about the trees. */
char *filename;
int i;
int diff;
-
+
diff = grub_be_to_cpu32 (catkey_a->parent) - catkey_b->parent;
if (diff)
- return diff;
+ return diff;
/* Change the filename in keya so the endianness is correct. */
for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++)
int first_rec,
int (*hook) (void *record))
{
- int rec;
+ int rec;
for (;;)
{
for (rec = 0; rec < grub_be_to_cpu16 (nodedesc->count); rec++)
{
struct grub_hfsplus_key *currkey;
- currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec);
-
+ currkey = grub_hfsplus_btree_recptr (btree, nodedesc, rec);
+
/* The action that has to be taken depend on the type of
record. */
if (nodedesc->type == GRUB_HFSPLUS_BTNODE_TYPE_LEAF
grub_fshelp_node_t node))
{
int ret = 0;
-
+
auto int list_nodes (void *record);
int list_nodes (void *record)
{
catkey = (struct grub_hfsplus_catkey *) record;
fileinfo =
- (struct grub_hfsplus_catfile *) ((char *) record
+ (struct grub_hfsplus_catfile *) ((char *) record
+ grub_be_to_cpu16 (catkey->keylen)
+ 2 + (grub_be_to_cpu16(catkey->keylen)
% 2));
callback function. */
node = grub_malloc (sizeof (*node));
node->data = dir->data;
-
+
grub_memcpy (node->extents, fileinfo->data.extents,
sizeof (node->extents));
node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800;
{
struct grub_hfsplus_data *data;
struct grub_fshelp_node *fdiro = 0;
-
+
grub_dl_ref (my_mod);
-
+
data = grub_hfsplus_mount (file->device->disk);
if (!data)
goto fail;
if (data && fdiro != &data->dirroot)
grub_free (fdiro);
grub_free (data);
-
+
grub_dl_unref (my_mod);
return grub_errno;
static grub_ssize_t
grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_hfsplus_data *data =
+ struct grub_hfsplus_data *data =
(struct grub_hfsplus_data *) file->data;
int size = grub_hfsplus_read_file (&data->opened_file, file->read_hook,
static grub_err_t
-grub_hfsplus_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_hfsplus_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_hfsplus_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
-
+
auto int NESTED_FUNC_ATTR iterate (const char *filename,
enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node);
}
grub_dl_ref (my_mod);
-
+
data = grub_hfsplus_mount (device->disk);
if (!data)
goto fail;
/* Iterate over all entries in this directory. */
grub_hfsplus_iterate_dir (fdiro, iterate);
-
+
fail:
if (data && fdiro != &data->dirroot)
grub_free (fdiro);
}
/* Get mtime. */
-static grub_err_t
+static grub_err_t
grub_hfsplus_mtime (grub_device_t device, grub_int32_t *tm)
{
struct grub_hfsplus_data *data;
data = grub_hfsplus_mount (disk);
if (!data)
*tm = 0;
- else
+ else
*tm = grub_be_to_cpu32 (data->volheader.utime) - 2082844800;
grub_dl_unref (my_mod);
if (data)
{
*uuid = grub_malloc (16 + sizeof ('\0'));
- grub_sprintf (*uuid, "%016llx",
- (unsigned long long)
+ grub_sprintf (*uuid, "%016llx",
+ (unsigned long long)
grub_be_to_cpu64 (data->volheader.num_serial));
}
else
{
char *sua;
struct grub_iso9660_susp_entry *entry;
-
+
auto grub_err_t load_sua (void);
-
+
/* Load a part of the System Usage Area. */
grub_err_t load_sua (void)
{
sua = grub_malloc (sua_size);
if (!sua)
return grub_errno;
-
+
if (grub_disk_read (data->disk, sua_block, sua_pos,
sua_size, sua))
return grub_errno;
-
+
entry = (struct grub_iso9660_susp_entry *) sua;
return 0;
}
-
+
if (load_sua ())
return grub_errno;
-
+
for (; (char *) entry < (char *) sua + sua_size - 1;
entry = (struct grub_iso9660_susp_entry *)
((char *) entry + entry->len))
/* The last entry. */
if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0)
break;
-
+
/* Additional entries are stored elsewhere. */
if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0)
{
struct grub_iso9660_susp_ce *ce;
-
+
ce = (struct grub_iso9660_susp_ce *) entry;
sua_size = grub_le_to_cpu32 (ce->len);
sua_pos = grub_le_to_cpu32 (ce->off);
sua_block = grub_le_to_cpu32 (ce->blk) << GRUB_ISO9660_LOG2_BLKSZ;
-
+
grub_free (sua);
if (load_sua ())
return grub_errno;
}
-
+
if (hook (entry))
{
grub_free (sua);
return 0;
}
}
-
+
grub_free (sua);
return 0;
}
struct grub_iso9660_susp_entry *entry;
struct grub_iso9660_primary_voldesc voldesc;
int block;
-
+
auto grub_err_t susp_iterate (struct grub_iso9660_susp_entry *);
-
+
grub_err_t susp_iterate (struct grub_iso9660_susp_entry *susp_entry)
{
/* The "ER" entry is used to detect extensions. The
}
return 0;
}
-
+
data = grub_malloc (sizeof (struct grub_iso9660_data));
if (! data)
return 0;
-
+
data->disk = disk;
data->rockridge = 0;
data->joliet = 0;
grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
goto fail;
}
-
+
sua_pos = (sizeof (rootdir) + rootdir.namelen
+ (rootdir.namelen % 2) - 1);
sua_size = rootdir.len - sua_pos;
sua = grub_malloc (sua_size);
if (! sua)
goto fail;
-
+
if (grub_disk_read (disk, (grub_le_to_cpu32 (data->voldesc.rootdir.first_sector)
<< GRUB_ISO9660_LOG2_BLKSZ), sua_pos,
sua_size, sua))
grub_error (GRUB_ERR_BAD_FS, "not a iso9660 filesystem");
goto fail;
}
-
+
entry = (struct grub_iso9660_susp_entry *) sua;
-
+
/* Test if the SUSP protocol is used on this filesystem. */
if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
{
to get to the SUA (System Usage Area). */
data->susp_skip = entry->data[2];
entry = (struct grub_iso9660_susp_entry *) ((char *) entry + entry->len);
-
+
/* Iterate over the entries in the SUA area to detect
extensions. */
if (grub_iso9660_susp_iterate (data,
sua_pos, sua_size, susp_iterate))
goto fail;
}
-
+
return data;
-
+
fail:
grub_free (data);
return 0;
int sua_size;
char *symlink = 0;
int addslash = 0;
-
+
auto void add_part (const char *part, int len);
auto grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *);
void add_part (const char *part, int len)
{
int size = grub_strlen (symlink);
-
+
symlink = grub_realloc (symlink, size + len + 1);
if (! symlink)
return;
-
+
grub_strncat (symlink, part, len);
}
-
+
/* Read in a symlink. */
grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry)
{
add_part ("/", 1);
addslash = 0;
}
-
+
/* The current position is the `Component Flag'. */
switch (entry->data[pos] & 30)
{
break;
}
-
+
case 2:
add_part ("./", 2);
break;
-
+
case 4:
add_part ("../", 3);
break;
-
+
case 8:
add_part ("/", 1);
break;
stored. */
pos += entry->data[pos + 1] + 2;
}
-
+
/* Check if `grub_realloc' failed. */
if (grub_errno)
return grub_errno;
}
-
+
return 0;
}
-
+
if (grub_disk_read (node->data->disk, node->dir_blk, node->dir_off,
sizeof (dirent), (char *) &dirent))
return 0;
-
+
sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2)
+ node->data->susp_skip);
sua_size = dirent.len - sua_off;
-
+
symlink = grub_malloc (1);
if (!symlink)
return 0;
-
+
*symlink = '\0';
-
+
if (grub_iso9660_susp_iterate (node->data, node->dir_blk,
node->dir_off + sua_off,
sua_size, susp_iterate_sl))
grub_free (symlink);
return 0;
}
-
+
return symlink;
}
char *filename;
int filename_alloc = 0;
enum grub_fshelp_filetype type;
-
+
auto grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *);
grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry)
type = GRUB_FSHELP_UNKNOWN;
}
}
-
+
return 0;
}
offset % GRUB_DISK_SECTOR_SIZE,
sizeof (dirent), (char *) &dirent))
return 0;
-
+
/* The end of the block, skip to the next one. */
if (!dirent.len)
{
offset = (offset / GRUB_ISO9660_BLKSZ + 1) * GRUB_ISO9660_BLKSZ;
continue;
}
-
+
{
char name[dirent.namelen + 1];
int nameoffset = offset + sizeof (dirent);
int sua_off = (sizeof (dirent) + dirent.namelen + 1
- (dirent.namelen % 2));;
int sua_size = dirent.len - sua_off;
-
+
sua_off += offset + dir->data->susp_skip;
-
+
filename = 0;
filename_alloc = 0;
type = GRUB_FSHELP_UNKNOWN;
sua_off % GRUB_DISK_SECTOR_SIZE,
sua_size, susp_iterate_dir))
return 0;
-
+
/* Read the name. */
if (grub_disk_read (dir->data->disk,
(dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
nameoffset % GRUB_DISK_SECTOR_SIZE,
dirent.namelen, (char *) name))
return 0;
-
+
node = grub_malloc (sizeof (struct grub_fshelp_node));
if (!node)
return 0;
-
+
/* Setup a new node. */
node->data = dir->data;
node->size = grub_le_to_cpu32 (dirent.size);
node->dir_blk = ((dir->blk << GRUB_ISO9660_LOG2_BLKSZ)
+ offset / GRUB_DISK_SECTOR_SIZE);
node->dir_off = offset % GRUB_DISK_SECTOR_SIZE;
-
+
/* If the filetype was not stored using rockridge, use
whatever is stored in the iso9660 filesystem. */
if (type == GRUB_FSHELP_UNKNOWN)
else
type = GRUB_FSHELP_REG;
}
-
+
/* The filename was not stored in a rock ridge entry. Read it
from the iso9660 filesystem. */
if (!filename)
filename = grub_strrchr (name, ';');
if (filename)
*filename = '\0';
-
+
if (dirent.namelen == 1 && name[0] == 0)
filename = ".";
else if (dirent.namelen == 1 && name[0] == 1)
else
filename = name;
}
-
+
if (dir->data->joliet)
{
char *oldname;
if (filename_alloc)
grub_free (filename);
}
-
+
offset += dirent.len;
}
-
+
return 0;
}
\f
static grub_err_t
-grub_iso9660_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_iso9660_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_iso9660_data *data = 0;
struct grub_fshelp_node rootnode;
struct grub_fshelp_node *foundnode;
-
+
auto int NESTED_FUNC_ATTR iterate (const char *filename,
enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node);
data = grub_iso9660_mount (device->disk);
if (! data)
goto fail;
-
+
rootnode.data = data;
rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
-
+
/* Use the fshelp function to traverse the path. */
if (grub_fshelp_find_file (path, &rootnode,
&foundnode,
grub_iso9660_read_symlink,
GRUB_FSHELP_DIR))
goto fail;
-
+
/* List the files in the directory. */
grub_iso9660_iterate_dir (foundnode, iterate);
-
+
if (foundnode != &rootnode)
grub_free (foundnode);
-
+
fail:
grub_free (data);
struct grub_iso9660_data *data;
struct grub_fshelp_node rootnode;
struct grub_fshelp_node *foundnode;
-
+
grub_dl_ref (my_mod);
data = grub_iso9660_mount (file->device->disk);
if (!data)
goto fail;
-
+
rootnode.data = data;
rootnode.blk = grub_le_to_cpu32 (data->voldesc.rootdir.first_sector);
rootnode.size = grub_le_to_cpu32 (data->voldesc.rootdir.size);
-
+
/* Use the fshelp function to traverse the path. */
if (grub_fshelp_find_file (name, &rootnode,
&foundnode,
grub_iso9660_read_symlink,
GRUB_FSHELP_REG))
goto fail;
-
+
data->first_sector = foundnode->blk;
data->length = foundnode->size;
-
+
file->data = data;
file->size = foundnode->size;
file->offset = 0;
-
+
return 0;
-
+
fail:
grub_dl_unref (my_mod);
-
+
grub_free (data);
-
+
return grub_errno;;
}
static grub_ssize_t
grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_iso9660_data *data =
+ struct grub_iso9660_data *data =
(struct grub_iso9660_data *) file->data;
-
+
/* XXX: The file is stored in as a single extent. */
- data->disk->read_hook = file->read_hook;
+ data->disk->read_hook = file->read_hook;
grub_disk_read (data->disk,
data->first_sector << GRUB_ISO9660_LOG2_BLKSZ,
file->offset,
len, buf);
data->disk->read_hook = 0;
-
+
return len;
}
grub_iso9660_close (grub_file_t file)
{
grub_free (file->data);
-
+
grub_dl_unref (my_mod);
-
+
return GRUB_ERR_NONE;
}
{
struct grub_iso9660_data *data;
data = grub_iso9660_mount (device->disk);
-
+
if (data)
{
if (data->joliet)
grub_error (GRUB_ERR_BAD_NUMBER, "No creation date in filesystem to generate UUID.");
*uuid = NULL;
}
- else
+ else
{
*uuid = grub_malloc (sizeof ("YYYY-MM-DD-HH-mm-ss-hh"));
grub_sprintf (*uuid, "%c%c%c%c-%c%c-%c%c-%c%c-%c%c-%c%c-%c%c",
- data->voldesc.modified.year[0], data->voldesc.modified.year[1],
+ data->voldesc.modified.year[0], data->voldesc.modified.year[1],
data->voldesc.modified.year[2], data->voldesc.modified.year[3],
data->voldesc.modified.month[0], data->voldesc.modified.month[1],
data->voldesc.modified.day[0], data->voldesc.modified.day[1],
grub_uint8_t magic[4];
grub_uint32_t version;
grub_uint64_t ag_size;
-
+
/* The size of a filesystem block in bytes. XXX: currently only
4096 was tested. */
grub_uint32_t blksz;
grub_uint16_t log2_blksz;
-
+
grub_uint8_t unused[71];
- grub_uint8_t volname[11];
+ grub_uint8_t volname[11];
};
struct grub_jfs_extent
/* The length of the extent in filesystem blocks. */
grub_uint16_t length;
grub_uint8_t length2;
-
+
/* The physical offset of the first block on the disk. */
grub_uint8_t blk1;
grub_uint32_t blk2;
{
grub_uint64_t next;
grub_uint64_t prev;
-
- grub_uint8_t flags;
+
+ grub_uint8_t flags;
grub_uint8_t unused;
-
+
grub_uint16_t count;
grub_uint16_t max;
grub_uint8_t unused2[10];
/* The offset is the key used to lookup an extent. */
grub_uint8_t offset1;
grub_uint32_t offset2;
-
+
struct grub_jfs_extent extent;
} __attribute__ ((packed));
this level. */
grub_uint64_t nextb;
grub_uint64_t prevb;
-
+
grub_uint8_t flags;
-
+
/* The amount of dirents in this node. */
grub_uint8_t count;
grub_uint8_t freecnt;
grub_uint8_t freelist;
grub_uint8_t maxslot;
-
+
/* The location of the sorted array of pointers to dirents. */
grub_uint8_t sindex;
grub_uint8_t unused[10];
grub_uint32_t mode;
grub_uint8_t unused3[72];
grub_uint8_t unused4[96];
-
+
union
{
/* The tree describing the extents of the file. */
{
grub_uint8_t unused[16];
grub_uint8_t flags;
-
+
/* Amount of dirents in this node. */
grub_uint8_t count;
grub_uint8_t freecnt;
char *sorted;
struct grub_jfs_leaf_dirent *leaf;
struct grub_jfs_leaf_next_dirent *next_leaf;
-
+
/* The filename and inode of the last read dirent. */
char name[255];
grub_uint32_t ino;
{
auto int getblk (struct grub_jfs_treehead *treehead,
struct grub_jfs_tree_extent *extents);
-
+
int getblk (struct grub_jfs_treehead *treehead,
struct grub_jfs_tree_extent *extents)
{
int found = -1;
int i;
-
+
for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++)
{
if (treehead->flags & GRUB_JFS_TREE_LEAF)
{
/* Read the leafnode. */
- if (grub_le_to_cpu32 (extents[i].offset2) <= blk
+ if (grub_le_to_cpu32 (extents[i].offset2) <= blk
&& ((grub_le_to_cpu16 (extents[i].extent.length))
+ (extents[i].extent.length2 << 8)
+ grub_le_to_cpu32 (extents[i].offset2)) > blk)
if (blk >= grub_le_to_cpu32 (extents[i].offset2))
found = i;
}
-
+
if (found != -1)
{
struct
struct grub_jfs_treehead treehead;
struct grub_jfs_tree_extent extents[254];
} tree;
-
+
if (grub_disk_read (data->disk,
grub_le_to_cpu32 (extents[found].extent.blk2)
<< (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS), 0,
sizeof (tree), (char *) &tree))
return -1;
-
+
return getblk (&tree.treehead, &tree.extents[0]);
}
-
+
return -1;
}
-
+
return getblk (&inode->file.tree, &inode->file.extents[0]);
}
- GRUB_DISK_SECTOR_BITS), 0,
sizeof (struct grub_jfs_iag), &iag))
return grub_errno;
-
+
inoblk = grub_le_to_cpu32 (iag.inodes[inoext].blk2);
inoblk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS);
inoblk += inonum;
-
+
if (grub_disk_read (data->disk, inoblk, 0,
sizeof (struct grub_jfs_inode), inode))
return grub_errno;
if (grub_disk_read (disk, GRUB_JFS_SBLOCK, 0,
sizeof (struct grub_jfs_sblock), &data->sblock))
goto fail;
-
+
if (grub_strncmp ((char *) (data->sblock.magic), "JFS1", 4))
{
grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem");
goto fail;
}
-
+
data->disk = disk;
data->pos = 0;
data->linknest = 0;
if (grub_disk_read (data->disk, GRUB_JFS_FS1_INODE_BLK, 0,
sizeof (struct grub_jfs_inode), &data->fileset))
goto fail;
-
+
return data;
-
+
fail:
grub_free (data);
-
+
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not a jfs filesystem");
-
+
return 0;
}
struct grub_jfs_internal_dirent *de;
struct grub_jfs_diropen *diro;
int blk;
-
+
de = (struct grub_jfs_internal_dirent *) inode->dir.dirents;
-
+
if (!((grub_le_to_cpu32 (inode->mode)
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR))
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
return 0;
}
-
+
diro = grub_malloc (sizeof (struct grub_jfs_diropen));
if (!diro)
return 0;
-
+
diro->index = 0;
diro->data = data;
diro->inode = inode;
grub_free (diro);
return 0;
}
-
+
blk = grub_le_to_cpu32 (de[inode->dir.header.sorted[0]].ex.blk2);
blk <<= (grub_le_to_cpu16 (data->sblock.log2_blksz) - GRUB_DISK_SECTOR_BITS);
-
+
/* Read in the nodes until we are on the leaf node level. */
do
{
diro->next_leaf = diro->dirpage->next_dirent;
diro->sorted = &diro->dirpage->sorted[diro->dirpage->header.sindex * 32];
diro->count = diro->dirpage->header.count;
-
+
return diro;
}
int len;
int nextent;
grub_uint16_t filename[255];
-
+
auto void addstr (grub_uint16_t *uname, int ulen);
-
+
/* Add the unicode string to the utf16 filename buffer. */
void addstr (grub_uint16_t *name, int ulen)
{
while (ulen--)
filename[strpos++] = *(name++);
}
-
+
/* The last node, read in more. */
if (diro->index == diro->count)
{
unsigned int next;
-
+
/* If the inode contains the entry tree or if this was the last
node, there is nothing to read. */
if ((diro->inode->file.tree.flags & GRUB_JFS_TREE_LEAF)
|| !grub_le_to_cpu64 (diro->dirpage->header.nextb))
return GRUB_ERR_OUT_OF_RANGE;
-
+
next = grub_le_to_cpu64 (diro->dirpage->header.nextb);
next <<= (grub_le_to_cpu16 (diro->data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS);
-
+
if (grub_disk_read (diro->data->disk, next, 0,
grub_le_to_cpu32 (diro->data->sblock.blksz),
diro->dirpage->sorted))
leaf = &diro->leaf[(int) diro->sorted[diro->index]];
next_leaf = &diro->next_leaf[diro->index];
-
+
len = leaf->len;
if (!len)
{
diro->index++;
return grub_jfs_getent (diro);
}
-
+
addstr (leaf->namepart, len < 11 ? len : 11);
diro->ino = grub_le_to_cpu32 (leaf->inode);
len -= 11;
-
+
/* Move down to the leaf level. */
nextent = leaf->next;
if (leaf->next != 255)
{
next_leaf = &diro->next_leaf[nextent];
addstr (next_leaf->namepart, len < 15 ? len : 15 );
-
+
len -= 15;
nextent = next_leaf->next;
} while (next_leaf->next != 255 && len > 0);
/* Convert the temporary UTF16 filename to UTF8. */
*grub_utf16_to_utf8 ((grub_uint8_t *) (diro->name), filename, strpos) = '\0';
-
+
return 0;
}
blockcnt = ((len + pos + grub_le_to_cpu32 (data->sblock.blksz) - 1)
/ grub_le_to_cpu32 (data->sblock.blksz));
-
+
for (i = pos / grub_le_to_cpu32 (data->sblock.blksz); i < blockcnt; i++)
{
int blknr;
int blockoff = pos % grub_le_to_cpu32 (data->sblock.blksz);
int blockend = grub_le_to_cpu32 (data->sblock.blksz);
-
+
int skipfirst = 0;
-
+
blknr = grub_jfs_blkno (data, &data->currinode, i);
if (grub_errno)
return -1;
if (i == blockcnt - 1)
{
blockend = (len + pos) % grub_le_to_cpu32 (data->sblock.blksz);
-
+
if (!blockend)
blockend = grub_le_to_cpu32 (data->sblock.blksz);
}
-
+
/* First block. */
if (i == (pos / (int) grub_le_to_cpu32 (data->sblock.blksz)))
{
skipfirst = blockoff;
blockend -= skipfirst;
}
-
+
data->disk->read_hook = read_hook;
grub_disk_read (data->disk,
blknr << (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS),
skipfirst, blockend, buf);
-
+
data->disk->read_hook = 0;
if (grub_errno)
return -1;
-
+
buf += grub_le_to_cpu32 (data->sblock.blksz) - skipfirst;
}
-
+
return len;
}
char *next;
unsigned int pos = 0;
struct grub_jfs_diropen *diro;
-
+
grub_strncpy (fpath, path, grub_strlen (path) + 1);
-
+
if (grub_jfs_read_inode (data, GRUB_JFS_AGGR_INODE, &data->currinode))
return grub_errno;
diro = grub_jfs_opendir (data, &data->currinode);
if (!diro)
return grub_errno;
-
+
for (;;)
{
if (grub_strlen (name) == 0)
return GRUB_ERR_NONE;
-
+
if (grub_jfs_getent (diro) == GRUB_ERR_OUT_OF_RANGE)
break;
-
+
/* Check if the current direntry matches the current part of the
pathname. */
if (!grub_strcmp (name, diro->name))
{
int ino = diro->ino;
int dirino = grub_le_to_cpu32 (data->currinode.inode);
-
+
grub_jfs_closedir (diro);
diro = 0;
-
+
if (grub_jfs_read_inode (data, ino, &data->currinode))
break;
-
+
/* Check if this is a symlink. */
if ((grub_le_to_cpu32 (data->currinode.mode)
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_LNK)
if (grub_errno)
return grub_errno;
}
-
+
if (!next)
return 0;
pos = 0;
-
+
name = next;
next = grub_strchr (name, '/');
if (next)
next[0] = '\0';
next++;
}
-
+
/* Open this directory for reading dirents. */
diro = grub_jfs_opendir (data, &data->currinode);
if (!diro)
return grub_errno;
-
+
continue;
}
}
if (++data->linknest > GRUB_JFS_MAX_SYMLNK_CNT)
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
-
+
if (size <= 128)
grub_strncpy (symlink, (char *) (data->currinode.symlink.path), 128);
else if (grub_jfs_read_file (data, 0, 0, size, symlink) < 0)
return grub_errno;
symlink[size] = '\0';
-
+
/* The symlink is an absolute path, go back to the root inode. */
if (symlink[0] == '/')
ino = 2;
-
+
/* Now load in the old inode. */
if (grub_jfs_read_inode (data, ino, &data->currinode))
return grub_errno;
-
+
grub_jfs_find_file (data, symlink);
if (grub_errno)
grub_error (grub_errno, "Can not follow symlink `%s'.", symlink);
-
+
return grub_errno;
}
\f
static grub_err_t
-grub_jfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_jfs_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_jfs_data *data = 0;
if (grub_jfs_find_file (data, path))
goto fail;
-
+
diro = grub_jfs_opendir (data, &data->currinode);
if (!diro)
goto fail;
struct grub_jfs_inode inode;
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
-
+
if (grub_jfs_read_inode (data, diro->ino, &inode))
goto fail;
-
+
info.dir = (grub_le_to_cpu32 (inode.mode)
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_DIR;
if (hook (diro->name, &info))
goto fail;
}
-
+
/* XXX: GRUB_ERR_OUT_OF_RANGE is used for the last dirent. */
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_errno = 0;
data = grub_jfs_mount (file->device->disk);
if (!data)
goto fail;
-
+
grub_jfs_find_file (data, name);
if (grub_errno)
goto fail;
-
+
/* It is only possible for open regular files. */
if (! ((grub_le_to_cpu32 (data->currinode.mode)
& GRUB_JFS_FILETYPE_MASK) == GRUB_JFS_FILETYPE_REG))
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a regular file");
goto fail;
}
-
+
file->data = data;
file->size = grub_le_to_cpu64 (data->currinode.size);
-
+
return 0;
-
+
fail:
grub_dl_unref (my_mod);
-
+
grub_free (data);
-
+
return grub_errno;;
}
static grub_ssize_t
grub_jfs_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_jfs_data *data =
+ struct grub_jfs_data *data =
(struct grub_jfs_data *) file->data;
-
+
return grub_jfs_read_file (data, file->read_hook, file->offset, len, buf);
}
grub_jfs_close (grub_file_t file)
{
grub_free (file->data);
-
+
grub_dl_unref (my_mod);
-
+
return GRUB_ERR_NONE;
}
{
struct grub_jfs_data *data;
data = grub_jfs_mount (device->disk);
-
+
if (data)
*label = grub_strndup ((char *) (data->sblock.volname), 11);
else
*label = 0;
-
+
return grub_errno;
}
\f
grub_uint32_t indir_zone;
grub_uint32_t double_indir_zone;
grub_uint32_t unused;
-
+
};
/* Information about a "mounted" minix filesystem. */
return grub_le_to_cpu32 (indir32);
}
}
-
+
/* Direct block. */
if (blk < 7)
return GRUB_MINIX_INODE_DIR_ZONES (data, blk);
-
+
/* Indirect block. */
blk -= 7;
if (blk < GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
indir = grub_get_indir (GRUB_MINIX_INODE_INDIR_ZONE (data), blk);
return indir;
}
-
+
/* Double indirect block. */
blk -= GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data);
if (blk < (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data))
* (GRUB_MINIX_ZONESZ / GRUB_MINIX_INODE_BLKSZ (data)))
{
- indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
+ indir = grub_get_indir (GRUB_MINIX_INODE_DINDIR_ZONE (data),
blk / GRUB_MINIX_ZONESZ);
-
+
indir = grub_get_indir (indir, blk % GRUB_MINIX_ZONESZ);
-
+
return indir;
}
-
+
/* This should never happen. */
grub_error (GRUB_ERR_OUT_OF_RANGE, "file bigger than maximum size");
-
+
return 0;
}
len = GRUB_MINIX_INODE_SIZE (data);
blockcnt = (len + pos + GRUB_MINIX_BSIZE - 1) / GRUB_MINIX_BSIZE;
-
+
for (i = pos / GRUB_MINIX_BSIZE; i < blockcnt; i++)
{
int blknr;
int blockoff = pos % GRUB_MINIX_BSIZE;
int blockend = GRUB_MINIX_BSIZE;
-
+
int skipfirst = 0;
-
+
blknr = grub_minix_get_file_block (data, i);
if (grub_errno)
return -1;
-
+
/* Last block. */
if (i == blockcnt - 1)
{
blockend = (len + pos) % GRUB_MINIX_BSIZE;
-
+
if (!blockend)
blockend = GRUB_MINIX_BSIZE;
}
-
+
/* First block. */
if (i == (pos / (int) GRUB_MINIX_BSIZE))
{
skipfirst = blockoff;
blockend -= skipfirst;
}
-
+
data->disk->read_hook = read_hook;
grub_disk_read (data->disk, blknr << GRUB_MINIX_LOG2_ZONESZ,
skipfirst, blockend, buf);
-
+
data->disk->read_hook = 0;
if (grub_errno)
return -1;
-
+
buf += GRUB_MINIX_BSIZE - skipfirst;
}
-
+
return len;
}
/* The first inode in minix is inode 1. */
ino--;
-
+
block = ((2 + grub_le_to_cpu16 (sblock->inode_bmap_size)
+ grub_le_to_cpu16 (sblock->zone_bmap_size))
<< GRUB_MINIX_LOG2_BSIZE);
-
+
if (data->version == 1)
{
block += ino / (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix_inode));
- int offs = (ino % (GRUB_DISK_SECTOR_SIZE
+ int offs = (ino % (GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_minix_inode))
* sizeof (struct grub_minix_inode));
-
+
grub_disk_read (data->disk, block, offs,
sizeof (struct grub_minix_inode), &data->inode);
}
else
{
- block += ino / (GRUB_DISK_SECTOR_SIZE
+ block += ino / (GRUB_DISK_SECTOR_SIZE
/ sizeof (struct grub_minix2_inode));
- int offs = (ino
+ int offs = (ino
% (GRUB_DISK_SECTOR_SIZE / sizeof (struct grub_minix2_inode))
* sizeof (struct grub_minix2_inode));
-
+
grub_disk_read (data->disk, block, offs,
sizeof (struct grub_minix2_inode),&data->inode2);
}
-
+
return GRUB_ERR_NONE;
}
grub_minix_lookup_symlink (struct grub_minix_data *data, int ino)
{
char symlink[GRUB_MINIX_INODE_SIZE (data) + 1];
-
+
if (++data->linknest > GRUB_MINIX_MAX_SYMLNK_CNT)
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
-
+
if (grub_minix_read_file (data, 0, 0,
GRUB_MINIX_INODE_SIZE (data), symlink) < 0)
return grub_errno;
symlink[GRUB_MINIX_INODE_SIZE (data)] = '\0';
-
+
/* The symlink is an absolute path, go back to the root inode. */
if (symlink[0] == '/')
ino = GRUB_MINIX_ROOT_INODE;
-
+
/* Now load in the old inode. */
if (grub_minix_read_inode (data, ino))
return grub_errno;
-
+
grub_minix_find_file (data, symlink);
if (grub_errno)
grub_error (grub_errno, "Can not follow symlink `%s'.", symlink);
-
+
return grub_errno;
}
char *next;
unsigned int pos = 0;
int dirino;
-
+
grub_strcpy (fpath, path);
-
+
/* Skip the first slash. */
if (name[0] == '/')
{
next[0] = '\0';
next++;
}
-
+
do
{
grub_uint16_t ino;
char filename[data->filename_size + 1];
-
+
if (grub_strlen (name) == 0)
return GRUB_ERR_NONE;
-
+
if (grub_minix_read_file (data, 0, pos, sizeof (ino),
(char *) &ino) < 0)
return grub_errno;
return grub_errno;
filename[data->filename_size] = '\0';
-
+
/* Check if the current direntry matches the current part of the
pathname. */
if (!grub_strcmp (name, filename))
{
dirino = data->ino;
grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
-
+
/* Follow the symlink. */
- if ((GRUB_MINIX_INODE_MODE (data)
+ if ((GRUB_MINIX_INODE_MODE (data)
& GRUB_MINIX_IFLNK) == GRUB_MINIX_IFLNK)
{
grub_minix_lookup_symlink (data, dirino);
if (grub_errno)
return grub_errno;
}
-
+
if (!next)
return 0;
-
+
pos = 0;
-
+
name = next;
next = grub_strchr (name, '/');
if (next)
next[0] = '\0';
next++;
}
-
+
if ((GRUB_MINIX_INODE_MODE (data)
& GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
+
continue;
}
-
+
pos += sizeof (ino) + data->filename_size;
} while (pos < GRUB_MINIX_INODE_SIZE (data));
-
+
grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
return grub_errno;
}
grub_minix_mount (grub_disk_t disk)
{
struct grub_minix_data *data;
-
+
data = grub_malloc (sizeof (struct grub_minix_data));
if (!data)
return 0;
-
+
/* Read the superblock. */
grub_disk_read (disk, GRUB_MINIX_SBLOCK, 0,
sizeof (struct grub_minix_sblock),&data->sblock);
}
\f
static grub_err_t
-grub_minix_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_minix_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_minix_data *data = 0;
struct grub_minix_sblock *sblock;
unsigned int pos = 0;
-
+
data = grub_minix_mount (device->disk);
if (!data)
return grub_errno;
-
+
grub_minix_read_inode (data, GRUB_MINIX_ROOT_INODE);
if (grub_errno)
goto fail;
-
+
sblock = &data->sblock;
grub_minix_find_file (data, path);
if (grub_errno)
goto fail;
-
+
if ((GRUB_MINIX_INODE_MODE (data) & GRUB_MINIX_IFDIR) != GRUB_MINIX_IFDIR)
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
goto fail;
}
-
+
while (pos < GRUB_MINIX_INODE_SIZE (data))
{
grub_uint16_t ino;
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
-
+
if (grub_minix_read_file (data, 0, pos, sizeof (ino),
(char *) &ino) < 0)
return grub_errno;
-
+
if (grub_minix_read_file (data, 0, pos + sizeof (ino),
data->filename_size,
(char *) filename) < 0)
return grub_errno;
filename[data->filename_size] = '\0';
-
+
/* The filetype is not stored in the dirent. Read the inode to
find out the filetype. This *REALLY* sucks. */
grub_minix_read_inode (data, grub_le_to_cpu16 (ino));
- info.dir = ((GRUB_MINIX_INODE_MODE (data)
+ info.dir = ((GRUB_MINIX_INODE_MODE (data)
& GRUB_MINIX_IFDIR) == GRUB_MINIX_IFDIR);
if (hook (filename, &info) ? 1 : 0)
break;
-
+
/* Load the old inode back in. */
grub_minix_read_inode (data, dirino);
pos += sizeof (ino) + data->filename_size;
}
-
+
fail:
grub_free (data);
return grub_errno;
grub_free (data);
return grub_errno;
}
-
+
if (!name || name[0] != '/')
{
grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
return grub_errno;
}
-
+
/* Traverse the directory tree to the node that should be
opened. */
grub_minix_find_file (data, name);
grub_free (data);
return grub_errno;
}
-
+
file->data = data;
file->size = GRUB_MINIX_INODE_SIZE (data);
-
+
return GRUB_ERR_NONE;
}
static grub_ssize_t
grub_minix_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_minix_data *data =
+ struct grub_minix_data *data =
(struct grub_minix_data *) file->data;
-
+
return grub_minix_read_file (data, file->read_hook, file->offset, len, buf);
}
grub_minix_close (grub_file_t file)
{
grub_free (file->data);
-
+
return GRUB_ERR_NONE;
}
static grub_err_t
grub_ntfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_ntfs_data *data = 0;
"any ",
"unknown "
};
-
+
for (a = 0; a < sizeof (struct grub_reiserfs_key); a++)
grub_printf ("%02x ", ((unsigned int) ((unsigned char *) key)[a]) & 0xFF);
grub_printf ("parent id = 0x%08x, self id = 0x%08x, type = %s, offset = ",
int version)
{
grub_uint32_t type;
-
+
switch (grub_type)
{
case GRUB_REISERFS_STAT:
default:
return;
}
-
+
if (version == 1)
key->u.v1.type = grub_cpu_to_le32 (type);
else
key->u.v2.offset_type
= ((key->u.v2.offset_type & grub_cpu_to_le64 (~0ULL >> 4))
| grub_cpu_to_le64 ((grub_uint64_t) type << 60));
-
+
assert (grub_reiserfs_get_key_type (key) == grub_type);
}
grub_uint64_t offset1, offset2;
enum grub_reiserfs_item_type type1, type2;
grub_uint32_t id1, id2;
-
+
if (! key1 || ! key2)
return -2;
-
+
id1 = grub_le_to_cpu32 (key1->directory_id);
id2 = grub_le_to_cpu32 (key2->directory_id);
if (id1 < id2)
return -1;
if (id1 > id2)
return 1;
-
+
id1 = grub_le_to_cpu32 (key1->object_id);
id2 = grub_le_to_cpu32 (key2->object_id);
if (id1 < id2)
return -1;
if (id1 > id2)
return 1;
-
+
offset1 = grub_reiserfs_get_key_offset (key1);
offset2 = grub_reiserfs_get_key_offset (key2);
if (offset1 < offset2)
return -1;
if (offset1 > offset2)
return 1;
-
+
type1 = grub_reiserfs_get_key_type (key1);
type2 = grub_reiserfs_get_key_type (key2);
if ((type1 == GRUB_REISERFS_ANY
return -1;
if (type1 > type2)
return 1;
-
+
return 0;
}
grub_uint16_t i;
grub_uint16_t previous_level = ~0;
struct grub_reiserfs_item_header *item_headers = 0;
-
+
if (! data)
{
grub_error (GRUB_ERR_TEST_FAILURE, "data is NULL");
grub_error (GRUB_ERR_TEST_FAILURE, "item is NULL");
goto fail;
}
-
+
block_size = grub_le_to_cpu16 (data->superblock.block_size);
block_number = grub_le_to_cpu32 (data->superblock.root_block);
#ifdef GRUB_REISERFS_DEBUG
block_header = grub_malloc (block_size);
if (! block_header)
goto fail;
-
+
item->next_offset = 0;
do
{
struct grub_reiserfs_disk_child *children
= ((struct grub_reiserfs_disk_child *)
(keys + item_count));
-
+
for (i = 0;
i < item_count
&& grub_reiserfs_compare_keys (key, &(keys[i])) >= 0;
grub_reiserfs_print_key (block_key);
#endif
}
-
+
assert (grub_errno == GRUB_ERR_NONE);
grub_free (block_header);
return GRUB_ERR_NONE;
struct grub_fshelp_node directory_item;
grub_uint16_t entry_count, entry_number;
struct grub_reiserfs_item_header *item_headers;
-
+
grub_disk_read (data->disk,
block_number * (block_size >> GRUB_DISK_SECTOR_BITS),
(((grub_off_t) block_number * block_size)
goto fail;
}
#endif
-
+
item_headers = (struct grub_reiserfs_item_header *) (block_header + 1);
directory_headers
= ((struct grub_reiserfs_directory_header *)
= &directory_headers[entry_number];
grub_uint16_t entry_state
= grub_le_to_cpu16 (directory_header->state);
-
+
if (entry_state & GRUB_REISERFS_VISIBLE_MASK)
{
grub_fshelp_node_t entry_item;
entry_item = grub_malloc (sizeof (*entry_item));
if (! entry_item)
goto fail;
-
+
if (grub_reiserfs_get_item (data, &entry_key, entry_item)
!= GRUB_ERR_NONE)
{
grub_free (entry_item);
goto fail;
}
-
+
if (entry_item->type == GRUB_REISERFS_DIRECTORY)
entry_type = GRUB_FSHELP_DIR;
else
the current one. */
}
}
-
+
if (next_offset == 0)
break;
while (current_position < final_position)
{
grub_reiserfs_set_key_offset (&key, current_key_offset);
-
+
if (grub_reiserfs_get_item (data, &key, &found) != GRUB_ERR_NONE)
goto fail;
if (found.block_number == 0)
}
current_key_offset = current_position + 1;
}
-
+
grub_dprintf ("reiserfs",
"Have successfully read %lld bytes (%ld requested)\n",
(unsigned long long) (current_position - initial_position),
/* Call HOOK with each file under DIR. */
static grub_err_t
grub_reiserfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_reiserfs_data *data = 0;
/* We found a correct leaf. */
*size = grub_be_to_cpu16 (extent->size);
*nextext = grub_be_to_cpu32 (extent->next);
-
+
grub_free (treeblock);
return 0;
}
node->data = data;
node->size = size;
node->block = block;
-
+
return hook (name, type, node);
}
{
struct grub_sfs_data *data;
struct grub_fshelp_node *fdiro = 0;
-
+
grub_dl_ref (my_mod);
-
+
data = grub_sfs_mount (file->device->disk);
if (!data)
goto fail;
-
+
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_sfs_iterate_dir,
grub_sfs_read_symlink, GRUB_FSHELP_REG);
if (grub_errno)
goto fail;
-
+
file->size = fdiro->size;
data->diropen = *fdiro;
grub_free (fdiro);
if (data)
grub_free (data->label);
grub_free (data);
-
+
grub_dl_unref (my_mod);
return grub_errno;
static grub_err_t
-grub_sfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_sfs_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_sfs_data *data = 0;
struct grub_fshelp_node *fdiro = 0;
-
+
auto int NESTED_FUNC_ATTR iterate (const char *filename,
enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node);
}
grub_dl_ref (my_mod);
-
+
data = grub_sfs_mount (device->disk);
if (!data)
goto fail;
goto fail;
grub_sfs_iterate_dir (fdiro, iterate);
-
+
fail:
if (data && fdiro != &data->diropen)
grub_free (fdiro);
static grub_err_t
grub_udf_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_udf_data *data = 0;
grub_uint8_t unused[16];
/* The offset of the inodes in the cylinder group. */
grub_uint32_t inoblk_offs;
-
+
grub_uint8_t unused2[4];
-
+
/* The start of the cylinder group. */
grub_uint32_t cylg_offset;
grub_uint8_t unused3[4];
grub_uint32_t mtime;
grub_uint8_t unused4[12];
-
+
/* The size of a block in bytes. */
grub_int32_t bsize;
grub_uint8_t unused5[48];
-
+
/* The size of filesystem blocks to disk blocks. */
grub_uint32_t log2_blksz;
grub_uint8_t unused6[80];
-
+
/* Inodes stored per cylinder group. */
grub_uint32_t ino_per_group;
-
+
/* The frags per cylinder group. */
grub_uint32_t frags_per_group;
-
+
grub_uint8_t unused7[488];
/* Volume name for UFS2. */
grub_uint64_t mtime2;
grub_uint8_t unused9[420];
-
+
/* Magic value to check if this is really a UFS filesystem. */
grub_uint32_t magic;
};
struct
{
grub_uint8_t filetype_bsd;
- grub_uint8_t namelen_bsd;
+ grub_uint8_t namelen_bsd;
};
};
} __attribute__ ((packed));
{
struct grub_ufs_sblock *sblock = &data->sblock;
unsigned int indirsz;
- int log2_blksz;
-
+ int log2_blksz;
+
/* Direct. */
if (blk < GRUB_UFS_DIRBLKS)
return INODE_DIRBLOCKS (data, blk);
-
+
log2_blksz = grub_le_to_cpu32 (data->sblock.log2_blksz);
-
+
blk -= GRUB_UFS_DIRBLKS;
-
+
indirsz = UFS_BLKSZ (sblock) / INODE_BLKSZ (data);
/* Single indirect block. */
if (blk < indirsz)
return (data->ufs_type == UFS1) ? indir[blk] : indir[blk << 1];
}
blk -= indirsz;
-
+
/* Double indirect block. */
if (blk < indirsz * indirsz)
{
grub_uint32_t indir[UFS_BLKSZ (sblock) >> 2];
-
+
grub_disk_read (data->disk, INODE_INDIRBLOCKS (data, 1) << log2_blksz,
0, sizeof (indir), indir);
grub_disk_read (data->disk,
((data->ufs_type == UFS1) ?
- indir[blk / indirsz] : indir [(blk / indirsz) << 1])
+ indir[blk / indirsz] : indir [(blk / indirsz) << 1])
<< log2_blksz,
0, sizeof (indir), indir);
-
+
return (data->ufs_type == UFS1) ?
indir[blk % indirsz] : indir[(blk % indirsz) << 1];
}
len = INODE_SIZE (data);
blockcnt = (len + pos + UFS_BLKSZ (sblock) - 1) / UFS_BLKSZ (sblock);
-
+
for (i = pos / UFS_BLKSZ (sblock); i < blockcnt; i++)
{
int blknr;
int blockoff = pos % UFS_BLKSZ (sblock);
int blockend = UFS_BLKSZ (sblock);
-
+
int skipfirst = 0;
-
+
blknr = grub_ufs_get_file_block (data, i);
if (grub_errno)
return -1;
-
+
/* Last block. */
if (i == blockcnt - 1)
{
blockend = (len + pos) % UFS_BLKSZ (sblock);
-
+
if (!blockend)
blockend = UFS_BLKSZ (sblock);
}
-
+
/* First block. */
if (i == (pos / (int) UFS_BLKSZ (sblock)))
{
skipfirst = blockoff;
blockend -= skipfirst;
}
-
+
/* XXX: If the block number is 0 this block is not stored on
disk but is zero filled instead. */
if (blknr)
buf += UFS_BLKSZ (sblock) - skipfirst;
}
-
+
return len;
}
grub_ufs_read_inode (struct grub_ufs_data *data, int ino, char *inode)
{
struct grub_ufs_sblock *sblock = &data->sblock;
-
+
/* Determine the group the inode is in. */
int group = ino / grub_le_to_cpu32 (sblock->ino_per_group);
-
+
/* Determine the inode within the group. */
int grpino = ino % grub_le_to_cpu32 (sblock->ino_per_group);
-
+
/* The first block of the group. */
int grpblk = group * (grub_le_to_cpu32 (sblock->frags_per_group));
-
+
if (data->ufs_type == UFS1)
{
if (!inode)
sizeof (struct grub_ufs2_inode),
inode);
}
-
+
return grub_errno;
}
grub_ufs_lookup_symlink (struct grub_ufs_data *data, int ino)
{
char symlink[INODE_SIZE (data)];
-
+
if (++data->linknest > GRUB_UFS_MAX_SYMLNK_CNT)
return grub_error (GRUB_ERR_SYMLINK_LOOP, "too deep nesting of symlinks");
-
+
if (INODE_NBLOCKS (data) == 0)
grub_strcpy (symlink, (char *) INODE (data, symlink));
else
{
- grub_disk_read (data->disk,
- (INODE_DIRBLOCKS (data, 0)
+ grub_disk_read (data->disk,
+ (INODE_DIRBLOCKS (data, 0)
<< grub_le_to_cpu32 (data->sblock.log2_blksz)),
0, INODE_SIZE (data), symlink);
symlink[INODE_SIZE (data)] = '\0';
/* The symlink is an absolute path, go back to the root inode. */
if (symlink[0] == '/')
ino = GRUB_UFS_INODE;
-
+
/* Now load in the old inode. */
if (grub_ufs_read_inode (data, ino, 0))
return grub_errno;
-
+
grub_ufs_find_file (data, symlink);
if (grub_errno)
grub_error (grub_errno, "Can not follow symlink `%s'.", symlink);
-
+
return grub_errno;
}
char *next;
unsigned int pos = 0;
int dirino;
-
+
grub_strcpy (fpath, path);
-
+
/* Skip the first slash. */
if (name[0] == '/')
{
next[0] = '\0';
next++;
}
-
+
do
{
struct grub_ufs_dirent dirent;
int namelen;
-
+
if (grub_strlen (name) == 0)
return GRUB_ERR_NONE;
-
+
if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
(char *) &dirent) < 0)
return grub_errno;
namelen = (data->ufs_type == UFS2)
? dirent.namelen_bsd : grub_le_to_cpu16 (dirent.namelen);
-
+
{
char filename[namelen + 1];
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
namelen, filename) < 0)
return grub_errno;
-
+
filename[namelen] = '\0';
-
+
if (!grub_strcmp (name, filename))
{
dirino = data->ino;
next[0] = '\0';
next++;
}
-
+
if ((INODE_MODE(data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
return grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
-
+
continue;
}
}
-
+
pos += grub_le_to_cpu16 (dirent.direntlen);
} while (pos < INODE_SIZE (data));
-
+
grub_error (GRUB_ERR_FILE_NOT_FOUND, "file not found");
return grub_errno;
}
{
struct grub_ufs_data *data;
int *sblklist = sblocklist;
-
+
data = grub_malloc (sizeof (struct grub_ufs_data));
if (!data)
return 0;
-
+
/* Find a UFS1 or UFS2 sblock. */
data->ufs_type = UNKNOWN;
while (*sblklist != -1)
&data->sblock);
if (grub_errno)
goto fail;
-
+
if (grub_le_to_cpu32 (data->sblock.magic) == GRUB_UFS_MAGIC)
{
data->ufs_type = UFS1;
fail:
grub_free (data);
-
+
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not a ufs filesystem");
-
+
return 0;
}
static grub_err_t
-grub_ufs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_ufs_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_ufs_data *data;
data = grub_ufs_mount (device->disk);
if (!data)
return grub_errno;
-
+
grub_ufs_read_inode (data, GRUB_UFS_INODE, 0);
if (grub_errno)
return grub_errno;
-
+
sblock = &data->sblock;
-
+
if (!path || path[0] != '/')
{
grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
return grub_errno;
}
-
+
grub_ufs_find_file (data, path);
if (grub_errno)
- goto fail;
-
+ goto fail;
+
if ((INODE_MODE (data) & GRUB_UFS_ATTR_TYPE) != GRUB_UFS_ATTR_DIR)
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, "not a directory");
goto fail;
}
-
+
while (pos < INODE_SIZE (data))
{
struct grub_ufs_dirent dirent;
int namelen;
-
+
if (grub_ufs_read_file (data, 0, pos, sizeof (dirent),
(char *) &dirent) < 0)
break;
namelen = (data->ufs_type == UFS2)
? dirent.namelen_bsd : grub_le_to_cpu16 (dirent.namelen);
-
+
{
char filename[namelen + 1];
struct grub_dirhook_info info;
grub_memset (&info, 0, sizeof (info));
-
+
if (grub_ufs_read_file (data, 0, pos + sizeof (dirent),
namelen, filename) < 0)
break;
-
+
filename[namelen] = '\0';
if (data->ufs_type == UFS1)
{
if (hook (filename, &info))
break;
}
-
+
pos += grub_le_to_cpu16 (dirent.direntlen);
}
data = grub_ufs_mount (file->device->disk);
if (!data)
return grub_errno;
-
+
grub_ufs_read_inode (data, 2, 0);
if (grub_errno)
{
grub_free (data);
return grub_errno;
}
-
+
if (!name || name[0] != '/')
{
grub_error (GRUB_ERR_BAD_FILENAME, "bad filename");
return grub_errno;
}
-
+
grub_ufs_find_file (data, name);
if (grub_errno)
{
grub_free (data);
return grub_errno;
}
-
+
file->data = data;
file->size = INODE_SIZE (data);
static grub_ssize_t
grub_ufs_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_ufs_data *data =
+ struct grub_ufs_data *data =
(struct grub_ufs_data *) file->data;
-
+
return grub_ufs_read_file (data, file->read_hook, file->offset, len, buf);
}
grub_ufs_close (grub_file_t file)
{
grub_free (file->data);
-
+
return GRUB_ERR_NONE;
}
}
/* Get mtime. */
-static grub_err_t
+static grub_err_t
grub_ufs_mtime (grub_device_t device, grub_int32_t *tm)
{
struct grub_ufs_data *data = 0;
grub_uint8_t unused2[8];
grub_uint64_t rootino;
grub_uint8_t unused3[20];
- grub_uint32_t agsize;
+ grub_uint32_t agsize;
grub_uint8_t unused4[20];
grub_uint8_t label[12];
grub_uint8_t log2_bsize;
{
struct grub_fshelp_node *diro = (struct grub_fshelp_node *) dir;
auto int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename);
-
+
int NESTED_FUNC_ATTR call_hook (grub_uint64_t ino, char *filename)
{
struct grub_fshelp_node *fdiro;
fdiro = grub_malloc (sizeof (struct grub_fshelp_node));
if (!fdiro)
return 0;
-
+
/* The inode should be read, otherwise the filetype can
not be determined. */
fdiro->ino = ino;
grub_xfs_mode_to_filetype (fdiro->inode.mode),
fdiro);
}
-
+
switch (diro->inode.format)
{
case XFS_INODE_FORMAT_INO:
+ sizeof (struct grub_xfs_dir_entry)
+ de->len - 1);
char name[de->len + 1];
-
+
if (smallino)
{
ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos);
if (call_hook (ino, name))
return 1;
- de = ((struct grub_xfs_dir_entry *)
+ de = ((struct grub_xfs_dir_entry *)
(((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
+ ((smallino ? sizeof (grub_uint32_t)
: sizeof (grub_uint64_t))) - 1));
/* Iterate over every block the directory has. */
for (blk = 0;
- blk < (grub_be_to_cpu64 (dir->inode.size)
+ blk < (grub_be_to_cpu64 (dir->inode.size)
>> dirblk_log2);
blk++)
{
if (grub_disk_read (disk, 0, 0,
sizeof (struct grub_xfs_sblock), &data->sblock))
goto fail;
-
+
if (grub_strncmp ((char *) (data->sblock.magic), "XFSB", 4))
{
grub_error (GRUB_ERR_BAD_FS, "not a xfs filesystem");
return data;
fail:
-
+
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not an xfs filesystem");
grub_free (data);
-
+
return 0;
}
\f
static grub_err_t
-grub_xfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_xfs_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
struct grub_xfs_data *data = 0;;
struct grub_fshelp_node *fdiro = 0;
-
+
auto int NESTED_FUNC_ATTR iterate (const char *filename,
enum grub_fshelp_filetype filetype,
grub_fshelp_node_t node);
}
grub_dl_ref (my_mod);
-
+
data = grub_xfs_mount (device->disk);
if (!data)
goto fail;
-
+
grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_xfs_iterate_dir,
grub_xfs_read_symlink, GRUB_FSHELP_DIR);
if (grub_errno)
goto fail;
grub_xfs_iterate_dir (fdiro, iterate);
-
+
fail:
if (fdiro != &data->diropen)
grub_free (fdiro);
{
struct grub_xfs_data *data;
struct grub_fshelp_node *fdiro = 0;
-
+
grub_dl_ref (my_mod);
-
+
data = grub_xfs_mount (file->device->disk);
if (!data)
goto fail;
-
+
grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_xfs_iterate_dir,
grub_xfs_read_symlink, GRUB_FSHELP_REG);
if (grub_errno)
goto fail;
-
+
if (!fdiro->inode_read)
{
grub_xfs_read_inode (data, fdiro->ino, &fdiro->inode);
if (grub_errno)
goto fail;
}
-
+
grub_memcpy (data->inode,
&fdiro->inode,
sizeof (struct grub_xfs_inode));
if (fdiro != &data->diropen)
grub_free (fdiro);
grub_free (data);
-
+
grub_dl_unref (my_mod);
return grub_errno;
static grub_ssize_t
grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
{
- struct grub_xfs_data *data =
+ struct grub_xfs_data *data =
(struct grub_xfs_data *) file->data;
return grub_xfs_read_file (&data->diropen, file->read_hook,
objs_str = objs.join(' ')
deps = objs.collect {|obj| obj.suffix('d')}
deps_str = deps.join(' ')
-
+
"CLEANFILES += #{@name} #{exe} #{objs_str}
MOSTLYCLEANFILES += #{deps_str}
flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
dir = File.dirname(src)
-
+
"#{obj}: #{src} $(#{src}_DEPENDENCIES)
$(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
-include #{dep}
undsym = 'und-' + @name.suffix('lst')
mod_name = File.basename(@name, '.mod')
symbolic_name = mod_name.sub(/\.[^\.]*$/, '')
-
+
"CLEANFILES += #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym}
ifneq ($(#{prefix}_EXPORTS),no)
CLEANFILES += #{defsym}
end
src = sources[0]
if /\.in$/ !~ src
- raise "unknown source file `#{src}'"
+ raise "unknown source file `#{src}'"
end
"CLEANFILES += #{@name}
cont = (/\\$/ =~ l)
unless cont
str.gsub!(/\\\n/, ' ')
-
+
if /^([a-zA-Z0-9_]+)\s*\+?=\s*(.*?)\s*$/ =~ str
var, args = $1, $2
pmodules += args.split(/\s+/).collect do |pmod|
PModule.new(prefix, pmod)
end
-
+
when 'UTILITIES'
utils += args.split(/\s+/).collect do |util|
Utility.new(prefix, util)
end
end
end
-
+
end
-
+
end
-
+
end
END {
if (error == 1)
exit 1;
-
+
for (mod in modtab) {
# Remove duplications.
split(modtab[mod], depmods, " ");
grub_uint8_t oemtable[8];
grub_uint32_t oemrev;
grub_uint8_t creator_id[4];
- grub_uint32_t creator_rev;
+ grub_uint32_t creator_rev;
} __attribute__ ((packed));
struct grub_acpi_fadt
# define SYSTEM_TABLE_SIZEOF GRUB_EFIEMU_SYSTEM_TABLE_SIZEOF
# define SYSTEM_TABLE_VAR GRUB_EFIEMU_SYSTEM_TABLE_VAR
# define SYSTEM_TABLE_PTR GRUB_EFIEMU_SYSTEM_TABLE_PTR
-# define SIZEOF_OF_UINTN GRUB_EFIEMU_SIZEOF_OF_UINTN
-# define SYSTEM_TABLE GRUB_EFIEMU_SYSTEM_TABLE
+# define SIZEOF_OF_UINTN GRUB_EFIEMU_SIZEOF_OF_UINTN
+# define SYSTEM_TABLE GRUB_EFIEMU_SYSTEM_TABLE
# define grub_efi_allocate_pages(x,y) (x)
# define grub_efi_free_pages(x,y) GRUB_EFI_SUCCESS
# define EFI_PRESENT 1
int grub_get_weekday (struct grub_datetime *datetime);
char *grub_get_weekday_name (struct grub_datetime *datetime);
-void grub_unixtime2datetime (grub_int32_t nix,
+void grub_unixtime2datetime (grub_int32_t nix,
struct grub_datetime *datetime);
/* The device id used by the cache manager. */
unsigned long id;
-
+
/* Call HOOK with each device name, until HOOK returns non-zero. */
int (*iterate) (int (*hook) (const char *name));
/* The id used by the disk cache manager. */
unsigned long id;
-
+
/* The partition information. This is machine-specific. */
struct grub_partition *partition;
struct grub_efi_boot_services
{
grub_efi_table_header_t hdr;
-
+
grub_efi_tpl_t
(*raise_tpl) (grub_efi_tpl_t new_tpl);
-
+
void
(*restore_tpl) (grub_efi_tpl_t old_tpl);
-
+
grub_efi_status_t
(*allocate_pages) (grub_efi_allocate_type_t type,
grub_efi_memory_type_t memory_type,
grub_efi_uintn_t pages,
grub_efi_physical_address_t *memory);
-
+
grub_efi_status_t
(*free_pages) (grub_efi_physical_address_t memory,
grub_efi_uintn_t pages);
-
+
grub_efi_status_t
(*get_memory_map) (grub_efi_uintn_t *memory_map_size,
grub_efi_memory_descriptor_t *memory_map,
grub_efi_uintn_t *map_key,
grub_efi_uintn_t *descriptor_size,
grub_efi_uint32_t *descriptor_version);
-
+
grub_efi_status_t
(*allocate_pool) (grub_efi_memory_type_t pool_type,
grub_efi_uintn_t size,
void **buffer);
-
+
grub_efi_status_t
(*free_pool) (void *buffer);
-
+
grub_efi_status_t
(*create_event) (grub_efi_uint32_t type,
grub_efi_tpl_t notify_tpl,
(*set_timer) (grub_efi_event_t event,
grub_efi_timer_delay_t type,
grub_efi_uint64_t trigger_time);
-
+
grub_efi_status_t
(*wait_for_event) (grub_efi_uintn_t num_events,
grub_efi_event_t *event,
grub_efi_status_t
(*signal_event) (grub_efi_event_t event);
-
+
grub_efi_status_t
(*close_event) (grub_efi_event_t event);
-
+
grub_efi_status_t
(*check_event) (grub_efi_event_t event);
grub_efi_guid_t *protocol,
grub_efi_interface_type_t interface_type,
void *interface);
-
+
grub_efi_status_t
(*reinstall_protocol_interface) (grub_efi_handle_t handle,
grub_efi_guid_t *protocol,
void *old_interface,
void *new_interface);
-
+
grub_efi_status_t
(*uninstall_protocol_interface) (grub_efi_handle_t handle,
grub_efi_guid_t *protocol,
(*handle_protocol) (grub_efi_handle_t handle,
grub_efi_guid_t *protocol,
void **interface);
-
+
void *reserved;
-
+
grub_efi_status_t
(*register_protocol_notify) (grub_efi_guid_t *protocol,
grub_efi_event_t event,
{
grub_efi_table_header_t hdr;
- grub_efi_status_t
+ grub_efi_status_t
(*get_time) (grub_efi_time_t *time,
grub_efi_time_capabilities_t *capabilities);
grub_efi_status_t
(*reset) (struct grub_efi_simple_input_interface *this,
grub_efi_boolean_t extended_verification);
-
+
grub_efi_status_t
(*read_key_stroke) (struct grub_efi_simple_input_interface *this,
grub_efi_input_key_t *key);
-
+
grub_efi_event_t wait_for_key;
};
typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t;
grub_efi_uintn_t *columns,
grub_efi_uintn_t *rows);
- grub_efi_status_t
+ grub_efi_status_t
(*set_mode) (struct grub_efi_simple_text_output_interface *this,
grub_efi_uintn_t mode_number);
grub_efi_status_t
(*enable_cursor) (struct grub_efi_simple_text_output_interface *this,
grub_efi_boolean_t visible);
-
+
grub_efi_simple_text_output_mode_t *mode;
};
typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
#define GRUB_MACHINE_MEMORY_NVS 4
#define GRUB_MACHINE_MEMORY_CODE 5
#define GRUB_MACHINE_MEMORY_MAX_TYPE 5
- /* This one is special: it's used internally but is never reported
+ /* This one is special: it's used internally but is never reported
by firmware. */
#define GRUB_MACHINE_MEMORY_HOLE 6
-grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
+grub_err_t EXPORT_FUNC(grub_machine_mmap_iterate)
(int NESTED_FUNC_ATTR (*hook) (grub_uint64_t, grub_uint64_t, grub_uint32_t));
-grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
+grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
int type, int handle);
grub_err_t grub_machine_mmap_unregister (int handle);
grub_uint32_t bss_size;
grub_uint32_t entry_addr;
grub_uint32_t code_base;
-
+
#if GRUB_TARGET_SIZEOF_VOID_P == 4
grub_uint32_t data_base;
grub_uint32_t image_base;
grub_uint32_t loader_flags;
grub_uint32_t num_data_directories;
-
+
/* Data directories. */
struct grub_pe32_data_directory export_table;
struct grub_pe32_data_directory import_table;
{
/* This should be filled in with GRUB_PE32_MSDOS_STUB. */
grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
-
+
/* This is always PE\0\0. */
char signature[4];
grub_efiemu_segment_t *segments);
grub_err_t grub_efiemu_loadcore_init64 (void *core, grub_size_t core_size,
grub_efiemu_segment_t *segments);
-grub_err_t grub_efiemu_loadcore_load32 (void *core,
+grub_err_t grub_efiemu_loadcore_load32 (void *core,
grub_size_t core_size,
grub_efiemu_segment_t segments);
-grub_err_t grub_efiemu_loadcore_load64 (void *core,
+grub_err_t grub_efiemu_loadcore_load64 (void *core,
grub_size_t core_size,
grub_efiemu_segment_t segments);
grub_err_t grub_efiemu_loadcore_unload32 (void);
} __attribute__ ((packed));
typedef struct grub_efiemu_configuration_table32 grub_efiemu_configuration_table64_t;
grub_err_t grub_efiemu_unregister_configuration_table (grub_efi_guid_t guid);
-grub_err_t
-grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
+grub_err_t
+grub_efiemu_register_configuration_table (grub_efi_guid_t guid,
void * (*get_table) (void *data),
- void (*unload) (void *data),
+ void (*unload) (void *data),
void *data);
/* Memory management functions */
-int grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
+int grub_efiemu_request_memalign (grub_size_t align, grub_size_t size,
grub_efi_memory_type_t type);
void *grub_efiemu_mm_obtain_request (int handle);
int grub_efiemu_get_memory_map (grub_efi_uintn_t *memory_map_size,
grub_efi_uintn_t *descriptor_size,
grub_efi_uint32_t *descriptor_version);
grub_err_t
-grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
- grub_uint64_t,
+grub_efiemu_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+ grub_uint64_t,
grub_uint32_t));
int grub_efiemu_sizeof_uintn_t (void);
int grub_efiemu_exit_boot_services (grub_efi_uintn_t map_key);
void (*unload) (void *data);
void *data;
};
-grub_err_t grub_efiemu_prepare32 (struct grub_efiemu_prepare_hook
+grub_err_t grub_efiemu_prepare32 (struct grub_efiemu_prepare_hook
*prepare_hooks,
- struct grub_efiemu_configuration_table
+ struct grub_efiemu_configuration_table
*config_tables);
-grub_err_t grub_efiemu_prepare64 (struct grub_efiemu_prepare_hook
+grub_err_t grub_efiemu_prepare64 (struct grub_efiemu_prepare_hook
*prepare_hooks,
- struct grub_efiemu_configuration_table
+ struct grub_efiemu_configuration_table
*config_tables);
grub_err_t grub_efiemu_unload (void);
grub_err_t grub_efiemu_prepare (void);
grub_err_t
grub_efiemu_register_prepare_hook (grub_err_t (*hook) (void *data),
- void (*unload) (void *data),
+ void (*unload) (void *data),
void *data);
/* symbols and pointers */
grub_err_t grub_efiemu_alloc_syms (void);
grub_err_t grub_efiemu_request_symbols (int num);
-grub_err_t grub_efiemu_resolve_symbol (const char *name,
+grub_err_t grub_efiemu_resolve_symbol (const char *name,
int *handle, grub_off_t *off);
-grub_err_t grub_efiemu_register_symbol (const char *name,
+grub_err_t grub_efiemu_register_symbol (const char *name,
int handle, grub_off_t off);
void grub_efiemu_free_syms (void);
-grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value,
+grub_err_t grub_efiemu_write_value (void * addr, grub_uint32_t value,
int plus_handle,
int minus_handle, int ptv_needed, int size);
grub_err_t grub_efiemu_pnvram (void);
/* Call HOOK with each file under DIR. */
grub_err_t (*dir) (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info));
-
+
/* Open a file named NAME and initialize FILE. */
grub_err_t (*open) (struct grub_file *file, const char *name);
-
+
/* Read LEN bytes data from FILE into BUF. */
grub_ssize_t (*read) (struct grub_file *file, char *buf, grub_size_t len);
-
+
/* Close the file FILE. */
grub_err_t (*close) (struct grub_file *file);
-
+
/* Return the label of the device DEVICE in LABEL. The label is
returned in a grub_malloc'ed buffer and should be freed by the
caller. */
/* A pascal style string that holds the volumename. */
grub_uint8_t volname[28];
-
+
grub_uint8_t unused5[60];
grub_uint16_t embed_sig;
struct grub_hfs_extent embed_extent;
#define GRUB_ARCH_EFI_EMU_HEADER 1
grub_err_t
-grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
+grub_arch_efiemu_relocate_symbols32 (grub_efiemu_segment_t segs,
struct grub_efiemu_elf_sym *elfsyms,
void *ehdr);
grub_err_t
-grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
+grub_arch_efiemu_relocate_symbols64 (grub_efiemu_segment_t segs,
struct grub_efiemu_elf_sym *elfsyms,
void *ehdr);
/* For the Linux/i386 boot protocol version 2.03. */
struct linux_kernel_header
-{
+{
grub_uint8_t code1[0x0020];
grub_uint16_t cl_magic; /* Magic number 0xA33F */
grub_uint16_t cl_offset; /* The offset of command line */
grub_uint8_t video_cursor_y;
grub_uint16_t ext_mem; /* 2 */
-
+
grub_uint16_t video_page; /* 4 */
grub_uint8_t video_mode; /* 6 */
grub_uint8_t video_width; /* 7 */
-
+
grub_uint8_t padding1[0xa - 0x8];
-
+
grub_uint16_t video_ega_bx; /* a */
-
+
grub_uint8_t padding2[0xe - 0xc];
-
+
grub_uint8_t video_height; /* e */
grub_uint8_t have_vga; /* f */
grub_uint16_t font_size; /* 10 */
-
+
grub_uint16_t lfb_width; /* 12 */
grub_uint16_t lfb_height; /* 14 */
grub_uint16_t lfb_depth; /* 16 */
grub_uint16_t apm_flags; /* 4c */
grub_uint32_t apm_code_len; /* 4e */
grub_uint16_t apm_data_len; /* 52 */
-
+
grub_uint8_t padding4[0x60 - 0x54];
-
+
grub_uint32_t ist_signature; /* 60 */
grub_uint32_t ist_command; /* 64 */
grub_uint32_t ist_event; /* 68 */
grub_uint32_t ist_perf_level; /* 6c */
grub_uint8_t padding5[0x80 - 0x70];
-
+
grub_uint8_t hd0_drive_info[0x10]; /* 80 */
grub_uint8_t hd1_drive_info[0x10]; /* 90 */
grub_uint16_t rom_config_len; /* a0 */
grub_uint32_t efi_mmap_hi; /* 1dc */
} v0206;
};
-
+
grub_uint32_t alt_mem; /* 1e0 */
-
+
grub_uint8_t padding8[0x1e8 - 0x1e4];
-
+
grub_uint32_t mmap_size; /* 1e8 */
grub_uint8_t padding9[0x1f1 - 0x1ec];
-
+
grub_uint8_t setup_sects; /* The size of the setup in sectors */
grub_uint16_t root_flags; /* If the root is mounted readonly */
grub_uint16_t syssize; /* obsolete */
grub_uint8_t device_path[8];
grub_uint8_t reserved2;
grub_uint8_t checksum;
-
+
/* XXX: This is necessary, because the BIOS of Thinkpad X20
writes a garbage to the tail of drive parameters,
regardless of a size specified in a caller. */
#define GRUB_MACHINE_MEMORY_ACPI 3
#define GRUB_MACHINE_MEMORY_NVS 4
#define GRUB_MACHINE_MEMORY_MAX_TYPE 4
- /* This one is special: it's used internally but is never reported
+ /* This one is special: it's used internally but is never reported
by firmware. */
#define GRUB_MACHINE_MEMORY_HOLE 5
#define GRUB_MMAP_MALLOC_LOW 1
#ifdef GRUB_MACHINE_PCBIOS
-grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
+grub_err_t grub_machine_mmap_register (grub_uint64_t start, grub_uint64_t size,
int type, int handle);
grub_err_t grub_machine_mmap_unregister (int handle);
#else
-static inline grub_err_t
-grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
- int type __attribute__ ((unused)),
+static inline grub_err_t
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
+ int type __attribute__ ((unused)),
int handle __attribute__ ((unused)))
{
return GRUB_ERR_NONE;
}
-static inline grub_err_t
+static inline grub_err_t
grub_machine_mmap_unregister (int handle __attribute__ ((unused)))
{
return GRUB_ERR_NONE;
grub_uint8_t lin_rsvd_field_position;
grub_uint32_t max_pixel_clock;
- /* Reserved field to make structure to be 256 bytes long, VESA BIOS
- Extension 3.0 Specification says to reserve 189 bytes here but
- that doesn't make structure to be 256 bytes. So additional one is
+ /* Reserved field to make structure to be 256 bytes long, VESA BIOS
+ Extension 3.0 Specification says to reserve 189 bytes here but
+ that doesn't make structure to be 256 bytes. So additional one is
added here. */
grub_uint8_t reserved4[189 + 1];
} __attribute__ ((packed));
"pop %%rbx\n"
#else
"pop %%ebx\n"
-#endif
+#endif
:::"%rax", "%rcx", "%rdx");
#else
__asm__ __volatile__ ("xorl %%eax, %%eax\n\t"
struct grub_xnu_boot_params
{
- grub_uint16_t verminor;
- grub_uint16_t vermajor;
+ grub_uint16_t verminor;
+ grub_uint16_t vermajor;
/* Command line passed to xnu. */
- grub_uint8_t cmdline[1024];
+ grub_uint8_t cmdline[1024];
/* Later are the same as EFI's get_memory_map (). */
- grub_xnu_ptr_t efi_mmap;
- grub_uint32_t efi_mmap_size;
- grub_uint32_t efi_mem_desc_size;
- grub_uint32_t efi_mem_desc_version;
+ grub_xnu_ptr_t efi_mmap;
+ grub_uint32_t efi_mmap_size;
+ grub_uint32_t efi_mem_desc_size;
+ grub_uint32_t efi_mem_desc_version;
/* Later are video parameters. */
grub_xnu_ptr_t lfb_base;
#define GRUB_XNU_VIDEO_SPLASH 1
#define GRUB_XNU_VIDEO_TEXT_IN_VIDEO 2
- grub_uint32_t lfb_mode;
+ grub_uint32_t lfb_mode;
grub_uint32_t lfb_line_len;
grub_uint32_t lfb_width;
grub_uint32_t lfb_height;
/* Pointer to device tree and its len. */
grub_xnu_ptr_t devtree;
grub_uint32_t devtreelen;
-
+
/* First used address by kernel or boot structures. */
grub_xnu_ptr_t heap_start;
- /* Last used address by kernel or boot structures minus previous value. */
+ /* Last used address by kernel or boot structures minus previous value. */
grub_uint32_t heap_size;
-
+
/* First memory page containing runtime code or data. */
grub_uint32_t efi_runtime_first_page;
/* First memory page containing runtime code or data minus previous value. */
char *type;
};
-struct grub_ieee1275_mem_region
+struct grub_ieee1275_mem_region
{
unsigned int start;
unsigned int size;
#define IEEE1275_CALL_ENTRY_FN(args) (*grub_ieee1275_entry_fn) (args)
#endif
-/* All backcalls to the firmware is done by calling an entry function
- which was passed to us from the bootloader. When doing the backcall,
- a structure is passed which specifies what the firmware should do.
+/* All backcalls to the firmware is done by calling an entry function
+ which was passed to us from the bootloader. When doing the backcall,
+ a structure is passed which specifies what the firmware should do.
NAME is the requested service. NR_INS and NR_OUTS is the number of
passed arguments and the expected number of return values, resp. */
struct grub_ieee1275_common_hdr
grub_ssize_t *actual);
int EXPORT_FUNC(grub_ieee1275_next_property) (grub_ieee1275_phandle_t phandle,
char *prev_prop, char *prop);
-int EXPORT_FUNC(grub_ieee1275_get_property_length)
+int EXPORT_FUNC(grub_ieee1275_get_property_length)
(grub_ieee1275_phandle_t phandle, const char *prop, grub_ssize_t *length);
-int EXPORT_FUNC(grub_ieee1275_instance_to_package)
+int EXPORT_FUNC(grub_ieee1275_instance_to_package)
(grub_ieee1275_ihandle_t ihandle, grub_ieee1275_phandle_t *phandlep);
int EXPORT_FUNC(grub_ieee1275_package_to_path) (grub_ieee1275_phandle_t phandle,
char *path, grub_size_t len,
grub_ssize_t *actual);
-int EXPORT_FUNC(grub_ieee1275_instance_to_path)
+int EXPORT_FUNC(grub_ieee1275_instance_to_path)
(grub_ieee1275_ihandle_t ihandle, char *path, grub_size_t len,
grub_ssize_t *actual);
int EXPORT_FUNC(grub_ieee1275_write) (grub_ieee1275_ihandle_t ihandle,
grub_uint32_t version;
grub_uint64_t start; /* Absolute start byte of mda_header */
grub_uint64_t size; /* Size of metadata area */
-
+
struct grub_lvm_raw_locn raw_locns[0]; /* NULL-terminated list */
} __attribute__ ((packed));
{
struct grub_macho_fat_header fat;
struct grub_macho_header32 thin32;
- struct grub_macho_header64 thin64;
+ struct grub_macho_header64 thin64;
} __attribute__ ((packed));
/* Common header of Mach-O commands. */
#define GRUB_MACHO_NOBSS 0x1
grub_err_t grub_macho32_load (grub_macho_t macho, char *offset, int flags);
-/* Like filesize and file_read but take only 32-bit part
+/* Like filesize and file_read but take only 32-bit part
for current architecture. */
grub_size_t grub_macho32_filesize (grub_macho_t macho);
grub_err_t grub_macho32_readfile (grub_macho_t macho, void *dest);
#include <grub/err.h>
#include <grub/machine/memory.h>
-grub_err_t grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
- grub_uint64_t,
+grub_err_t grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+ grub_uint64_t,
grub_uint32_t));
int grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type);
grub_err_t grub_mmap_unregister (int handle);
#include <grub/types.h>
struct grub_multiboot_header
-{
+{
/* Must be MULTIBOOT_MAGIC - see above. */
grub_uint32_t magic;
/* The above fields plus this one must equal 0 mod 2^32. */
grub_uint32_t checksum;
-
+
/* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */
grub_uint32_t header_addr;
grub_uint32_t load_addr;
{
/* Multiboot info version number */
grub_uint32_t flags;
-
+
/* Available memory from BIOS */
grub_uint32_t mem_lower;
grub_uint32_t mem_upper;
-
+
/* "root" partition */
grub_uint32_t boot_device;
-
+
/* Kernel command line */
grub_uint32_t cmdline;
-
+
/* Boot-Module list */
grub_uint32_t mods_count;
grub_uint32_t mods_addr;
-
+
grub_uint32_t syms[4];
-
+
/* Memory Mapping buffer */
grub_uint32_t mmap_length;
grub_uint32_t mmap_addr;
-
+
/* Drive Info buffer */
grub_uint32_t drives_length;
grub_uint32_t drives_addr;
-
+
/* ROM configuration table */
grub_uint32_t config_table;
-
+
/* Boot Loader Name */
grub_uint32_t boot_loader_name;
/* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
grub_uint32_t mod_start;
grub_uint32_t mod_end;
-
+
/* Module command line */
grub_uint32_t cmdline;
-
+
/* padding to take it to 16 bytes (must be zero) */
grub_uint32_t pad;
};
grub_err_t
grub_mb2_tag_alloc (grub_addr_t *addr, int key, grub_size_t len);
-grub_err_t
+grub_err_t
grub_mb2_tags_arch_create (void);
-void
+void
grub_mb2_arch_boot (grub_addr_t entry, void *tags);
-void
+void
grub_mb2_arch_unload (struct multiboot_tag_header *tags);
grub_err_t
grub_mb2_arch_elf32_hook (Elf32_Phdr *phdr, grub_addr_t *addr);
-grub_err_t
+grub_err_t
grub_mb2_arch_elf64_hook (Elf64_Phdr *phdr, grub_addr_t *addr);
grub_err_t
grub_err_t
grub_mb2_arch_module_free (grub_addr_t addr, grub_size_t size);
-void
+void
grub_multiboot2 (int argc, char *argv[]);
-void
+void
grub_module2 (int argc, char *argv[]);
#define for_each_tag(tag, tags) \
{
/* The net name. */
const char *name;
-
+
/* The underlying disk device. */
grub_net_dev_t dev;
/* FIXME: More data would be required, such as an IP address, a mask,
a gateway, etc. */
-
+
/* Device-specific data. */
void *data;
};
{
/* The name of the partition map type. */
const char *name;
-
+
/* Call HOOK with each partition, until HOOK returns non-zero. */
grub_err_t (*iterate) (struct grub_disk *disk,
int (*hook) (struct grub_disk *disk,
const grub_partition_t partition));
-
+
/* Return the partition named STR on the disk DISK. */
grub_partition_t (*probe) (struct grub_disk *disk,
const char *str);
-
+
/* Return the name of the partition PARTITION. */
char *(*get_name) (const grub_partition_t partition);
-
+
/* The next partition map type. */
struct grub_partition_map *next;
};
/* The index of this partition in the partition table. */
int index;
-
+
/* Partition map type specific data. */
void *data;
-
+
/* The type partition map. */
grub_partition_map_t partmap;
};
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
int EXPORT_FUNC(grub_partition_map_iterate) (int (*hook) (const grub_partition_map_t partmap));
-
+
void EXPORT_FUNC(grub_partition_map_register) (grub_partition_map_t partmap);
void EXPORT_FUNC(grub_partition_map_unregister) (grub_partition_map_t partmap);
{
char *name;
char *desc;
- enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL}
+ enum {GRUB_PARTTOOL_ARG_END, GRUB_PARTTOOL_ARG_BOOL, GRUB_PARTTOOL_ARG_VAL}
type;
};
};
};
-typedef grub_err_t (*grub_parttool_function_t) (const grub_device_t dev,
+typedef grub_err_t (*grub_parttool_function_t) (const grub_device_t dev,
const struct grub_parttool_args *args);
struct grub_parttool
grub_parttool_function_t func;
};
-int grub_parttool_register(const char *part_name,
+int grub_parttool_register(const char *part_name,
const grub_parttool_function_t func,
const struct grub_parttool_argdesc *args);
void grub_parttool_unregister (int handle);
/* Clean up the terminal. */
grub_err_t (*fini) (void);
-
+
/* Check if any input character is available. */
int (*checkkey) (void);
-
+
/* Get a character. */
int (*getkey) (void);
};
/* Clean up the terminal. */
grub_err_t (*fini) (void);
-
+
/* Put a character. C is encoded in Unicode. */
void (*putchar) (grub_uint32_t c);
/* Get the number of columns occupied by a given character C. C is
encoded in Unicode. */
grub_ssize_t (*getcharwidth) (grub_uint32_t c);
-
+
/* Get the screen size. The return value is ((Width << 8) | Height). */
grub_uint16_t (*getwh) (void);
/* Get the cursor position. The return value is ((X << 8) | Y). */
grub_uint16_t (*getxy) (void);
-
+
/* Go to the position (X, Y). */
void (*gotoxy) (grub_uint8_t x, grub_uint8_t y);
-
+
/* Clear the screen. */
void (*cls) (void);
-
+
/* Set the current color to be used */
void (*setcolorstate) (grub_term_color_state state);
-
+
/* Set the normal color and the highlight color. The format of each
color is VGA's. */
void (*setcolor) (grub_uint8_t normal_color, grub_uint8_t highlight_color);
-
+
/* Get the normal color and the highlight color. The format of each
color is VGA's. */
void (*getcolor) (grub_uint8_t *normal_color, grub_uint8_t *highlight_color);
-
+
/* Turn on/off the cursor. */
void (*setcursor) (int on);
grub_uint8_t strvendor;
grub_uint8_t strprod;
grub_uint8_t strserial;
- grub_uint8_t configcnt;
+ grub_uint8_t configcnt;
} __attribute__ ((packed));
struct grub_usb_desc_config
/* When needed, decode color or just use value as is. */
GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR,
-
+
/* Two color bitmap; bits packed: rows are not padded to byte boundary. */
GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED
};
/* %esp at start. */
grub_uint32_t stack;
grub_uint8_t unknown2[44];
-#define GRUB_XNU_HIBERNATE_MAGIC 0x73696d65
+#define GRUB_XNU_HIBERNATE_MAGIC 0x73696d65
grub_uint32_t magic;
grub_uint8_t unknown3[28];
/* This value is non-zero if page is encrypted. Unsupported. */
/* In-memory structure for temporary keeping device tree. */
struct grub_xnu_devtree_key
{
- char *name;
+ char *name;
int datasize; /* -1 for not leaves. */
union
{
};
/* A structure used in memory-map values. */
-struct
+struct
grub_xnu_extdesc
{
grub_uint32_t addr;
struct grub_xnu_devtree_key *grub_xnu_find_key (struct grub_xnu_devtree_key *parent,
char *name);
grub_err_t grub_xnu_align_heap (int align);
-grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
+grub_err_t grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
int maxrecursion);
-grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
+grub_err_t grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
int maxrecursion);
void *grub_xnu_heap_malloc (int size);
extern grub_uint32_t grub_xnu_heap_real_start;
/* Alignment of the multiboot info structure. */
#define MULTIBOOT_INFO_ALIGN 0x00000004
-/*
+/*
* Flags set in the 'flags' member of the multiboot header.
*/
if (grub_file_tell (gzio->file) != 0)
grub_file_seek (gzio->file, 0);
-
+
/*
* This checks if the file is gzipped. If a problem occurs here
* (other than a real error with the disk) then we don't think it
}
gzio->data_offset = grub_file_tell (gzio->file);
-
+
grub_file_seek (gzio->file, grub_file_size (gzio->file) - 8);
-
+
if (grub_file_read (gzio->file, (char *) buf, 8) != 8)
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
get_byte (grub_file_t file)
{
grub_gzio_t gzio = file->data;
-
+
if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset
|| gzio->inbuf_d == INBUFSIZ)
{
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
grub_gzio_t gzio = file->data;
-
+
/* make local copies of globals */
d = gzio->inflate_d;
n = gzio->inflate_n;
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
grub_gzio_t gzio = file->data;
-
+
/* make local copies of globals */
b = gzio->bb; /* initialize bit buffer */
k = gzio->bk;
int i; /* temporary variable */
unsigned l[288]; /* length list for huft_build */
grub_gzio_t gzio = file->data;
-
+
/* set up literal table */
for (i = 0; i < 144; i++)
l[i] = 8;
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
grub_gzio_t gzio = file->data;
-
+
/* make local bit buffer */
b = gzio->bb;
k = gzio->bk;
register ulg b; /* bit buffer */
register unsigned k; /* number of bits in bit buffer */
grub_gzio_t gzio = file->data;
-
+
/* make local bit buffer */
b = gzio->bb;
k = gzio->bk;
inflate_window (grub_file_t file)
{
grub_gzio_t gzio = file->data;
-
+
/* initialize window */
gzio->wp = 0;
initialize_tables (grub_file_t file)
{
grub_gzio_t gzio = file->data;
-
+
gzio->saved_offset = 0;
grub_file_seek (gzio->file, gzio->data_offset);
{
grub_file_t file;
grub_gzio_t gzio = 0;
-
+
file = (grub_file_t) grub_malloc (sizeof (*file));
if (! file)
return 0;
grub_free (file);
return 0;
}
-
+
grub_memset (gzio, 0, sizeof (*gzio));
gzio->file = io;
-
+
file->device = io->device;
file->offset = 0;
file->data = gzio;
else
return 0;
}
-
+
return file;
}
grub_gzfile_open (const char *name, int transparent)
{
grub_file_t io, file;
-
+
io = grub_file_open (name);
if (! io)
return 0;
grub_ssize_t ret = 0;
grub_gzio_t gzio = file->data;
grub_off_t offset;
-
+
/* Do we reset decompression to the beginning of the file? */
if (gzio->saved_offset > file->offset + WSIZE)
initialize_tables (file);
*/
offset = file->offset;
-
+
while (len > 0 && grub_errno == GRUB_ERR_NONE)
{
register grub_size_t size;
grub_gzio_close (grub_file_t file)
{
grub_gzio_t gzio = file->data;
-
+
grub_file_close (gzio->file);
huft_free (gzio->tl);
huft_free (gzio->td);
}
static int
-grub_mini_print_files (const char *filename,
+grub_mini_print_files (const char *filename,
const struct grub_dirhook_info *info)
{
grub_printf ("%s%s ", filename, info->dir ? "/" : "");
goto fail;
}
}
-
+
dev = grub_malloc (sizeof (*dev));
if (! dev)
goto fail;
-
+
/* Try to open a disk. */
disk = grub_disk_open (name);
if (! disk)
fail:
if (disk)
grub_disk_close (disk);
-
+
grub_free (dev);
return 0;
auto int iterate_disk (const char *disk_name);
auto int iterate_partition (grub_disk_t disk,
const grub_partition_t partition);
-
+
struct part_ent
{
struct part_ent *next;
if (hook (disk_name))
return 1;
-
+
dev = grub_device_open (disk_name);
if (! dev)
return 0;
-
+
if (dev->disk && dev->disk->has_partitions)
{
struct part_ent *p;
grub_device_close (dev);
return 0;
}
-
+
int iterate_partition (grub_disk_t disk, const grub_partition_t partition)
{
char *partition_name;
struct part_ent *p;
-
+
partition_name = grub_partition_get_name (partition);
if (! partition_name)
return 1;
#if 0
grub_disk_cache_misses++;
#endif
-
+
return 0;
}
{
unsigned index;
struct grub_disk_cache *cache;
-
+
index = grub_disk_cache_get_index (dev_id, disk_id, sector);
cache = grub_disk_cache_table + index;
-
+
cache->lock = 1;
grub_free (cache->data);
cache->data = 0;
cache->lock = 0;
-
+
cache->data = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
if (! cache->data)
return grub_errno;
-
+
grub_memcpy (cache->data, data,
GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
cache->dev_id = dev_id;
grub_disk_dev_unregister (grub_disk_dev_t dev)
{
grub_disk_dev_t *p, q;
-
+
for (p = &grub_disk_dev_list, q = *p; q; p = &(q->next), q = q->next)
if (q == dev)
{
disk->name = grub_strdup (name);
if (! disk->name)
goto fail;
-
+
p = find_part_sep (name);
if (p)
{
grub_size_t len = p - name;
-
+
raw = grub_malloc (len + 1);
if (! raw)
goto fail;
grub_error (GRUB_ERR_BAD_DEVICE, "no partition on this disk");
goto fail;
}
-
+
disk->dev = dev;
if (p)
if (current_time > (grub_last_time
+ GRUB_CACHE_TIMEOUT * 1000))
grub_disk_cache_invalidate_all ();
-
+
grub_last_time = current_time;
-
+
fail:
-
+
if (raw && raw != name)
grub_free (raw);
{
*sector += *offset >> GRUB_DISK_SECTOR_BITS;
*offset &= GRUB_DISK_SECTOR_SIZE - 1;
-
+
if (disk->partition)
{
grub_disk_addr_t start;
unsigned real_offset;
grub_dprintf ("disk", "Reading `%s'...\n", disk->name);
-
+
/* First of all, check if the region is within the disk. */
if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE)
{
}
real_offset = offset;
-
+
/* Allocate a temporary buffer. */
tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
if (! tmp_buf)
goto finish;
tmp_buf = p;
-
+
if ((disk->dev->read) (disk, sector, num, tmp_buf))
{
grub_error_push ();
{
grub_disk_addr_t s = sector;
grub_size_t l = len;
-
+
while (l)
{
(disk->read_hook) (s, real_offset,
((l > GRUB_DISK_SECTOR_SIZE)
? GRUB_DISK_SECTOR_SIZE
: l));
-
+
if (l < GRUB_DISK_SECTOR_SIZE - real_offset)
break;
-
+
s++;
l -= GRUB_DISK_SECTOR_SIZE - real_offset;
real_offset = 0;
}
}
-
+
sector = start_sector + GRUB_DISK_CACHE_SIZE;
buf = (char *) buf + len;
size -= len;
real_offset = 0;
}
-
+
finish:
-
+
grub_free (tmp_buf);
-
+
return grub_errno;
}
grub_off_t offset, grub_size_t size, const void *buf)
{
unsigned real_offset;
-
+
grub_dprintf ("disk", "Writing `%s'...\n", disk->name);
if (grub_disk_adjust_range (disk, §or, &offset, size) != GRUB_ERR_NONE)
return -1;
real_offset = offset;
-
+
while (size)
{
if (real_offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0))
{
char tmp_buf[GRUB_DISK_SECTOR_SIZE];
grub_size_t len;
-
+
if (grub_disk_read (disk, sector, 0, GRUB_DISK_SECTOR_SIZE, tmp_buf)
!= GRUB_ERR_NONE)
goto finish;
len = GRUB_DISK_SECTOR_SIZE - real_offset;
if (len > size)
len = size;
-
+
grub_memcpy (tmp_buf + real_offset, buf, len);
grub_disk_cache_invalidate (disk->dev->id, disk->id, sector);
len = size & ~(GRUB_DISK_SECTOR_SIZE - 1);
n = size >> GRUB_DISK_SECTOR_BITS;
-
+
if ((disk->dev->write) (disk, sector, n, buf) != GRUB_ERR_NONE)
goto finish;
return grub_errno;
}
-grub_uint64_t
+grub_uint64_t
grub_disk_get_size (grub_disk_t disk)
{
if (disk->partition)
if (grub_dl_get (mod->name))
return grub_error (GRUB_ERR_BAD_MODULE,
"`%s' is already loaded", mod->name);
-
+
l = (grub_dl_list_t) grub_malloc (sizeof (*l));
if (! l)
return grub_errno;
{
grub_symbol_t sym;
unsigned k;
-
+
sym = (grub_symbol_t) grub_malloc (sizeof (*sym));
if (! sym)
return grub_errno;
}
else
sym->name = name;
-
+
sym->addr = addr;
sym->mod = mod;
-
+
k = grub_symbol_hash (name);
sym->next = grub_symtab[k];
grub_symtab[k] = sym;
if (! mod)
grub_fatal ("core symbols cannot be unregistered");
-
+
for (i = 0; i < GRUB_SYMTAB_SIZE; i++)
{
grub_symbol_t sym, *p, q;
{
unsigned i;
Elf_Shdr *s;
-
+
for (i = 0, s = (Elf_Shdr *)((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize))
seg = (grub_dl_segment_t) grub_malloc (sizeof (*seg));
if (! seg)
return grub_errno;
-
+
if (s->sh_size)
{
void *addr;
Elf_Sym *sym;
const char *str;
Elf_Word size, entsize;
-
+
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
sym = (Elf_Sym *) ((char *) e + s->sh_offset);
size = s->sh_size;
entsize = s->sh_entsize;
-
+
s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shentsize * s->sh_link);
str = (char *) e + s->sh_offset;
unsigned char type = ELF_ST_TYPE (sym->st_info);
unsigned char bind = ELF_ST_BIND (sym->st_info);
const char *name = str + sym->st_name;
-
+
switch (type)
{
case STT_NOTYPE:
if (bind != STB_LOCAL)
if (grub_dl_register_symbol (name, (void *) sym->st_value, mod))
return grub_errno;
-
+
if (grub_strcmp (name, "grub_mod_init") == 0)
mod->init = (void (*) (grub_dl_t)) sym->st_value;
else if (grub_strcmp (name, "grub_mod_fini") == 0)
s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize);
str = (char *) e + s->sh_offset;
-
+
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize))
{
grub_dl_t m;
grub_dl_dep_t dep;
-
+
m = grub_dl_load (name);
if (! m)
return grub_errno;
grub_dl_ref (m);
-
+
dep = (grub_dl_dep_t) grub_malloc (sizeof (*dep));
if (! dep)
return grub_errno;
-
+
dep->mod = m;
dep->next = mod->dep;
mod->dep = dep;
-
+
name += grub_strlen (name) + 1;
}
}
for (dep = mod->dep; dep; dep = dep->next)
grub_dl_ref (dep->mod);
-
+
return ++mod->ref_count;
}
for (dep = mod->dep; dep; dep = dep->next)
grub_dl_unref (dep->mod);
-
+
return --mod->ref_count;
}
#endif
grub_ssize_t size;
void *core = 0;
grub_dl_t mod = 0;
-
+
file = grub_file_open (filename);
if (! file)
return 0;
grub_free (core);
return 0;
}
-
+
mod->ref_count = 0;
return mod;
}
mod = grub_dl_get (name);
if (mod)
return mod;
-
+
if (! grub_dl_dir) {
grub_error (GRUB_ERR_FILE_NOT_FOUND, "\"prefix\" is not set");
return 0;
+ grub_strlen (name) + 4 + 1);
if (! filename)
return 0;
-
+
grub_sprintf (filename, "%s/%s.mod", grub_dl_dir, name);
mod = grub_dl_load_file (filename);
grub_free (filename);
if (! mod)
return 0;
-
+
if (grub_strcmp (mod->name, name) != 0)
grub_error (GRUB_ERR_BAD_MODULE, "mismatched names");
-
+
return mod;
}
if (mod->fini)
(mod->fini) ();
-
+
grub_dl_remove (mod);
grub_dl_unregister_symbols (mod);
-
+
for (dep = mod->dep; dep; dep = depn)
{
depn = dep->next;
-
+
if (! grub_dl_unref (dep->mod))
grub_dl_unload (dep->mod);
-
+
grub_free (dep);
}
grub_free (seg->addr);
grub_free (seg);
}
-
+
grub_free (mod->name);
grub_free (mod);
return 1;
/* Because grub_dl_remove modifies the list of modules, this
implementation is tricky. */
grub_dl_list_t p = grub_dl_head;
-
+
while (p)
{
if (grub_dl_unload (p->mod))
while (grub_dl_head)
{
grub_dl_list_t p;
-
+
grub_dl_unload_unneeded ();
/* Force to decrement the ref count. This will purge pre-loaded
{
void *interface;
grub_efi_status_t status;
-
+
status = efi_call_3 (grub_efi_system_table->boot_services->locate_protocol,
protocol, registration, &interface);
if (status != GRUB_EFI_SUCCESS)
return 0;
-
+
return interface;
}
grub_efi_status_t status;
grub_efi_handle_t *buffer;
grub_efi_uintn_t buffer_size = 8 * sizeof (grub_efi_handle_t);
-
+
buffer = grub_malloc (buffer_size);
if (! buffer)
return 0;
-
+
b = grub_efi_system_table->boot_services;
status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
&buffer_size, buffer);
buffer = grub_malloc (buffer_size);
if (! buffer)
return 0;
-
+
status = efi_call_5 (b->locate_handle, search_type, protocol, search_key,
&buffer_size, buffer);
}
grub_efi_boot_services_t *b;
grub_efi_status_t status;
void *interface;
-
+
b = grub_efi_system_table->boot_services;
status = efi_call_6 (b->open_protocol, handle,
protocol,
/* No console control protocol instance available, assume it is
already in text mode. */
return 1;
-
+
if (efi_call_4 (c->get_mode, c, &mode, 0, 0) != GRUB_EFI_SUCCESS)
return 0;
{
grub_efi_boot_services_t *b;
grub_efi_status_t status;
-
+
b = grub_efi_system_table->boot_services;
status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, map_key);
return status == GRUB_EFI_SUCCESS;
struct grub_pe32_section_table *section;
struct grub_module_info *info;
grub_uint16_t i;
-
+
image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (! image)
return 0;
grub_efi_get_filename (grub_efi_device_path_t *dp)
{
char *name = 0;
-
+
while (1)
{
grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp);
}
else
size = 0;
-
+
len = ((GRUB_EFI_DEVICE_PATH_LENGTH (dp) - 4)
/ sizeof (grub_efi_char16_t));
p = grub_realloc (name, size + len * 4 + 1);
grub_efi_expanded_acpi_device_path_t eacpi;
grub_memcpy (&eacpi, dp, sizeof (eacpi));
grub_printf ("/ACPI(");
-
+
if (GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp)[0] == '\0')
grub_printf ("%x,", (unsigned) eacpi.hid);
else
grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_HIDSTR (dp));
-
+
if (GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp)[0] == '\0')
grub_printf ("%x,", (unsigned) eacpi.uid);
else
grub_printf ("%s,", GRUB_EFI_EXPANDED_ACPI_UIDSTR (dp));
-
+
if (GRUB_EFI_EXPANDED_ACPI_CIDSTR (dp)[0] == '\0')
grub_printf ("%x)", (unsigned) eacpi.cid);
else
return;
break;
}
-
+
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
break;
return 0;
mmap_buf = grub_malloc (mmap_size);
-
+
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, &map_key,
&desc_size, &desc_version) <= 0)
return 0;
grub_efi_set_prefix (void)
{
grub_efi_loaded_image_t *image;
-
+
image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (image)
{
device = grub_efidisk_get_device_name (image->device_handle);
file = grub_efi_get_filename (image->file_path);
-
+
if (device && file)
{
char *p;
char *prefix;
-
+
/* Get the directory. */
p = grub_strrchr (file, '/');
if (p)
grub_free (prefix);
}
}
-
+
grub_free (device);
grub_free (file);
}
if (address > 0xffffffff)
return 0;
#endif
-
+
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
if (address == 0)
{
if (status != GRUB_EFI_SUCCESS)
return 0;
}
-
+
if (allocated_pages)
{
unsigned i;
if (i == MAX_ALLOCATED_PAGES)
grub_fatal ("too many page allocations");
}
-
+
return (void *) ((grub_addr_t) address);
}
!= address))
{
unsigned i;
-
+
for (i = 0; i < MAX_ALLOCATED_PAGES; i++)
if (allocated_pages[i].addr == address)
{
break;
}
}
-
+
b = grub_efi_system_table->boot_services;
efi_call_2 (b->free_pages, address, pages);
}
map_key = &key;
if (! descriptor_version)
descriptor_version = &version;
-
+
b = grub_efi_system_table->boot_services;
status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key,
descriptor_size, descriptor_version);
{
grub_efi_memory_descriptor_t *d1;
grub_efi_memory_descriptor_t *d2;
-
+
for (d1 = memory_map;
d1 < memory_map_end;
d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size))
{
grub_efi_memory_descriptor_t *max_desc = d1;
-
+
for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size);
d2 < memory_map_end;
d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size))
&& desc->num_pages != 0)
{
grub_memcpy (filtered_desc, desc, desc_size);
-
+
/* Avoid less than 1MB, because some loaders seem to be confused. */
if (desc->physical_start < 0x100000)
{
- desc->physical_start);
desc->physical_start = 0x100000;
}
-
+
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ filtered_desc->num_pages
= (BYTES_TO_PAGES (0x100000000LL)
- BYTES_TO_PAGES (filtered_desc->physical_start));
#endif
-
+
if (filtered_desc->num_pages == 0)
continue;
-
+
filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size);
}
}
{
grub_efi_memory_descriptor_t *desc;
grub_efi_uint64_t total = 0;
-
+
for (desc = memory_map;
desc < memory_map_end;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
grub_efi_uint64_t required_pages)
{
grub_efi_memory_descriptor_t *desc;
-
+
for (desc = memory_map;
desc < memory_map_end;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{
grub_efi_memory_descriptor_t *desc;
int i;
-
+
for (desc = memory_map, i = 0;
desc < memory_map_end;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++)
grub_fatal ("cannot allocate memory");
grub_memset (allocated_pages, 0, ALLOCATED_PAGES_SIZE);
-
+
/* Prepare a memory region to store two memory maps. */
memory_map = grub_efi_allocate_pages (0,
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
grub_fatal ("cannot get memory map");
memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size);
-
+
filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map,
desc_size, memory_map_end);
-
+
/* By default, request a quarter of the available memory. */
total_pages = get_total_pages (filtered_memory_map, desc_size,
filtered_memory_map_end);
NEXT_MEMORY_DESCRIPTOR (memory_map, map_size));
grub_abort ();
#endif
-
+
/* Release the memory maps. */
grub_efi_free_pages ((grub_addr_t) memory_map,
2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
{
/* A hash table for variables. */
struct grub_env_var *vars[HASHSZ];
-
+
/* One level deeper on the stack. */
struct grub_env_context *prev;
};
for (i = 0; i < HASHSZ; i++)
{
struct grub_env_var *var;
-
+
for (var = context->prev->vars[i]; var; var = var->next)
{
if (export && var->type == GRUB_ENV_VAR_GLOBAL)
}
}
}
-
+
return GRUB_ERR_NONE;
}
if (! current_context->prev)
grub_fatal ("cannot close the initial context");
-
+
/* Free the variables associated with this context. */
for (i = 0; i < HASHSZ; i++)
{
struct grub_env_var *p, *q;
-
+
for (p = current_context->vars[i]; p; p = q)
{
q = p->next;
var->value = var->write_hook (var, val);
else
var->value = grub_strdup (val);
-
+
if (! var->value)
{
var->value = old;
var = grub_malloc (sizeof (*var));
if (! var)
return grub_errno;
-
+
grub_memset (var, 0, sizeof (*var));
/* This is not necessary, because GRUB_ENV_VAR_LOCAL == 0. But leave
this for readability. */
var->type = GRUB_ENV_VAR_LOCAL;
-
+
var->name = grub_strdup (name);
if (! var->name)
goto fail;
-
+
var->value = grub_strdup (val);
if (! var->value)
goto fail;
grub_env_get (const char *name)
{
struct grub_env_var *var;
-
+
var = grub_env_find (name);
if (! var)
return 0;
grub_env_unset (const char *name)
{
struct grub_env_var *var;
-
+
var = grub_env_find (name);
if (! var)
return;
struct grub_env_sorted_var *sorted_list = 0;
struct grub_env_sorted_var *sorted_var;
int i;
-
+
/* Add variables associated with this context into a sorted list. */
for (i = 0; i < HASHSZ; i++)
{
struct grub_env_var *var;
-
+
for (var = current_context->vars[i]; var; var = var->next)
{
struct grub_env_sorted_var *p, **q;
/* Ignore data slots. */
if (var->type == GRUB_ENV_VAR_DATA)
continue;
-
+
sorted_var = grub_malloc (sizeof (*sorted_var));
if (! sorted_var)
goto fail;
if (grub_strcmp (p->var->name, var->name) > 0)
break;
}
-
+
sorted_var->next = *q;
*q = sorted_var;
}
{
if (grub_env_set (name, "") != GRUB_ERR_NONE)
return grub_errno;
-
+
var = grub_env_find (name);
/* XXX Insert an assertion? */
}
-
+
var->read_hook = read_hook;
var->write_hook = write_hook;
mangled_name = grub_malloc (grub_strlen (name) + 2);
if (! mangled_name)
return 0;
-
+
grub_sprintf (mangled_name, "\e%s", name);
return mangled_name;
}
var = grub_malloc (sizeof (*var));
if (! var)
goto fail;
-
+
grub_memset (var, 0, sizeof (*var));
var->type = GRUB_ENV_VAR_DATA;
{
char *mangled_name;
void *ptr = 0;
-
+
mangled_name = mangle_data_slot_name (name);
if (! mangled_name)
goto fail;
grub_free (mangled_name);
fail:
-
+
return ptr;
}
grub_env_unset_data_slot (const char *name)
{
char *mangled_name;
-
+
mangled_name = mangle_data_slot_name (name);
if (! mangled_name)
return;
grub_error (grub_err_t n, const char *fmt, ...)
{
va_list ap;
-
+
grub_errno = n;
va_start (ap, fmt);
grub_memcpy (grub_error_stack_items[grub_error_stack_pos].errmsg,
grub_errmsg,
sizeof (grub_errmsg));
-
+
/* Advance to next error stack position. */
grub_error_stack_pos++;
}
{
/* Pop error message from error stack to current active error. */
grub_error_stack_pos--;
-
+
grub_errno = grub_error_stack_items[grub_error_stack_pos].errno;
grub_memcpy (grub_errmsg,
grub_error_stack_items[grub_error_stack_pos].errmsg,
sizeof (grub_errmsg));
-
+
return 1;
}
else
{
/* There is no more items on error stack, reset to no error state. */
grub_errno = GRUB_ERR_NONE;
-
+
return 0;
}
}
{
if (grub_errno != GRUB_ERR_NONE)
grub_err_printf ("error: %s\n", grub_errmsg);
- }
+ }
while (grub_error_pop ());
-
+
/* If there was an assert while using error stack, report about it. */
if (grub_error_stack_assert)
{
{
char *p = grub_strchr (name, ')');
char *ret;
-
+
if (! p)
{
grub_error (GRUB_ERR_BAD_FILENAME, "missing `)'");
ret = (char *) grub_malloc (p - name);
if (! ret)
return 0;
-
+
grub_memcpy (ret, name + 1, p - name - 1);
ret[p - name - 1] = '\0';
return ret;
grub_free (device_name);
if (! device)
goto fail;
-
+
file = (grub_file_t) grub_malloc (sizeof (*file));
if (! file)
goto fail;
-
+
file->device = device;
file->offset = 0;
file->data = 0;
file->read_hook = 0;
-
+
if (device->disk && file_name[0] != '/')
/* This is a block list. */
file->fs = &grub_fs_blocklist;
/* if (net) grub_net_close (net); */
grub_free (file);
-
+
return 0;
}
grub_file_read (grub_file_t file, char *buf, grub_size_t len)
{
grub_ssize_t res;
-
+
if (len == 0 || len > file->size - file->offset)
len = file->size - file->offset;
/* Prevent an overflow. */
if ((grub_ssize_t) len < 0)
len >>= 1;
-
+
if (len == 0)
return 0;
-
+
res = (file->fs->read) (file, buf, len);
if (res > 0)
file->offset += res;
"attempt to seek outside of the file");
return -1;
}
-
+
old = file->offset;
file->offset = offset;
return old;
grub_fs_probe (grub_device_t device)
{
grub_fs_t p;
- auto int dummy_func (const char *filename,
+ auto int dummy_func (const char *filename,
const struct grub_dirhook_info *info);
int dummy_func (const char *filename __attribute__ ((unused)),
if (grub_fs_autoload_hook && count == 0)
{
count++;
-
+
while (grub_fs_autoload_hook ())
{
p = grub_fs_list;
-
+
(p->dir) (device, "/", dummy_func);
if (grub_errno == GRUB_ERR_NONE)
{
count--;
return p;
}
-
+
if (grub_errno != GRUB_ERR_BAD_FS)
{
count--;
return 0;
}
-
+
grub_errno = GRUB_ERR_NONE;
}
unsigned i;
grub_disk_t disk = file->device->disk;
struct grub_fs_block *blocks;
-
+
/* First, count the number of blocks. */
do
{
grub_error (GRUB_ERR_BAD_FILENAME, "beyond the total sectors");
goto fail;
}
-
+
file->size += (blocks[i].length << GRUB_DISK_SECTOR_BITS);
p++;
}
blocks[i].length = 0;
file->data = blocks;
-
+
return GRUB_ERR_NONE;
fail:
if (((size + offset + GRUB_DISK_SECTOR_SIZE - 1)
>> GRUB_DISK_SECTOR_BITS) > p->length - sector)
size = ((p->length - sector) << GRUB_DISK_SECTOR_BITS) - offset;
-
+
if (grub_disk_read (file->device->disk, p->offset + sector, offset,
size, buf) != GRUB_ERR_NONE)
return -1;
-
+
ret += size;
len -= size;
sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS);
start = grub_get_time_ms ();
- /* Instead of setting an end time and looping while the current time is
+ /* Instead of setting an end time and looping while the current time is
less than that, comparing the elapsed sleep time with the desired sleep
- time handles the (unlikely!) case that the timer would wrap around
+ time handles the (unlikely!) case that the timer would wrap around
during the sleep. */
while (grub_get_time_ms () - start < ms)
grub_uint64_t
grub_rtc_get_time_ms (void)
{
- /* By dimensional analysis:
-
+ /* By dimensional analysis:
+
1000 ms N rtc ticks 1 s
------- * ----------- * ----------- = 1000*N/T ms
1 s 1 T rtc ticks
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
+
symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
entsize = s->sh_entsize;
if (seg)
{
Elf32_Rel *rel, *max;
-
+
for (rel = (Elf32_Rel *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
{
Elf32_Word *addr;
Elf32_Sym *sym;
-
+
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
-
+
addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf32_Sym *) ((char *) symtab
+ entsize * ELF32_R_SYM (rel->r_info));
-
+
switch (ELF32_R_TYPE (rel->r_info))
{
case R_386_32:
{
}
-void
+void
grub_arch_sync_caches (void *address __attribute__ ((unused)),
grub_size_t len __attribute__ ((unused)))
{
grub_addr_t grub_os_area_addr;
grub_size_t grub_os_area_size;
-void
+void
grub_arch_sync_caches (void *address __attribute__ ((unused)),
grub_size_t len __attribute__ ((unused)))
{
to the boot drive. */
if (grub_root_drive == 0xFF)
grub_root_drive = grub_boot_drive;
-
+
grub_sprintf (dev, "(%cd%u", (grub_root_drive & 0x80) ? 'h' : 'f',
grub_root_drive & 0x7f);
-
+
if (grub_install_dos_part >= 0)
grub_sprintf (dev + grub_strlen (dev), ",%u", grub_install_dos_part + 1);
-
+
if (grub_install_bsd_part >= 0)
grub_sprintf (dev + grub_strlen (dev), ",%c", grub_install_bsd_part + 'a');
-
+
grub_sprintf (dev + grub_strlen (dev), ")%s", grub_prefix);
grub_strcpy (grub_prefix, dev);
}
-
+
return grub_prefix;
}
if (mem_regions[i].addr + mem_regions[i].size >= mem_regions[i + 1].addr)
{
j = i + 1;
-
+
if (mem_regions[i].addr + mem_regions[i].size
< mem_regions[j].addr + mem_regions[j].size)
mem_regions[i].size = (mem_regions[j].addr + mem_regions[j].size
{
int i;
int grub_lower_mem;
-
+
/* Initialize the console as early as possible. */
grub_console_init ();
-
+
grub_lower_mem = grub_get_memsize (0) << 10;
-
+
/* Sanity check. */
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
grub_fatal ("too small memory");
add_mem_region (GRUB_MEMORY_MACHINE_RESERVED_END,
grub_lower_mem - GRUB_MEMORY_MACHINE_RESERVED_END);
#endif
-
+
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size, grub_uint32_t type)
{
{
if (size <= 0x100000 - addr)
return 0;
-
+
size -= 0x100000 - addr;
addr = 0x100000;
}
-
+
/* Ignore >4GB. */
if (addr <= 0xFFFFFFFF && type == GRUB_MACHINE_MEMORY_AVAILABLE)
{
grub_size_t len;
-
+
len = (grub_size_t) ((addr + size > 0xFFFFFFFF)
? 0xFFFFFFFF - addr
: size);
}
grub_machine_mmap_iterate (hook);
-
+
compact_mem_regions ();
/* Add the memory regions to free memory, except for the region starting
}
else
grub_mm_init_region ((void *) mem_regions[i].addr, mem_regions[i].size);
-
+
if (! grub_os_area_addr)
grub_fatal ("no upper memory");
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
-
+
/*
* This code was stolen from the files enter.sh, leave.sh, lzo1x_d.sh,
* lzo1x_f.s and lzo_asm.h in LZO version 1.08, and was heavily modified
#define MOVSL(r1,r2,x) movl (r1), x ; addl $4, r1 ; movl x, (r2) ; addl $4, r2
#define COPYL_C(r1,r2,x,rc) 9: MOVSL(r1,r2,x) ; decl rc ; jnz 9b
#define COPYL(r1,r2,x) COPYL_C(r1,r2,x,%ecx)
-
+
lzo1x_decompress:
pushl %ebp
pushl %edi
movl OUTP, %edi
movl $3, %ebp
-
+
xorl %eax, %eax
xorl %ebx, %ebx /* high bits 9-32 stay 0 */
lodsb
.L_leave:
negl %eax
jnz 1f
-
+
subl OUTP, %edi /* write back the uncompressed size */
movl %edi, %eax
grub_uint32_t cont;
struct grub_machine_mmap_entry *entry
= (struct grub_machine_mmap_entry *) GRUB_MEMORY_MACHINE_SCRATCH_ADDR;
-
+
/* Check if grub_get_mmap_entry works. */
cont = grub_get_mmap_entry (entry, 0);
* Note: These functions defined in this file may be called from C.
* Be careful of that you must not modify some registers. Quote
* from gcc-2.95.2/gcc/config/i386/i386.h:
-
+
1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
registers that can be used without being saved.
#include <grub/term.h>
#include <multiboot.h>
#include <multiboot2.h>
-
+
#define ABS(x) ((x) - _start + GRUB_BOOT_MACHINE_KERNEL_ADDR + 0x200)
-
+
.file "startup.S"
.text
.long 0
/* entry addr */
.long multiboot_entry - _start + 0x100000 + 0x200
-
+
multiboot_entry:
.code32
/* obtain the boot device */
/* jump to the real address */
movl $multiboot_trampoline, %eax
jmp *%eax
-
+
multiboot_trampoline:
/* fill the boot information */
movl %edx, %eax
/* enter the usual booting */
call prot_to_real
.code16
-
+
/* the real mode code continues... */
codestart:
cli /* we're not safe here! */
/* reset disk system (%ah = 0) */
int $0x13
-
+
/* transition to protected mode */
DATA32 call real_to_prot
incl %eax
call EXT_C(grub_gate_a20)
-
+
#if defined(ENABLE_LZO)
/* decompress the compressed part and put the result at 1MB */
movl $GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR, %esi
rep
movsb
#endif
-
+
#ifdef APPLE_CC
/* clean out the bss */
bss_start_abs = ABS (bss_start)
movl $END_SYMBOL, %ecx
subl %edi, %ecx
#endif
-
+
/* clean out */
xorl %eax, %eax
cld
rep
stosb
-
+
/*
* Call the start of main body of C code.
*/
.byte 0
.p2align 2 /* force 4-byte alignment */
-
+
/*
* These next two routines, "real_to_prot" and "prot_to_real" are structured
* in a very specific way. Be very careful when changing them.
FUNCTION(grub_gate_a20)
movl %eax, %edx
-gate_a20_test_current_state:
+gate_a20_test_current_state:
/* first of all, test if already in a good state */
call gate_a20_check_state
cmpb %al, %dl
cmpb %al, %dl
jnz gate_a20_try_system_control_port_a
ret
-
+
gate_a20_try_system_control_port_a:
/*
* In macbook, the keyboard test would hang the machine, so we move
inb $0x64
andb $0x02, %al
jnz gate_a20_flush_keyboard_buffer
-2:
+2:
inb $0x64
andb $0x01, %al
jz 3f
jmp 2b
3:
ret
-
-gate_a20_try_keyboard_controller:
+
+gate_a20_try_keyboard_controller:
/* third, try the keyboard controller */
call gate_a20_flush_keyboard_buffer
movb $0xd1, %al
outb $0x64
-4:
+4:
inb $0x64
andb $0x02, %al
jnz 4b
/* everything failed, so restart from the beginning */
jnz gate_a20_try_bios
ret
-
+
gate_a20_check_state:
/* iterate the checking for a while */
movl $100, %ecx
-1:
+1:
call 3f
cmpb %al, %dl
jz 2f
loop 1b
2:
ret
-3:
+3:
pushl %ebx
pushl %ecx
xorl %eax, %eax
int $0x18
jmp cold_reboot
.code32
-
+
/*
* grub_reboot()
*
FUNCTION(grub_reboot)
call prot_to_real
.code16
-cold_reboot:
+cold_reboot:
/* cold boot */
movw $0x0472, %di
movw %ax, (%di)
ljmp $0xFFFF, $0x0000
.code32
-
+
/*
* grub_halt(int no_apm)
*
call prot_to_real
.code16
-
+
/* detect APM */
movw $0x5300, %ax
xorw %bx, %bx
movw $0x0101, %cx
int $0x15
jc EXT_C(grub_hard_stop)
-
+
/* set the power state to off */
movw $0x5307, %ax
movw $1, %bx
/* shouldn't reach here */
jmp EXT_C(grub_hard_stop)
.code32
-
-
+
+
/*
* void grub_chainloader_real_boot (int drive, void *part_addr)
*
movb %al, %dh
/* enter real mode */
call prot_to_real
-
+
.code16
movb %dh, %ah
movw %cx, %ds
popl %ebp
ret
-
+
/*
* int grub_biosdisk_rw_standard (int ah, int drive, int coff, int hoff,
* int soff, int nsec, int segment)
movw %ax, %di
/* save SEGMENT in %bx */
movw 0x14(%ebp), %bx
-
+
/* enter real mode */
call prot_to_real
xorw %bx, %bx
movw $3, %si /* attempt at least three times */
-1:
+1:
movw %di, %ax
int $0x13 /* do the operation */
jnc 2f /* check if successful */
/* if fail, reset the disk system */
xorw %ax, %ax
int $0x13
-
+
decw %si
cmpw $0, %si
je 2f
xorb %bl, %bl
jmp 1b /* retry */
-2:
+2:
/* back to protected mode */
DATA32 call real_to_prot
.code32
movb %bl, %al /* return value in %eax */
-
+
popl %esi
popl %edi
popl %ebx
movb $0x41, %ah
movw $0x55aa, %bx
int $0x13 /* do the operation */
-
+
/* check the result */
jc 1f
cmpw $0xaa55, %bx
/* check if AH=0x42 is supported */
andw $1, %cx
jnz 2f
-
+
1:
xorb %bl, %bl
2:
popl %esi
popl %ebx
popl %ebp
-
+
ret
/*
* int grub_biosdisk_get_diskinfo_standard (int drive,
- * unsigned long *cylinders,
+ * unsigned long *cylinders,
* unsigned long *heads,
* unsigned long *sectors)
*
/* push HEADS */
pushl %ecx
/* SECTORS is on the stack */
-
+
/* drive */
movb %al, %dl
/* enter real mode */
andb $0x3f, %cl
movzbl %cl, %eax
movl %eax, (%edi)
-
+
xorl %eax, %eax
movb %bl, %al /* return value in %eax */
xorl %edx, %edx
call prot_to_real
-
+
.code16
/* reset the disk system first */
int $0x13
1:
stc
-
+
/* call GET DISK TYPE */
movb $0x15, %ah
int $0x13
jc 2f
- /* check if this drive exists */
+ /* check if this drive exists */
testb $0x3, %ah
jz 2f
movl %edx, %eax
popl %ebp
ret
-
-
+
+
/*
*
* grub_get_memsize(i) : return the memory size in KB. i == 0 for conventional
/* push ADDR */
pushl %eax
-
+
/* place address (+4) in ES:DI */
addl $4, %eax
movl %eax, %edi
popl %ebp
ret
-
+
/*
* void grub_console_real_putchar (int c)
*
movl %eax, %edx
pusha
movb EXT_C(grub_console_cur_color), %bl
-
+
call prot_to_real
.code16
movb %dl, %al
/* save the character and the attribute on the stack */
pushw %ax
pushw %bx
-
+
/* get the current position */
movb $0x3, %ah
int $0x10
/* check the column with the width */
cmpb $79, %dl
jl 2f
-
- /* print CR and LF, if next write will exceed the width */
+
+ /* print CR and LF, if next write will exceed the width */
movw $0x0e0d, %ax
int $0x10
movb $0x0a, %al
int $0x10
-
+
/* get the current position */
movb $0x3, %ah
int $0x10
-2:
+2:
/* restore the character and the attribute */
popw %bx
popw %ax
-
+
/* write the character with the attribute */
movb $0x9, %ah
movw $1, %cx
1: movw $1, %bx
movb $0xe, %ah
int $0x10
-
+
3: DATA32 call real_to_prot
.code32
-
+
popa
ret
-
+
/*
* int grub_console_getkey (void)
.word GRUB_CONSOLE_KEY_PPAGE, GRUB_TERM_PPAGE
.word GRUB_CONSOLE_KEY_NPAGE, GRUB_TERM_NPAGE
.word 0
-
+
/*
* translate_keycode translates the key code %dx to an ascii code.
*/
translate_keycode:
pushw %bx
pushw %si
-
+
#ifdef APPLE_CC
translation_table_abs = ABS (translation_table) - 0x10000
movw $(translation_table_abs), %si
#else
movw $ABS(translation_table), %si
#endif
-
+
1: lodsw
/* check if this is the end */
testw %ax, %ax
ret
.code32
-
+
FUNCTION(grub_console_getkey)
pushl %ebp
movw %ax, %dx /* real_to_prot uses %eax */
call translate_keycode
-
+
DATA32 call real_to_prot
.code32
FUNCTION(grub_console_checkkey)
pushl %ebp
xorl %edx, %edx
-
+
call prot_to_real /* enter real mode */
.code16
int $0x16
jz notpending
-
+
movw %ax, %dx
DATA32 jmp pending
popl %ebp
ret
-
+
/*
* grub_uint16_t grub_console_getxy (void)
* BIOS call "INT 10H Function 03h" to get cursor position
popl %ebp
ret
-
+
/*
* void grub_console_cls (void)
* BIOS call "INT 10H Function 09h" to write character and attribute
popl %ebp
ret
-
+
/*
* void grub_console_setcursor (int on)
* BIOS call "INT 10H Function 01h" to set cursor type
.byte 1
console_cursor_shape:
.word 0
-
+
FUNCTION(grub_console_setcursor)
pushl %ebp
pushl %ebx
/* push ON */
pushl %eax
-
+
/* check if the standard cursor shape has already been saved */
movw console_cursor_shape, %ax
testw %ax, %ax
testl %eax, %eax
jz 2f
movw console_cursor_shape, %cx
-2:
+2:
call prot_to_real
.code16
movb $0x1, %ah
- int $0x10
+ int $0x10
DATA32 call real_to_prot
.code32
popl %ebx
popl %ebp
ret
-
+
/*
* grub_getrtsecs()
* if a seconds value can be read, read it and return it (BCD),
popl %ebp
ret
-
+
/*
* grub_get_rtc()
* return the real time in ticks, of which there are about
xorw %ax, %ax
shrl $4, %eax
mov %eax, %edx /* prot_to_real destroys %eax. */
-
+
call prot_to_real
.code16
movl %edx, %eax
andl $0x0FFFF, %eax /* Return value in %eax. */
-
+
pop %edx
popl %edi
popl %ebp
DATA32 call real_to_prot
.code32
-
+
movw %dx, %ax
andl $0xFFFF, %eax /* Return value in %eax. */
DATA32 call real_to_prot
.code32
-
+
movw %dx, %ax
andl $0xFFFF, %eax /* Return value in %eax. */
DATA32 call real_to_prot
.code32
-
+
movw %dx, %ax
andl $0xFFFF, %eax /* Return value in %eax. */
.code16
movw $0x4f07, %ax
- movw $0x0080, %bx /* BL = 80h, Set Display Start
+ movw $0x0080, %bx /* BL = 80h, Set Display Start
during Vertical Retrace. */
int $0x10
DATA32 call real_to_prot
.code32
-
+
movw %dx, %ax
andl $0xFFFF, %eax /* Return value in %eax. */
DATA32 call real_to_prot
.code32
-
+
movw %dx, %ax
andl $0xFFFF, %eax /* Return value in %eax. */
* Note: These functions defined in this file may be called from C.
* Be careful of that you must not modify some registers. Quote
* from gcc-2.95.2/gcc/config/i386/i386.h:
-
+
1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
registers that can be used without being saved.
/* -- data segment --
* base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
- * type = 32 bit data read/write, DPL = 0
+ * type = 32 bit data read/write, DPL = 0
*/
.word 0xFFFF, 0
.byte 0, 0x92, 0xCF, 0
/* kern/i386/tsc.c - x86 TSC time source implementation
* Requires Pentium or better x86 CPU that supports the RDTSC instruction.
- * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to
+ * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to
* real time.
*
* GRUB -- GRand Unified Bootloader
}
int
-grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
+grub_ieee1275_get_property_length (grub_ieee1275_phandle_t phandle,
const char *prop, grub_ssize_t *length)
{
struct get_property_args
INIT_IEEE1275_COMMON (&args.common, "instance-to-package", 1, 1);
args.ihandle = ihandle;
-
+
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return -1;
*phandlep = args.phandle;
args.phandle = phandle;
args.buf = (grub_ieee1275_cell_t) path;
args.buflen = (grub_ieee1275_cell_t) len;
-
+
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return -1;
if (actual)
args.ihandle = ihandle;
args.buf = (grub_ieee1275_cell_t) path;
args.buflen = (grub_ieee1275_cell_t) len;
-
+
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return -1;
if (actual)
}
int
-grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer,
+grub_ieee1275_write (grub_ieee1275_ihandle_t ihandle, void *buffer,
grub_size_t len, grub_ssize_t *actualp)
{
struct write_args
INIT_IEEE1275_COMMON (&args.common, "release", 2, 0);
args.addr = addr;
args.size = size;
-
+
if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
return -1;
return 0;
modbase = grub_arch_modules_addr ();
modinfo = (struct grub_module_info *) modbase;
-
+
/* Check if there are any modules. */
if ((modinfo == 0) || modinfo->magic != GRUB_MODULE_MAGIC)
return;
{
/* XXX Is it better to check the existence of the device? */
grub_size_t len = grub_strlen (val);
-
+
if (val[0] == '(' && val[len - 1] == ')')
return grub_strndup (val + 1, len - 2);
grub_register_variable_hook ("root", 0, grub_env_write_root);
grub_env_export ("root");
-
+
prefix = grub_env_get ("prefix");
-
+
if (prefix)
{
char *dev;
{
/* Load the module. */
grub_dl_load ("normal");
-
+
/* Something went wrong. Print errors here to let user know why we're entering rescue mode. */
grub_print_error ();
grub_errno = 0;
grub_register_core_commands ();
grub_register_rescue_parser ();
grub_register_rescue_reader ();
-
+
grub_load_config ();
grub_load_normal_mode ();
grub_reader_loop (0);
{
d += n;
s += n;
-
+
while (n--)
*--d = *--s;
}
-
+
return dest;
}
grub_strncpy (char *dest, const char *src, int c)
{
char *p = dest;
-
+
while ((*p++ = *src++) != '\0' && --c)
;
{
va_list ap;
int ret;
-
+
va_start (ap, fmt);
ret = grub_vprintf (fmt, ap);
va_end (ap);
return ret;
-}
+}
#if defined (APPLE_CC) && ! defined (GRUB_UTIL)
int
{
va_list ap;
int ret;
-
+
va_start (ap, fmt);
ret = grub_vprintf (fmt, ap);
va_end (ap);
-
+
return ret;
-}
+}
#endif
#if ! defined (APPLE_CC) && ! defined (GRUB_UTIL)
{
va_list args;
const char *debug = grub_env_get ("debug");
-
+
if (! debug)
return;
-
+
if (grub_strword (debug, "all") || grub_strword (debug, condition))
{
grub_printf ("%s:%d: ", file, line);
{
const char *t1 = s1;
const char *t2 = s2;
-
+
while (n--)
{
if (*t1 != *t2)
{
if (*s1 != *s2)
break;
-
+
s1++;
s2++;
}
{
if (n == 0)
return 0;
-
+
while (*s1 && *s2 && --n)
{
if (*s1 != *s2)
break;
-
+
s1++;
s2++;
}
{
if (grub_tolower (*s1) != grub_tolower (*s2))
break;
-
+
s1++;
s2++;
}
/* Speed up the following searches of needle by caching its first
character. */
char b = *needle++;
-
+
for (;; haystack++)
{
if (*haystack == '\0')
{
unsigned long long num = 0;
int found = 0;
-
+
/* Skip white spaces. */
while (*str && grub_isspace (*str))
str++;
-
+
/* Guess the base, if not specified. The prefix `0x' means 16, and
the prefix `0' means 8. */
if (str[0] == '0')
else if (base == 0 && str[1] >= '0' && str[1] <= '7')
base = 8;
}
-
+
if (base == 0)
base = 10;
grub_error (GRUB_ERR_BAD_NUMBER, "unrecognized number");
return 0;
}
-
+
if (end)
*end = (char *) str;
{
grub_size_t len;
char *p;
-
+
len = grub_strlen (s) + 1;
p = (char *) grub_malloc (len);
if (! p)
{
grub_size_t len;
char *p;
-
+
len = grub_strlen (s);
if (len > n)
len = n;
p = (char *) grub_malloc (len + 1);
if (! p)
return 0;
-
+
grub_memcpy (p, s, len);
p[len] = '\0';
return p;
return ((grub_uint32_t) n) / d;
}
-
+
while (bits--)
{
m <<= 1;
-
+
if (n & (1ULL << 63))
m |= 1;
-
+
q <<= 1;
n <<= 1;
-
+
if (m >= d)
{
q |= 1;
if (r)
*r = m;
-
+
return q;
}
{
unsigned base = (c == 'x') ? 16 : 10;
char *p;
-
+
if ((long long) n < 0 && c == 'd')
{
n = (unsigned long long) (-((long long) n));
do
{
unsigned m;
-
+
n = grub_divmod64 (n, 10, &m);
*p++ = m + '0';
}
while (n);
-
+
*p = 0;
grub_reverse (str);
auto void write_char (unsigned char ch);
auto void write_str (const char *s);
auto void write_fill (const char ch, int n);
-
+
void write_char (unsigned char ch)
{
if (str)
for (i = 0; i < n; i++)
write_char (ch);
}
-
+
while ((c = *fmt++) != 0)
{
if (c != '%')
if (rightfill && grub_strlen (tmp) < format1)
write_fill (zerofill, format1 - grub_strlen (tmp));
break;
-
+
case 'c':
n = va_arg (args, int);
write_char (n & 0xff);
grub_uint32_t code = va_arg (args, grub_uint32_t);
int shift;
unsigned mask;
-
+
if (code <= 0x7f)
{
shift = 0;
}
write_char (mask | (code >> shift));
-
+
for (shift -= 6; shift >= 0; shift -= 6)
write_char (0x80 | (0x3f & (code >> shift)));
}
}
else
write_str ("(null)");
-
+
break;
default:
if (count && !str)
grub_refresh ();
-
+
return count;
}
{
va_list ap;
int ret;
-
+
va_start (ap, fmt);
ret = grub_vsprintf (str, fmt, ap);
va_end (ap);
{
/* Surrogate pair. */
code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000;
-
+
*dest++ = (code >> 18) | 0xF0;
*dest++ = ((code >> 12) & 0x3F) | 0x80;
*dest++ = ((code >> 6) & 0x3F) | 0x80;
grub_uint32_t *p = dest;
int count = 0;
grub_uint32_t code = 0;
-
+
if (srcend)
*srcend = src;
{
if (c == 0)
break;
-
+
if ((c & 0x80) == 0x00)
code = c;
else if ((c & 0xe0) == 0xc0)
if (transition->input == c)
break;
- if (transition->input == ' ' && ! grub_isalpha (c)
+ if (transition->input == ' ' && ! grub_isalpha (c)
&& ! grub_isdigit (c) && c != '_')
break;
vp = varname;
if (! val)
return;
-
+
/* Insert the contents of the variable in the buffer. */
for (; *val; val++)
*(bp++) = *val;
{
grub_parser_state_t newstate;
char use;
-
+
newstate = grub_parser_cmdline_state (state, *rd, &use);
/* If a variable was being processed and this character does
/* A special case for when the last character was part of a
variable. */
add_var (GRUB_PARSER_STATE_TEXT);
-
+
/* Reserve memory for the return values. */
args = grub_malloc (bp - buffer);
if (! args)
return grub_errno;
grub_memcpy (args, buffer, bp - buffer);
-
+
*argv = grub_malloc (sizeof (char *) * (*argc + 1));
if (! *argv)
{
grub_partition_map_unregister (grub_partition_map_t partmap)
{
grub_partition_map_t *p, q;
-
+
for (p = &grub_partition_map_list, q = *p; q; p = &(q->next), q = q->next)
if (q == partmap)
{
{
grub_partition_map_t partmap = 0;
int ret = 0;
-
+
auto int part_map_iterate (const grub_partition_map_t p);
auto int part_map_iterate_hook (grub_disk_t d,
const grub_partition_t partition);
{
return 1;
}
-
+
int part_map_iterate (const grub_partition_map_t p)
{
grub_dprintf ("partition", "Detecting %s...\n", p->name);
grub_partition_map_iterate (part_map_iterate);
if (partmap)
ret = partmap->iterate (disk, hook);
-
+
return ret;
}
Elf32_Sym *symtab;
Elf32_Word entsize;
unsigned i;
-
+
/* Find a symbol table. */
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
+
symtab = (Elf32_Sym *) ((char *) e + s->sh_offset);
entsize = s->sh_entsize;
-
+
for (i = 0, s = (Elf32_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf32_Shdr *) ((char *) s + e->e_shentsize))
if (seg)
{
Elf32_Rela *rel, *max;
-
+
for (rel = (Elf32_Rela *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
Elf32_Word *addr;
Elf32_Sym *sym;
grub_uint32_t value;
-
+
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
-
+
addr = (Elf32_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf32_Sym *) ((char *) symtab
+ entsize * ELF32_R_SYM (rel->r_info));
-
+
/* On the PPC the value does not have an explicit
addend, add it. */
value = sym->st_value + rel->r_addend;
case R_PPC_ADDR16_LO:
*(Elf32_Half *) addr = value;
break;
-
+
case R_PPC_REL24:
{
Elf32_Sword delta = value - (Elf32_Word) addr;
-
+
if (delta << 6 >> 6 != delta)
return grub_error (GRUB_ERR_BAD_MODULE, "Relocation overflow");
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
break;
}
-
+
case R_PPC_ADDR16_HA:
*(Elf32_Half *) addr = (value + 0x8000) >> 16;
break;
-
+
case R_PPC_ADDR32:
*addr = value;
break;
-
+
case R_PPC_REL32:
*addr = value - (Elf32_Word) addr;
break;
-
+
default:
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"This relocation (%d) is not implemented yet",
}
}
}
-
+
return GRUB_ERR_NONE;
}
Elf64_Sym *symtab;
Elf64_Word entsize;
unsigned i;
-
+
/* Find a symbol table. */
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
if (i == e->e_shnum)
return grub_error (GRUB_ERR_BAD_MODULE, "no symtab found");
-
+
symtab = (Elf64_Sym *) ((char *) e + s->sh_offset);
entsize = s->sh_entsize;
-
+
for (i = 0, s = (Elf64_Shdr *) ((char *) e + e->e_shoff);
i < e->e_shnum;
i++, s = (Elf64_Shdr *) ((char *) s + e->e_shentsize))
if (seg)
{
Elf64_Rela *rel, *max;
-
+
for (rel = (Elf64_Rela *) ((char *) e + s->sh_offset),
max = rel + s->sh_size / s->sh_entsize;
rel < max;
Elf64_Word *addr;
Elf64_Sym *sym;
Elf64_Addr value;
-
+
if (seg->size < rel->r_offset)
return grub_error (GRUB_ERR_BAD_MODULE,
"reloc offset is out of the segment");
-
+
addr = (Elf64_Word *) ((char *) seg->addr + rel->r_offset);
sym = (Elf64_Sym *) ((char *) symtab
+ entsize * ELF64_R_SYM (rel->r_info));
}
}
}
-
+
return GRUB_ERR_NONE;
}
{
.name = "terminal_input"
};
-
+
struct grub_handler_class grub_term_output_class =
{
.name = "terminal_output"
};
-
+
#define grub_cur_term_input grub_term_get_current_input ()
#define grub_cur_term_output grub_term_get_current_output ()
if (code == '\t' && grub_cur_term_output->getxy)
{
int n;
-
+
n = 8 - ((grub_getxy () >> 8) & 7);
while (n--)
grub_putcode (' ');
return;
}
-
+
(grub_cur_term_output->putchar) (code);
-
+
if (code == '\n')
{
grub_putcode ('\r');
grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
key = grub_getkey ();
-
+
/* Remove the message. */
grub_gotoxy (1, height - 1);
grub_printf (" ");
grub_gotoxy (pos >> 8, pos & 0xFF);
-
+
/* Scroll one lines or an entire page, depending on the key. */
if (key == '\r' || key =='\n')
grub_more_lines--;
buf[size++] = c;
ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
-
+
if (ret > 0)
{
size = 0;
(grub_cur_term_output->setcursor) (on);
cursor_state = on;
}
-
+
return ret;
}
grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
return 0;
}
-
+
envblk = grub_malloc (sizeof (*envblk));
if (envblk)
{
envblk->buf = buf;
envblk->size = size;
}
-
+
return envblk;
}
{
int n = 0;
char *p;
-
+
for (p = (char *) value; *p; p++)
{
if (*p == '\\' || *p == '\n')
else
n++;
}
-
+
return n;
}
else
p++;
}
-
+
return p + 1;
}
vl = escaped_value_len (value);
p = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
pend = envblk->buf + envblk->size;
-
+
/* First, look at free space. */
for (space = pend - 1; *space == '#'; space--)
;
if (grub_memcmp (p, name, nl) == 0 && p[nl] == '=')
{
int len;
-
+
/* Found the same name. */
p += nl + 1;
-
+
/* Check the length of the current value. */
len = 0;
while (p + len < pend && p[len] != '\n')
if (! found)
{
/* Append a new variable. */
-
+
if (pend - space < nl + 1 + vl + 1)
/* No space. */
return 0;
{
if (value[i] == '\\' || value[i] == '\n')
*p++ = '\\';
-
+
*p++ = value[i];
}
}
p = find_next_line (p, pend);
- }
+ }
}
void
else
p++;
}
-
+
if (p >= pend)
/* Broken. */
return;
return;
value = name + (value_start - name_start);
-
+
grub_memcpy (name, name_start, name_end - name_start);
name[name_end - name_start] = '\0';
-
+
for (p = value_start, q = value; *p != '\n'; ++p)
{
if (*p == '\\')
*q++ = *p;
}
*q = '\0';
-
+
ret = hook (name, value);
grub_free (name);
if (ret)
return;
}
-
+
p = find_next_line (p, pend);
}
}
#include <grub/symbol.h>
.file "setjmp.S"
-
+
.text
-
+
/*
* int grub_setjmp (grub_jmp_buf env)
*/
xorl %eax, %eax
jmp *%ecx
-
+
/*
* int grub_longjmp (grub_jmp_buf env, int val)
*/
jnz 1f
incl %eax
1: jmp *%ecx
-
+
grub_chainloader_unload (void)
{
grub_efi_boot_services_t *b;
-
+
b = grub_efi_system_table->boot_services;
efi_call_1 (b->unload_image, image_handle);
efi_call_2 (b->free_pages, address, pages);
grub_free (file_path);
grub_free (cmdline);
cmdline = 0;
-
+
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
}
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
grub_efi_char16_t *exit_data;
-
+
b = grub_efi_system_table->boot_services;
status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
if (status != GRUB_EFI_SUCCESS)
if (exit_data)
{
char *buf;
-
+
buf = grub_malloc (exit_data_size * 4 + 1);
if (buf)
{
*grub_utf16_to_utf8 ((grub_uint8_t *) buf,
exit_data, exit_data_size) = 0;
-
+
grub_error (GRUB_ERR_BAD_OS, buf);
grub_free (buf);
}
efi_call_1 (b->free_pool, exit_data);
grub_chainloader_unload ();
-
+
return grub_errno;
}
{
grub_efi_char16_t *p;
grub_efi_uint16_t size;
-
+
fp->header.type = GRUB_EFI_MEDIA_DEVICE_PATH_TYPE;
fp->header.subtype = GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE;
size = len * sizeof (grub_efi_char16_t) + sizeof (*fp);
grub_error (GRUB_ERR_BAD_FILENAME, "invalid EFI file path");
return 0;
}
-
+
size = 0;
d = dp;
while (1)
break;
d = GRUB_EFI_NEXT_DEVICE_PATH (d);
}
-
+
file_path = grub_malloc (size
+ ((grub_strlen (dir_start) + 1)
* sizeof (grub_efi_char16_t))
return 0;
grub_memcpy (file_path, dp, size);
-
+
/* Fill the file path for the directory. */
d = (grub_efi_device_path_t *) ((char *) file_path
+ ((char *) d - (char *) dp));
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
filename = argv[0];
-
+
grub_dl_ref (my_mod);
/* Initialize some global variables. */
address = 0;
image_handle = 0;
file_path = 0;
-
+
b = grub_efi_system_table->boot_services;
file = grub_file_open (filename);
if (dev_handle)
dp = grub_efi_get_device_path (dev_handle);
}
-
+
if (! dev->disk || ! dev_handle || ! dp)
{
grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
grub_printf ("file path: ");
grub_efi_print_device_path (file_path);
-
+
size = grub_file_size (file);
pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12);
-
+
status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES,
GRUB_EFI_LOADER_CODE,
pages, &address);
grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources");
else
grub_error (GRUB_ERR_BAD_OS, "cannot load image");
-
+
goto fail;
}
goto fail;
}
loaded_image->device_handle = dev_handle;
-
+
grub_file_close (file);
if (argc > 1)
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
return 0;
-
+
fail:
if (dev)
grub_device_close (dev);
-
+
if (file)
grub_file_close (file);
if (file_path)
grub_free (file_path);
-
+
if (address)
efi_call_2 (b->free_pages, address, pages);
-
+
grub_dl_unref (my_mod);
return grub_errno;
int NESTED_FUNC_ATTR hook (grub_uint64_t addr, grub_uint64_t size,
grub_uint32_t type)
{
- /* FreeBSD assumes that first 64KiB are available.
+ /* FreeBSD assumes that first 64KiB are available.
Not always true but try to prevent panic somehow. */
if (isfirstrun && addr != 0)
{
mmap++;
}
else
- len += sizeof (struct grub_e820_mmap);
+ len += sizeof (struct grub_e820_mmap);
}
isfirstrun = 0;
if (mmap)
for (i = 0; i < mmap - mmap_buf; i++)
grub_dprintf ("bsd", "smap %d, %d:%llx - %llx\n", i,
mmap_buf[i].type,
- (unsigned long long) mmap_buf[i].addr,
+ (unsigned long long) mmap_buf[i].addr,
(unsigned long long) mmap_buf[i].size);
-
+
grub_dprintf ("bsd", "%d entries in smap\n", mmap - mmap_buf);
grub_freebsd_add_meta (FREEBSD_MODINFO_METADATA |
FREEBSD_MODINFOMD_SMAP, mmap_buf, len);
if (is_64bit)
{
- grub_uint64_t addr64 = addr, size64 = size;
+ grub_uint64_t addr64 = addr, size64 = size;
if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
grub_strlen (type) + 1)) ||
- (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr64,
+ (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr64,
sizeof (addr64))) ||
- (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size64,
+ (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size64,
sizeof (size64))))
return grub_errno;
}
{
if ((grub_freebsd_add_meta (FREEBSD_MODINFO_TYPE, type,
grub_strlen (type) + 1)) ||
- (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr,
+ (grub_freebsd_add_meta (FREEBSD_MODINFO_ADDR, &addr,
sizeof (addr))) ||
- (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size,
+ (grub_freebsd_add_meta (FREEBSD_MODINFO_SIZE, &size,
sizeof (size))))
return grub_errno;
}
gdtdesc->base = gdt;
/* Prepare trampoline. */
- trampoline = (grub_uint8_t *) (kern_end - 4096 + 24
+ trampoline = (grub_uint8_t *) (kern_end - 4096 + 24
+ sizeof (struct gdt_descriptor));
- launch_trampoline = (void __attribute__ ((cdecl, regparm (0)))
+ launch_trampoline = (void __attribute__ ((cdecl, regparm (0)))
(*) (grub_addr_t entry, ...)) trampoline;
grub_bsd64_trampoline_gdt = (grub_uint32_t) gdtdesc;
- grub_bsd64_trampoline_selfjump
+ grub_bsd64_trampoline_selfjump
= (grub_uint32_t) (trampoline + 6
- + ((grub_uint8_t *) &grub_bsd64_trampoline_selfjump
+ + ((grub_uint8_t *) &grub_bsd64_trampoline_selfjump
- &grub_bsd64_trampoline_start));
/* Copy trampoline. */
- grub_memcpy (trampoline, &grub_bsd64_trampoline_start,
+ grub_memcpy (trampoline, &grub_bsd64_trampoline_start,
&grub_bsd64_trampoline_end - &grub_bsd64_trampoline_start);
/* Launch trampoline. */
- launch_trampoline (entry, entry_hi, pagetable, bi.bi_modulep,
+ launch_trampoline (entry, entry_hi, pagetable, bi.bi_modulep,
kern_end);
}
else
case GRUB_MACHINE_MEMORY_AVAILABLE:
pm->type = OPENBSD_MMAP_AVAILABLE;
break;
-
+
default:
pm->type = OPENBSD_MMAP_RESERVED;
break;
(part << OPENBSD_B_PARTSHIFT));
grub_unix_real_boot (entry, bootflags, bootdev, OPENBSD_BOOTARG_APIVER,
- 0, grub_mmap_get_upper () >> 10,
+ 0, grub_mmap_get_upper () >> 10,
grub_mmap_get_lower () >> 10,
(char *) pa - buf, buf);
bootinfo->bi_data[0] = rootdev;
grub_unix_real_boot (entry, bootflags, 0, bootinfo,
- 0, grub_mmap_get_upper () >> 10,
+ 0, grub_mmap_get_upper () >> 10,
grub_mmap_get_lower () >> 10);
/* Not reached. */
*/
#include <grub/symbol.h>
-
+
.p2align 2
-
+
.code32
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Based on the code from FreeBSD originally distributed under the
+/* Based on the code from FreeBSD originally distributed under the
following terms: */
/*-
pt4 = (grub_uint64_t *) target;
pt3 = (grub_uint64_t *) (target + 4096);
pt2 = (grub_uint64_t *) (target + 8192);
-
+
grub_memset ((char *) target, 0, 4096 * 3);
/*
* This is kinda brutal, but every single 1GB VM memory segment points to
- * the same first 1GB of physical memory. But it is how BSD expects
+ * the same first 1GB of physical memory. But it is how BSD expects
* it to be.
*/
for (i = 0; i < 512; i++)
/* Each slot of the level 3 pages points to the same level 2 page */
pt3[i] = (grub_addr_t) &pt2[0];
pt3[i] |= PG_V | PG_RW | PG_U;
-
+
/* The level 2 page slots are mapped with 2MB pages for 1GB. */
pt2[i] = i * (2 * 1024 * 1024);
pt2[i] |= PG_V | PG_RW | PG_PS | PG_U;
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
-/* Based on the code from FreeBSD originally distributed under the
+/* Based on the code from FreeBSD originally distributed under the
following terms: */
/*-
* $FreeBSD$
*/
-
+
#define MSR_EFER 0xc0000080
#define EFER_LME 0x00000100
#define CR4_PAE 0x00000020
#include <grub/symbol.h>
.p2align 2
-
- .code32
-
+ .code32
+
+
VARIABLE(grub_bsd64_trampoline_start)
/* Discard `grub_unix_real_boot' return address. */
.byte 0x15
VARIABLE (grub_bsd64_trampoline_gdt)
.long 0x0
-
+
/* ljmp */
.byte 0xea
VARIABLE (grub_bsd64_trampoline_selfjump)
if (mmap_size != 0)
return mmap_size;
-
+
mmap_size = (1 << 12);
while (1)
{
int ret;
grub_efi_memory_descriptor_t *mmap;
grub_efi_uintn_t desc_size;
-
+
mmap = grub_malloc (mmap_size);
if (! mmap)
return 0;
ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0);
grub_free (mmap);
-
+
if (ret < 0)
grub_fatal ("cannot get memory map");
else if (ret > 0)
grub_efi_free_pages ((grub_addr_t) prot_mode_mem, prot_mode_pages);
prot_mode_mem = 0;
}
-
+
if (initrd_mem)
{
grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
grub_efi_uintn_t mmap_size, tmp_mmap_size;
grub_efi_memory_descriptor_t *desc;
grub_size_t real_size;
-
+
/* Make sure that each size is aligned to a page boundary. */
real_size = GRUB_LINUX_CL_END_OFFSET;
prot_size = page_align (prot_size);
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
-
+
/* Calculate the number of pages; Combine the real mode code with
the memory map buffer for simplicity. */
real_mode_pages = ((real_size + mmap_size) >> 12);
prot_mode_pages = (prot_size >> 12);
-
+
/* Initialize the memory pointers with NULL for convenience. */
real_mode_mem = 0;
prot_mode_mem = 0;
-
+
/* Read the memory map temporarily, to find free space. */
mmap = grub_malloc (mmap_size);
if (! mmap)
grub_fatal ("cannot get memory map");
mmap_end = NEXT_MEMORY_DESCRIPTOR (mmap, tmp_mmap_size);
-
+
/* First, find free pages for the real mode code
and the memory map buffer. */
for (desc = mmap;
{
grub_efi_physical_address_t physical_end;
grub_efi_physical_address_t addr;
-
+
physical_end = desc->physical_start + (desc->num_pages << 12);
if (physical_end > 0x90000)
physical_end = 0x90000;
real_mode_mem = grub_efi_allocate_pages (addr, real_mode_pages);
if (! real_mode_mem)
grub_fatal ("cannot allocate pages");
-
+
desc->num_pages -= real_mode_pages;
break;
}
}
mmap_buf = (void *) ((char *) real_mode_mem + real_size);
-
+
/* Next, find free pages for the protected mode code. */
/* XXX what happens if anything is using this address? */
prot_mode_mem = grub_efi_allocate_pages (0x100000, prot_mode_pages + 1);
grub_efi_uintn_t desc_size;
grub_efi_uint32_t desc_version;
int e820_num;
-
+
params = real_mode_mem;
grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
}
#ifdef __x86_64__
-
- grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
- grub_linux_trampoline_start,
+
+ grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
+ grub_linux_trampoline_start,
grub_linux_trampoline_end - grub_linux_trampoline_start);
-
- ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+
+ ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+ (prot_mode_pages << 12)))
(params->code32_start, real_mode_mem);
/* Hardware interrupts are not safe any longer. */
asm volatile ("cli" : : );
-
+
/* Load the IDT and the GDT for the bootstrap. */
asm volatile ("lidt %0" : : "m" (idt_desc));
asm volatile ("lgdt %0" : : "m" (gdt_desc));
/* Enter Linux. */
asm volatile ("jmp *%%ecx" : : );
-
+
#endif
/* Never reach here. */
char *dest;
grub_dl_ref (my_mod);
-
+
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
}
setup_sects = lh.setup_sects;
-
+
/* If SETUP_SECTS is not set, set it to the default (4). */
if (! setup_sects)
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
-
+
if (! allocate_pages (prot_size))
goto fail;
-
+
params = (struct linux_kernel_params *) real_mode_mem;
grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
space. */
params->ext_mem = ((32 * 0x100000) >> 10);
params->alt_mem = ((32 * 0x100000) >> 10);
-
+
params->video_cursor_x = grub_getxy () >> 8;
params->video_cursor_y = grub_getxy () & 0xff;
params->video_page = 0; /* ??? */
grub_memset (params->padding7, 0, sizeof (params->padding7));
grub_memset (params->padding8, 0, sizeof (params->padding8));
grub_memset (params->padding9, 0, sizeof (params->padding9));
-
+
#endif
/* The other EFI parameters are filled when booting. */
if (grub_memcmp (argv[i], "mem=", 4) == 0)
{
char *val = argv[i] + 4;
-
+
linux_mem_size = grub_strtoul (val, &val, 0);
-
+
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
else
{
int shift = 0;
-
+
switch (grub_tolower (val[0]))
{
case 'g':
dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
"BOOT_IMAGE=");
dest = grub_stpcpy (dest, argv[0]);
-
+
/* Copy kernel parameters. */
for (i = 1;
i < argc
}
fail:
-
+
if (file)
grub_file_close (file);
grub_efi_memory_descriptor_t *desc;
grub_efi_uintn_t desc_size;
struct linux_kernel_header *lh;
-
+
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
goto fail;
}
-
+
if (! loaded)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
initrd_pages = (page_align (size) >> 12);
lh = (struct linux_kernel_header *) real_mode_mem;
-
+
addr_max = (grub_cpu_to_le32 (lh->initrd_addr_max) << 10);
if (linux_mem_size != 0 && linux_mem_size < addr_max)
addr_max = linux_mem_size;
-
+
/* Linux 2.3.xx has a bug in the memory range check, so avoid
the last page.
Linux 2.2.xx has a bug in the memory range check, which is
/* Usually, the compression ratio is about 50%. */
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+ page_align (size);
-
+
/* Find the highest address to put the initrd. */
mmap_size = find_mmap_size ();
if (grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0) <= 0)
&& desc->num_pages >= initrd_pages)
{
grub_efi_physical_address_t physical_end;
-
+
physical_end = desc->physical_start + (desc->num_pages << 12);
if (physical_end > addr_max)
physical_end = addr_max;
grub_error (GRUB_ERR_OUT_OF_MEMORY, "no free pages available");
goto fail;
}
-
+
initrd_mem = grub_efi_allocate_pages (addr, initrd_pages);
if (! initrd_mem)
grub_fatal ("cannot allocate pages");
-
+
if (grub_file_read (file, initrd_mem, size) != size)
{
grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
grub_printf (" [Initrd, addr=0x%x, size=0x%x]\n",
(unsigned) addr, (unsigned) size);
-
+
lh->ramdisk_image = addr;
lh->ramdisk_size = size;
lh->root_dev = 0x0100; /* XXX */
-
+
fail:
if (file)
grub_file_close (file);
count++;
return 0;
}
-
+
grub_mmap_iterate (hook);
-
+
mmap_size = count * sizeof (struct grub_e820_mmap);
/* Increase the size a bit for safety, because GRUB allocates more on
later. */
mmap_size += (1 << 12);
-
+
return page_align (mmap_size);
}
grub_dprintf ("linux", "real_size = %x, prot_size = %x, mmap_size = %x\n",
(unsigned) real_size, (unsigned) prot_size, (unsigned) mmap_size);
-
+
/* Calculate the number of pages; Combine the real mode code with
the memory map buffer for simplicity. */
real_mode_pages = ((real_size + mmap_size) >> 12);
prot_mode_pages = (prot_size >> 12);
-
+
/* Initialize the memory pointers with NULL for convenience. */
free_pages ();
-
+
/* FIXME: Should request low memory from the heap when this feature is
implemented. */
modevar = grub_env_get ("gfxpayload");
- /* Now all graphical modes are acceptable.
+ /* Now all graphical modes are acceptable.
May change in future if we have modes without framebuffer. */
if (modevar && *modevar != 0)
{
- tmp = grub_malloc (grub_strlen (modevar)
+ tmp = grub_malloc (grub_strlen (modevar)
+ sizeof (DEFAULT_VIDEO_MODE) + 1);
if (! tmp)
return grub_errno;
params->video_width = 80;
params->video_height = 25;
}
-
+
grub_dprintf ("linux", "code32_start = %x, idt_desc = %lx, gdt_desc = %lx\n",
(unsigned) params->code32_start,
(unsigned long) &(idt_desc.limit),
#ifdef __x86_64__
- grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
- grub_linux_trampoline_start,
+ grub_memcpy ((char *) prot_mode_mem + (prot_mode_pages << 12),
+ grub_linux_trampoline_start,
grub_linux_trampoline_end - grub_linux_trampoline_start);
-
- ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+
+ ((void (*) (unsigned long, void *)) ((char *) prot_mode_mem
+ (prot_mode_pages << 12)))
(params->code32_start, real_mode_mem);
#else
/* Hardware interrupts are not safe any longer. */
asm volatile ("cli" : : );
-
+
/* Load the IDT and the GDT for the bootstrap. */
asm volatile ("lidt %0" : : "m" (idt_desc));
asm volatile ("lgdt %0" : : "m" (gdt_desc));
/* Enter Linux. */
asm volatile ("jmp *%%ecx" : : );
-
+
#endif
/* Never reach here. */
char *dest;
grub_dl_ref (my_mod);
-
+
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
}
setup_sects = lh.setup_sects;
-
+
/* If SETUP_SECTS is not set, set it to the default (4). */
if (! setup_sects)
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
-
+
if (! allocate_pages (prot_size))
goto fail;
-
+
params = (struct linux_kernel_params *) real_mode_mem;
grub_memset (params, 0, GRUB_LINUX_CL_END_OFFSET);
grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
space. */
params->ext_mem = ((32 * 0x100000) >> 10);
params->alt_mem = ((32 * 0x100000) >> 10);
-
+
params->video_page = 0; /* ??? */
params->video_mode = 0;
params->video_ega_bx = 0;
grub_env_set ("gfxpayload", "text");
grub_printf ("%s is deprecated. "
"Use set gfxpayload=text before "
- "linux command instead.\n",
- argv[i]);
+ "linux command instead.\n",
+ argv[i]);
break;
case 1:
grub_env_set ("gfxpayload", "text");
grub_printf ("%s is deprecated. "
"Use set gfxpayload=text before "
- "linux command instead.\n",
- argv[i]);
+ "linux command instead.\n",
+ argv[i]);
break;
default:
/* Ignore invalid values. */
grub_env_set ("gfxpayload", "text");
grub_printf ("%s is deprecated. Mode %d isn't recognized. "
"Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] before "
- "linux command instead.\n",
- argv[i], vid_mode);
+ "linux command instead.\n",
+ argv[i], vid_mode);
break;
}
buf = grub_malloc (sizeof ("WWWWxHHHHxDD;WWWWxHHHH"));
if (! buf)
goto fail;
-
- linux_mode
+
+ linux_mode
= &linux_vesafb_modes[vid_mode - GRUB_LINUX_VID_MODE_VESA_START];
-
- grub_sprintf (buf, "%ux%ux%u;%ux%u",
+
+ grub_sprintf (buf, "%ux%ux%u;%ux%u",
linux_vesafb_res[linux_mode->res_index].width,
linux_vesafb_res[linux_mode->res_index].height,
linux_mode->depth,
linux_vesafb_res[linux_mode->res_index].height);
grub_printf ("%s is deprecated. "
"Use set gfxpayload=%s before "
- "linux command instead.\n",
- argv[i], buf);
+ "linux command instead.\n",
+ argv[i], buf);
err = grub_env_set ("gfxpayload", buf);
grub_free (buf);
if (err)
if (grub_memcmp (argv[i], "mem=", 4) == 0)
{
char *val = argv[i] + 4;
-
+
linux_mem_size = grub_strtoul (val, &val, 0);
-
+
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
else
{
int shift = 0;
-
+
switch (grub_tolower (val[0]))
{
case 'g':
linux_mem_size <<= shift;
}
}
-
+
/* Specify the boot file. */
dest = grub_stpcpy ((char *) real_mode_mem + GRUB_LINUX_CL_OFFSET,
"BOOT_IMAGE=");
dest = grub_stpcpy (dest, argv[0]);
-
+
/* Copy kernel parameters. */
for (i = 1;
i < argc
}
fail:
-
+
if (file)
grub_file_close (file);
grub_addr_t addr_min, addr_max;
grub_addr_t addr;
struct linux_kernel_header *lh;
-
+
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
goto fail;
}
-
+
if (! loaded)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
}
else
addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS;
-
+
if (linux_mem_size != 0 && linux_mem_size < addr_max)
addr_max = linux_mem_size;
-
+
/* Linux 2.3.xx has a bug in the memory range check, so avoid
the last page.
Linux 2.2.xx has a bug in the memory range check, which is
/* Usually, the compression ratio is about 50%. */
addr_min = (grub_addr_t) prot_mode_mem + ((prot_mode_pages * 3) << 12)
+ page_align (size);
-
+
if (addr_max > grub_os_area_addr + grub_os_area_size)
addr_max = grub_os_area_addr + grub_os_area_size;
grub_error (GRUB_ERR_OUT_OF_RANGE, "The initrd is too big");
goto fail;
}
-
+
initrd_mem = (void *) addr;
-
+
if (grub_file_read (file, initrd_mem, size) != size)
{
grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
grub_printf (" [Initrd, addr=0x%x, size=0x%x]\n",
(unsigned) addr, (unsigned) size);
-
+
lh->ramdisk_image = addr;
lh->ramdisk_size = size;
lh->root_dev = 0x0100; /* XXX */
-
+
fail:
if (file)
grub_file_close (file);
*/
#include <grub/symbol.h>
-
+
.p2align 4 /* force 16-byte alignment */
VARIABLE(grub_linux_trampoline_start)
contains real memory start. */
mov %rsi, %rbx
-
+
call base
-base:
+base:
pop %rsi
-#ifdef APPLE_CC
+#ifdef APPLE_CC
lea (cont1 - base) (%esi, 1), %rax
mov %eax, (jump_vector - base) (%esi, 1)
lea (gdt - base) (%esi, 1), %rax
mov %rax, (gdtaddr - base) (%esi, 1)
-
+
/* Switch to compatibility mode. */
lidt (idtdesc - base) (%esi, 1)
lgdt (gdtdesc - base) (%esi, 1)
-
+
/* Update %cs. Thanks to David Miller for pointing this mistake out. */
ljmp *(jump_vector - base) (%esi, 1)
#else
lea (gdt - base) (%rsi, 1), %rax
mov %rax, (gdtaddr - base) (%rsi, 1)
-
+
/* Switch to compatibility mode. */
lidt (idtdesc - base) (%rsi, 1)
lgdt (gdtdesc - base) (%rsi, 1)
-
+
/* Update %cs. Thanks to David Miller for pointing this mistake out. */
ljmp *(jump_vector - base) (%rsi, 1)
#endif
-
+
cont1:
.code32
/* Update other registers. */
mov $0x18, %eax
- mov %eax, %ds
+ mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
mov %eax, %cr4
jmp cont2
-cont2:
+cont2:
.code32
-
+
mov %ebx, %esi
jmp *%edi
/* GDT. */
.p2align 4
-gdt:
+gdt:
/* NULL. */
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
+
/* Reserved. */
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
+
/* Code segment. */
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
-
+
/* Data segment. */
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
-gdtdesc:
+gdtdesc:
.word 31
-gdtaddr:
+gdtaddr:
.quad gdt
-idtdesc:
+idtdesc:
.word 0
-idtaddr:
+idtaddr:
.quad 0
.p2align 4
jump_vector:
/* Jump location. Is filled by the code */
.long 0
- .long 0x10
+ .long 0x10
VARIABLE(grub_linux_trampoline_end)
grub_free ((void *) mbi->cmdline);
grub_free (mbi);
}
-
+
mbi = 0;
grub_dl_unref (my_mod);
count++;
return 0;
}
-
+
grub_mmap_iterate (hook);
-
+
return count * sizeof (struct grub_multiboot_mmap_entry);
}
grub_file_read (file, (void *) grub_multiboot_payload_orig, load_size);
if (grub_errno)
goto fail;
-
+
if (header->bss_end_addr)
grub_memset ((void *) (grub_multiboot_payload_orig + load_size), 0,
header->bss_end_addr - header->load_addr - load_size);
-
+
grub_multiboot_payload_entry_offset = header->entry_addr - header->load_addr;
}
mbi_dest = mbi_addr (grub_multiboot_payload_dest);
grub_memset (mbi, 0, sizeof (struct grub_multiboot_info));
mbi->mmap_length = mmap_length;
-
+
grub_fill_multiboot_mmap (mmap_addr (grub_multiboot_payload_orig));
/* FIXME: grub_uint32_t will break for addresses above 4 GiB, but is mandated
&grub_multiboot_backward_relocator, RELOCATOR_SIZEOF(backward));
entry = (grub_addr_t) grub_multiboot_payload_orig + grub_multiboot_payload_size;
}
-
+
grub_dprintf ("multiboot_loader", "dest=%p, size=0x%x, entry_offset=0x%x\n",
(void *) grub_multiboot_payload_dest,
grub_multiboot_payload_size,
mbi->flags |= MULTIBOOT_INFO_CMDLINE;
mbi->cmdline = (grub_uint32_t) cmdline_addr (grub_multiboot_payload_dest);
-
-
+
+
grub_strcpy (boot_loader_name_addr (grub_multiboot_payload_orig), PACKAGE_STRING);
mbi->flags |= MULTIBOOT_INFO_BOOT_LOADER_NAME;
mbi->boot_loader_name = (grub_uint32_t) boot_loader_name_addr (grub_multiboot_payload_dest);
|| ehdr->e_ident[EI_DATA] != ELFDATA2LSB
|| ehdr->e_machine != E_MACHINE)
return grub_error(GRUB_ERR_UNKNOWN_OS, "no valid ELF header found");
-
+
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
return grub_error (GRUB_ERR_UNKNOWN_OS, "invalid ELF file type");
-
+
/* FIXME: Should we support program headers at strange locations? */
if (ehdr->e_phoff + ehdr->e_phnum * ehdr->e_phentsize > MULTIBOOT_SEARCH)
return grub_error (GRUB_ERR_BAD_OS, "program header at a too high offset");
if (phdr(i)->p_type == PT_LOAD && phdr(i)->p_filesz != 0)
{
/* Beware that segment 0 isn't necessarily loadable */
- if (lowest_segment == -1
+ if (lowest_segment == -1
|| phdr(i)->p_paddr < phdr(lowest_segment)->p_paddr)
lowest_segment = i;
if (highest_segment == -1
}
for (i = 0; i < ehdr->e_phnum; i++)
- if (phdr(i)->p_vaddr <= ehdr->e_entry
+ if (phdr(i)->p_vaddr <= ehdr->e_entry
&& phdr(i)->p_vaddr + phdr(i)->p_memsz > ehdr->e_entry)
{
grub_multiboot_payload_entry_offset = (ehdr->e_entry - phdr(i)->p_vaddr)
#include <grub/symbol.h>
#include <multiboot.h>
#include <multiboot2.h>
-
+
.p2align 2 /* force 4-byte alignment */
/*
/* Move the magic value into eax. */
movl $MULTIBOOT_MAGIC2, %eax
-
+
/* Jump to the relocator. */
popl %ebp
jmp *%ebp
void *part_addr = 0;
grub_dl_ref (my_mod);
-
+
file = grub_file_open (filename);
if (! file)
goto fail;
if (dev)
{
grub_disk_t disk = dev->disk;
-
+
if (disk)
{
grub_partition_t p = disk->partition;
-
+
/* In i386-pc, the id is equal to the BIOS drive number. */
drive = (int) disk->id;
grub_device_close (dev);
}
-
+
/* Ignore errors. Perhaps it's not fatal. */
grub_errno = GRUB_ERR_NONE;
boot_drive = drive;
boot_part_addr = part_addr;
-
+
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 1);
return;
-
+
fail:
if (file)
grub_file_close (file);
-
+
grub_dl_unref (my_mod);
}
argc--;
argv++;
}
-
+
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no file specified");
else
char *dest;
grub_dl_ref (my_mod);
-
+
if (argc == 0)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "no kernel specified");
grub_linux_is_bzimage = 0;
setup_sects = lh.setup_sects;
linux_mem_size = 0;
-
+
if (lh.header == grub_cpu_to_le32 (GRUB_LINUX_MAGIC_SIGNATURE)
&& grub_le_to_cpu16 (lh.version) >= 0x0200)
{
grub_linux_is_bzimage = (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL);
lh.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE;
-
+
/* Put the real mode part at as a high location as possible. */
- grub_linux_real_addr
+ grub_linux_real_addr
= (char *) UINT_TO_PTR (grub_mmap_get_lower ()
- GRUB_LINUX_SETUP_MOVE_SIZE);
/* But it must not exceed the traditional area. */
if (grub_linux_real_addr > (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR)
grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
-
+
if (grub_le_to_cpu16 (lh.version) >= 0x0201)
{
lh.heap_end_ptr = grub_cpu_to_le16 (GRUB_LINUX_HEAP_END_OFFSET);
lh.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP;
}
-
+
if (grub_le_to_cpu16 (lh.version) >= 0x0202)
lh.cmd_line_ptr = grub_linux_real_addr + GRUB_LINUX_CL_OFFSET;
else
/* Your kernel is quite old... */
lh.cl_magic = grub_cpu_to_le16 (GRUB_LINUX_CL_MAGIC);
lh.cl_offset = grub_cpu_to_le16 (GRUB_LINUX_CL_OFFSET);
-
+
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
+
grub_linux_real_addr = (char *) GRUB_LINUX_OLD_REAL_MODE_ADDR;
}
-
+
/* If SETUP_SECTS is not set, set it to the default (4). */
if (! setup_sects)
setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS;
-
+
real_size = setup_sects << GRUB_DISK_SECTOR_BITS;
prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE;
-
+
grub_linux_tmp_addr = (char *) GRUB_LINUX_BZIMAGE_ADDR + prot_size;
if (! grub_linux_is_bzimage
(grub_size_t) grub_linux_real_addr);
goto fail;
}
-
+
if (grub_linux_real_addr + GRUB_LINUX_SETUP_MOVE_SIZE
> (char *) UINT_TO_PTR (grub_mmap_get_lower ()))
{
else if (grub_memcmp (argv[i], "mem=", 4) == 0)
{
char *val = argv[i] + 4;
-
+
linux_mem_size = grub_strtoul (val, &val, 0);
-
+
if (grub_errno)
{
grub_errno = GRUB_ERR_NONE;
else
{
int shift = 0;
-
+
switch (grub_tolower (val[0]))
{
case 'g':
dest = grub_stpcpy (grub_linux_tmp_addr + GRUB_LINUX_CL_OFFSET,
"BOOT_IMAGE=");
dest = grub_stpcpy (dest, argv[0]);
-
+
/* Copy kernel parameters. */
for (i = 1;
i < argc
len = prot_size;
if (grub_file_read (file, (char *) GRUB_LINUX_BZIMAGE_ADDR, len) != len)
grub_error (GRUB_ERR_FILE_READ_ERROR, "Couldn't read file");
-
+
if (grub_errno == GRUB_ERR_NONE)
{
grub_linux_prot_size = prot_size;
}
fail:
-
+
if (file)
grub_file_close (file);
grub_error (GRUB_ERR_BAD_ARGUMENT, "No module specified");
goto fail;
}
-
+
if (!loaded)
{
grub_error (GRUB_ERR_BAD_ARGUMENT, "You need to load the kernel first.");
lh->ramdisk_image = addr;
lh->ramdisk_size = size;
-
+
fail:
if (file)
grub_file_close (file);
if ((paddr < grub_os_area_addr)
|| (paddr + phdr->p_memsz > grub_os_area_addr + grub_os_area_size))
- return grub_error(GRUB_ERR_OUT_OF_RANGE,"Address 0x%x is out of range",
+ return grub_error(GRUB_ERR_OUT_OF_RANGE,"Address 0x%x is out of range",
paddr);
return GRUB_ERR_NONE;
grub_mb2_arch_unload (struct multiboot_tag_header *tags)
{
struct multiboot_tag_header *tag;
-
+
/* Free all module memory in the tag list. */
for_each_tag (tag, tags)
{
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
else
{
- tmp = grub_malloc (grub_strlen (modevar)
+ tmp = grub_malloc (grub_strlen (modevar)
+ sizeof (DEFAULT_VIDEO_MODE) + 1);
if (! tmp)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate temporary storag");
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, video_hook);
y > 0 ? y : 0,
x < 0 ? -x : 0,
y < 0 ? -y : 0,
- min (grub_xnu_bitmap->mode_info.width,
- mode_info.width),
- min (grub_xnu_bitmap->mode_info.height,
+ min (grub_xnu_bitmap->mode_info.width,
+ mode_info.width),
+ min (grub_xnu_bitmap->mode_info.height,
mode_info.height));
if (err)
{
params->lfb_line_len = mode_info.pitch;
params->lfb_base = PTR_TO_UINT32 (render_target->data);
- params->lfb_mode = grub_xnu_bitmap
- ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
+ params->lfb_mode = grub_xnu_bitmap
+ ? GRUB_XNU_VIDEO_SPLASH : GRUB_XNU_VIDEO_TEXT_IN_VIDEO;
return GRUB_ERR_NONE;
}
{GRUB_EFI_ACPI_TABLE_GUID, "ACPI"},
};
-/* The following function is used to be able to debug xnu loader
+/* The following function is used to be able to debug xnu loader
with grub-emu. */
#ifdef GRUB_UTIL
-static grub_err_t
+static grub_err_t
grub_xnu_launch (void)
{
grub_printf ("Fake launch %x:%p:%p", grub_xnu_entry_point, grub_xnu_arg1,
while (*str)
{
unsigned long digit;
-
+
digit = grub_tolower (*str) - '0';
if (digit > 9)
break;
while (*str)
{
unsigned long digit;
-
+
digit = grub_tolower (*str) - '0';
if (digit > 9)
break;
if (! grub_cpu_is_cpuid_supported ())
return sane_value;
-
+
#ifdef APPLE_CC
asm volatile ("movl $0, %%eax\n"
#ifdef __x86_64__
"pop %%rbx\n"
#else
"pop %%ebx\n"
-#endif
- : "=a" (max_cpuid),
+#endif
+ : "=a" (max_cpuid),
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
-
+
/* Only Intel for now is done. */
if (grub_memcmp (manufacturer + 1, "ineIntel", 12) != 0)
return sane_value;
-
+
#else
asm volatile ("movl $0, %%eax\n"
"cpuid"
- : "=a" (max_cpuid), "=b" (manufacturer[0]),
+ : "=a" (max_cpuid), "=b" (manufacturer[0]),
"=d" (manufacturer[1]), "=c" (manufacturer[2]));
/* Only Intel for now is done. */
"push %%rbx\n"
#else
"push %%ebx\n"
-#endif
+#endif
"cpuid\n"
#ifdef __x86_64__
"pop %%rbx\n"
"pop %%ebx\n"
#endif
: "=c" (capabilities):
- : "%rax", "%rdx");
+ : "%rax", "%rdx");
#else
asm volatile ("movl $1, %%eax\n"
"cpuid"
:
: "%ecx", "%eax");
- return grub_divmod64 (2000 * tsc_ticks_per_ms,
+ return grub_divmod64 (2000 * tsc_ticks_per_ms,
((msrlow >> 7) & 0x3e) + ((msrlow >> 14) & 1), 0);
}
curval = grub_xnu_create_value (&(efikey->first_child), "firmware-vendor");
if (! curval)
return grub_errno;
- curval->datasize =
+ curval->datasize =
2 * (utf16_strlen (SYSTEM_TABLE_PTR (firmware_vendor)) + 1);
curval->data = grub_malloc (curval->datasize);
if (! curval->data)
grub_memcpy (curval->data, "EFI64", curval->datasize);
/* The key "platform". */
- platformkey = grub_xnu_create_key (&(efikey->first_child),
+ platformkey = grub_xnu_create_key (&(efikey->first_child),
"platform");
if (! platformkey)
return grub_errno;
/* First see if user supplies the value. */
char *fsbvar = grub_env_get ("fsb");
if (! fsbvar)
- *((grub_uint64_t *) curval->data) = 0;
+ *((grub_uint64_t *) curval->data) = 0;
else
*((grub_uint64_t *) curval->data) = readfrequency (fsbvar);
/* Try autodetect. */
if (! *((grub_uint64_t *) curval->data))
- *((grub_uint64_t *) curval->data) = guessfsb ();
- grub_dprintf ("xnu", "fsb autodetected as %llu\n",
+ *((grub_uint64_t *) curval->data) = guessfsb ();
+ grub_dprintf ("xnu", "fsb autodetected as %llu\n",
(unsigned long long) *((grub_uint64_t *) curval->data));
- cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
+ cfgtablekey = grub_xnu_create_key (&(efikey->first_child),
"configuration-table");
if (!cfgtablekey)
return grub_errno;
/* Retrieve current key. */
#ifdef GRUB_MACHINE_EFI
{
- ptr = (void *)
+ ptr = (void *)
grub_efi_system_table->configuration_table[i].vendor_table;
guid = grub_efi_system_table->configuration_table[i].vendor_guid;
}
-#else
+#else
if (SIZEOF_OF_UINTN == 4)
{
ptr = UINT_TO_PTR (((grub_efiemu_configuration_table32_t *)
ptr = UINT_TO_PTR (((grub_efiemu_configuration_table64_t *)
SYSTEM_TABLE_PTR (configuration_table))[i]
.vendor_table);
- guid =
+ guid =
((grub_efiemu_configuration_table64_t *)
SYSTEM_TABLE_PTR (configuration_table))[i].vendor_guid;
}
curval->datasize = sizeof (guid);
curval->data = grub_malloc (curval->datasize);
if (! curval->data)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't create device tree");
grub_memcpy (curval->data, &guid, curval->datasize);
curval->datasize = SIZEOF_OF_UINTN;
curval->data = grub_malloc (curval->datasize);
if (! curval->data)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't create device tree");
if (SIZEOF_OF_UINTN == 4)
*((grub_uint32_t *)curval->data) = PTR_TO_UINT32 (ptr);
curval->datasize = grub_strlen (table_aliases[j].name) + 1;
curval->data = grub_malloc (curval->datasize);
if (!curval->data)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't create device tree");
grub_memcpy (curval->data, table_aliases[j].name, curval->datasize);
}
}
-
+
/* Create and fill "runtime-services" key. */
- runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
+ runtimesrvkey = grub_xnu_create_key (&(efikey->first_child),
"runtime-services");
if (! runtimesrvkey)
return grub_errno;
curval->datasize = SIZEOF_OF_UINTN;
curval->data = grub_malloc (curval->datasize);
if (! curval->data)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't create device tree");
if (SIZEOF_OF_UINTN == 4)
- *((grub_uint32_t *) curval->data)
+ *((grub_uint32_t *) curval->data)
= PTR_TO_UINT32 (SYSTEM_TABLE_PTR (runtime_services));
else
- *((grub_uint64_t *) curval->data)
+ *((grub_uint64_t *) curval->data)
= PTR_TO_UINT64 (SYSTEM_TABLE_PTR (runtime_services));
-
+
return GRUB_ERR_NONE;
}
/* Boot xnu. */
-grub_err_t
+grub_err_t
grub_xnu_boot (void)
{
struct grub_xnu_boot_params *bootparams_relloc;
&map_key, &descriptor_size,
&descriptor_version) <= 0)
return grub_errno;
- mmap_relloc_off = (grub_uint8_t *) memory_map
+ mmap_relloc_off = (grub_uint8_t *) memory_map
- (grub_uint8_t *) grub_xnu_heap_start;
- firstruntimeaddr = (grub_uint64_t) (-1);
+ firstruntimeaddr = (grub_uint64_t) (-1);
lastruntimeaddr = 0;
for (i = 0; (unsigned) i < memory_map_size / descriptor_size; i++)
{
- grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
+ grub_efi_memory_descriptor_t *curdesc = (grub_efi_memory_descriptor_t *)
((char *) memory_map + descriptor_size * i);
- /* Some EFI implementations set physical_start to 0 which
+ /* Some EFI implementations set physical_start to 0 which
causes XNU crash. */
curdesc->virtual_start = curdesc->physical_start;
bootparams_relloc = grub_xnu_heap_malloc (sizeof (*bootparams_relloc));
if (! bootparams_relloc)
return grub_errno;
- bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc
+ bootparams_relloc_off = (grub_uint8_t *) bootparams_relloc
- (grub_uint8_t *) grub_xnu_heap_start;
err = grub_xnu_writetree_toheap (&devtree, &devtreelen);
if (err)
bootparams_relloc = (struct grub_xnu_boot_params *)
(bootparams_relloc_off + (grub_uint8_t *) grub_xnu_heap_start);
- grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline,
+ grub_memcpy (bootparams_relloc->cmdline, grub_xnu_cmdline,
sizeof (bootparams_relloc->cmdline));
- bootparams_relloc->devtree = ((char *) devtree - grub_xnu_heap_start)
+ bootparams_relloc->devtree = ((char *) devtree - grub_xnu_heap_start)
+ grub_xnu_heap_will_be_at;
bootparams_relloc->devtreelen = devtreelen;
bootparams_relloc->heap_size = grub_xnu_heap_size;
bootparams_relloc->efi_mmap = grub_xnu_heap_will_be_at + mmap_relloc_off;
- bootparams_relloc->efi_mmap_size = memory_map_size;
- bootparams_relloc->efi_mem_desc_size = descriptor_size;
- bootparams_relloc->efi_mem_desc_version = descriptor_version;
+ bootparams_relloc->efi_mmap_size = memory_map_size;
+ bootparams_relloc->efi_mem_desc_size = descriptor_size;
+ bootparams_relloc->efi_mem_desc_version = descriptor_version;
- bootparams_relloc->efi_runtime_first_page = firstruntimeaddr
+ bootparams_relloc->efi_runtime_first_page = firstruntimeaddr
/ GRUB_XNU_PAGESIZE;
- bootparams_relloc->efi_runtime_npages
- = ((lastruntimeaddr + GRUB_XNU_PAGESIZE - 1) / GRUB_XNU_PAGESIZE)
+ bootparams_relloc->efi_runtime_npages
+ = ((lastruntimeaddr + GRUB_XNU_PAGESIZE - 1) / GRUB_XNU_PAGESIZE)
- (firstruntimeaddr / GRUB_XNU_PAGESIZE);
bootparams_relloc->efi_uintnbits = SIZEOF_OF_UINTN * 8;
- bootparams_relloc->efi_system_table
+ bootparams_relloc->efi_system_table
= PTR_TO_UINT32 (grub_autoefi_system_table);
- bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
+ bootparams_relloc->verminor = GRUB_XNU_BOOTARGS_VERMINOR;
bootparams_relloc->vermajor = GRUB_XNU_BOOTARGS_VERMAJOR;
/* Parameters for asm helper. */
- grub_xnu_stack = bootparams_relloc->heap_start
+ grub_xnu_stack = bootparams_relloc->heap_start
+ bootparams_relloc->heap_size + GRUB_XNU_PAGESIZE;
grub_xnu_arg1 = bootparams_relloc_off + grub_xnu_heap_will_be_at;
#ifndef GRUB_UTIL
- grub_xnu_launch = (void (*) (void))
+ grub_xnu_launch = (void (*) (void))
(grub_xnu_heap_start + grub_xnu_heap_size);
#endif
grub_dprintf ("xnu", "eip=%x\n", grub_xnu_entry_point);
grub_dprintf ("xnu", "launch=%p\n", grub_xnu_launch);
const char *debug = grub_env_get ("debug");
-
+
if (debug && (grub_strword (debug, "all") || grub_strword (debug, "xnu")))
{
grub_printf ("Press any key to launch xnu\n");
grub_getkey ();
}
-
+
/* Set video. */
err = grub_xnu_set_video (bootparams_relloc);
if (err != GRUB_ERR_NONE)
bootparams_relloc->lfb_base = 0;
}
- grub_memcpy (grub_xnu_heap_start + grub_xnu_heap_size,
- grub_xnu_launcher_start,
+ grub_memcpy (grub_xnu_heap_start + grub_xnu_heap_size,
+ grub_xnu_launcher_start,
grub_xnu_launcher_end - grub_xnu_launcher_start);
*/
#include <grub/symbol.h>
-
+
.p2align 4 /* force 16-byte alignment */
VARIABLE(grub_xnu_launcher_start)
-base:
+base:
cli
-
+
#ifndef __x86_64__
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_xnu_heap_will_be_at)
.long 0
mov %eax, %edi
-
+
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_xnu_heap_start)
.long 0
mov %eax, %esi
-
+
/* mov imm32, %ecx */
.byte 0xb9
VARIABLE(grub_xnu_heap_size)
mov %eax, %esi
add $(cont0-base), %eax
jmp *%eax
-cont0:
+cont0:
#else
xorq %rax, %rax
-
+
/* mov imm32, %eax */
.byte 0xb8
VARIABLE(grub_xnu_heap_will_be_at)
.long 0
mov %rax, %rdi
-
+
/* mov imm32, %rax */
.byte 0x48
.byte 0xb8
.long 0
.long 0
mov %rax, %rsi
-
+
/* mov imm32, %rcx */
.byte 0x48
.byte 0xb9
#endif
jmp *%rax
-cont0:
+cont0:
#ifdef APPLE_CC
lea (cont1 - base) (%esi, 1), %eax
mov %eax, (jump_vector - base) (%esi, 1)
lea (gdt - base) (%esi, 1), %eax
mov %eax, (gdt_addr - base) (%esi, 1)
-
+
/* Switch to compatibility mode. */
lgdt (gdtdesc - base) (%esi, 1)
-
+
/* Update %cs. Thanks to David Miller for pointing this mistake out. */
ljmp *(jump_vector - base) (%esi,1)
#else
lea (gdt - base) (%rsi, 1), %rax
mov %rax, (gdt_addr - base) (%rsi, 1)
-
+
/* Switch to compatibility mode. */
lgdt (gdtdesc - base) (%rsi, 1)
-
+
/* Update %cs. Thanks to David Miller for pointing this mistake out. */
ljmp *(jump_vector - base) (%rsi, 1)
#endif
-
+
cont1:
.code32
/* Update other registers. */
mov $0x18, %eax
- mov %eax, %ds
+ mov %eax, %ds
mov %eax, %es
mov %eax, %fs
mov %eax, %gs
mov %eax, %cr4
jmp cont2
-cont2:
+cont2:
#endif
.code32
-
+
/* Registers on XNU boot: eip, esp and eax. */
/* mov imm32, %ecx */
.byte 0xb9
#ifdef __x86_64__
/* GDT. Copied from loader/i386/linux.c. */
.p2align 4
-gdt:
+gdt:
/* NULL. */
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
+
/* Reserved. */
.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-
+
/* Code segment. */
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9A, 0xCF, 0x00
-
+
/* Data segment. */
.byte 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x92, 0xCF, 0x00
-gdtdesc:
+gdtdesc:
.word 31
-gdt_addr:
+gdt_addr:
/* Filled by the code. */
.quad 0
-
+
.p2align 4
jump_vector:
/* Jump location. Is filled by the code */
.long 0
- .long 0x10
+ .long 0x10
#endif
VARIABLE(grub_xnu_launcher_end)
/* Read header and check magic*/
if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1
- || grub_file_read (macho->file, (char *) &head, sizeof (head))
+ || grub_file_read (macho->file, (char *) &head, sizeof (head))
!= sizeof(head))
{
- grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
+ grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
macho->offset32 = -1;
return;
}
if (head.magic != GRUB_MACHO_MAGIC32)
{
- grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header.");
+ grub_error (GRUB_ERR_BAD_OS, "Invalid Mach-O 32-bit header.");
macho->offset32 = -1;
return;
}
grub_error (GRUB_ERR_OUT_OF_MEMORY, "not enough memory to read commands");
return;
}
- if (grub_file_read (macho->file, (char *) macho->cmds32,
- (grub_size_t) macho->cmdsize32)
+ if (grub_file_read (macho->file, (char *) macho->cmds32,
+ (grub_size_t) macho->cmdsize32)
!= (grub_ssize_t) macho->cmdsize32)
{
- grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
+ grub_error (GRUB_ERR_READ_ERROR, "Cannot read Mach-O header.");
macho->offset32 = -1;
}
}
typedef int NESTED_FUNC_ATTR (*grub_macho_iter_hook_t)
-(grub_macho_t , struct grub_macho_cmd *,
+(grub_macho_t , struct grub_macho_cmd *,
void *);
static grub_err_t
{
grub_ssize_t read;
if (! grub_macho_contains_macho32 (macho))
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"Couldn't read architecture-specific part");
if (grub_file_seek (macho->file, macho->offset32) == (grub_off_t) -1)
"Invalid offset in program header.");
}
- read = grub_file_read (macho->file, dest,
+ read = grub_file_read (macho->file, dest,
macho->end32 - macho->offset32);
if (read != (grub_ssize_t) (macho->end32 - macho->offset32))
{
grub_error_push ();
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"Couldn't read architecture-specific part");
}
return GRUB_ERR_NONE;
/* Run through the program headers to calculate the total memory size we
should claim. */
- auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho,
+ auto int NESTED_FUNC_ATTR calcsize (grub_macho_t _macho,
struct grub_macho_cmd *phdr, void *_arg);
- int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho,
+ int NESTED_FUNC_ATTR calcsize (grub_macho_t UNUSED _macho,
struct grub_macho_cmd *hdr0, void UNUSED *_arg)
{
struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0;
grub_macho32_load (grub_macho_t macho, char *offset, int flags)
{
grub_err_t err = 0;
- auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
- struct grub_macho_cmd *hdr0,
+ auto int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
+ struct grub_macho_cmd *hdr0,
void UNUSED *_arg);
- int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
- struct grub_macho_cmd *hdr0,
+ int NESTED_FUNC_ATTR do_load(grub_macho_t _macho,
+ struct grub_macho_cmd *hdr0,
void UNUSED *_arg)
{
struct grub_macho_segment32 *hdr = (struct grub_macho_segment32 *) hdr0;
if (hdr->cmd != GRUB_MACHO_CMD_SEGMENT32)
return 0;
-
+
if (! hdr->filesize && (flags & GRUB_MACHO_NOBSS))
return 0;
if (! hdr->vmsize)
return 0;
-
- if (grub_file_seek (_macho->file, hdr->fileoff
+
+ if (grub_file_seek (_macho->file, hdr->fileoff
+ _macho->offset32) == (grub_off_t) -1)
{
grub_error_push ();
"Invalid offset in program header.");
return 1;
}
-
+
if (hdr->filesize)
{
grub_ssize_t read;
- read = grub_file_read (_macho->file, offset + hdr->vmaddr,
+ read = grub_file_read (_macho->file, offset + hdr->vmaddr,
min (hdr->filesize, hdr->vmsize));
if (read != (grub_ssize_t) min (hdr->filesize, hdr->vmsize))
{
return 1;
}
}
-
+
if (hdr->filesize < hdr->vmsize)
grub_memset (offset + hdr->vmaddr + hdr->filesize,
0, hdr->vmsize - hdr->filesize);
grub_macho32_get_entry_point (grub_macho_t macho)
{
grub_uint32_t entry_point = 0;
- auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho,
- struct grub_macho_cmd *hdr,
+ auto int NESTED_FUNC_ATTR hook(grub_macho_t _macho,
+ struct grub_macho_cmd *hdr,
void UNUSED *_arg);
- int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho,
- struct grub_macho_cmd *hdr,
+ int NESTED_FUNC_ATTR hook(grub_macho_t UNUSED _macho,
+ struct grub_macho_cmd *hdr,
void UNUSED *_arg)
{
if (hdr->cmd == GRUB_MACHO_CMD_THREAD)
/* Load architecture description. */
narchs = grub_be_to_cpu32 (filestart.fat.nfat_arch);
- if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header))
+ if (grub_file_seek (macho->file, sizeof (struct grub_macho_fat_header))
== (grub_off_t) -1)
goto fail;
archs = grub_malloc (sizeof (struct grub_macho_fat_arch) * narchs);
if (!archs)
goto fail;
- if (grub_file_read (macho->file, (char *) archs,
+ if (grub_file_read (macho->file, (char *) archs,
sizeof (struct grub_macho_fat_arch) * narchs)
!= (grub_ssize_t)sizeof(struct grub_macho_fat_arch) * narchs)
{
for (i = 0; i < narchs; i++)
{
- if (GRUB_MACHO_CPUTYPE_IS_HOST32
+ if (GRUB_MACHO_CPUTYPE_IS_HOST32
(grub_be_to_cpu32 (archs[i].cputype)))
{
macho->offset32 = grub_be_to_cpu32 (archs[i].offset);
- macho->end32 = grub_be_to_cpu32 (archs[i].offset)
+ macho->end32 = grub_be_to_cpu32 (archs[i].offset)
+ grub_be_to_cpu32 (archs[i].size);
}
if (GRUB_MACHO_CPUTYPE_IS_HOST64
(grub_be_to_cpu32 (archs[i].cputype)))
{
macho->offset64 = grub_be_to_cpu32 (archs[i].offset);
- macho->end64 = grub_be_to_cpu32 (archs[i].offset)
+ macho->end64 = grub_be_to_cpu32 (archs[i].offset)
+ grub_be_to_cpu32 (archs[i].size);
}
}
grub_macho_parse32 (macho);
/* FIXME: implement 64-bit.*/
/* grub_macho_parse64 (macho); */
-
+
return macho;
fail:
/* This tracks which version of multiboot to use when using
* the module command. By default use multiboot version 1.
* values:
- * 1 - Multiboot version 1
+ * 1 - Multiboot version 1
* 2 - Multiboot version 2
*/
-static unsigned int module_version_status = 1;
+static unsigned int module_version_status = 1;
static int
find_multi_boot1_header (grub_file_t file)
char buffer[MULTIBOOT_SEARCH];
int found_status = 0;
grub_ssize_t len;
-
+
len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
if (len < 32)
return found_status;
char buffer[MULTIBOOT_SEARCH];
int found_status = 0;
grub_ssize_t len;
-
+
len = grub_file_read (file, buffer, MULTIBOOT_SEARCH);
if (len < 32)
return found_status;
/* Launch multi boot with header */
- /* XXX Find a better way to identify this.
+ /* XXX Find a better way to identify this.
This is for i386-pc */
#if defined(GRUB_MACHINE_PCBIOS) || defined(GRUB_MACHINE_LINUXBIOS)
if (header_multi_ver_found == 1)
/* Specify the boot file. */
dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
dest = grub_stpcpy (dest, argv[0]);
-
+
for (i = 1; i < argc; i++)
{
*dest++ = ' ';
/* Attempt to claim at a series of addresses until successful in
the same way that grub_rescue_cmd_linux does. */
- for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000)
+ for (addr = first_addr; addr < first_addr + 200 * 0x100000; addr += 0x100000)
{
- grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
+ grub_dprintf ("loader", "Attempting to claim at 0x%x, size 0x%x.\n",
addr, size);
found_addr = grub_claimmap (addr, size);
if (found_addr != -1)
-/* xnu.c - load xnu kernel. Thanks to Florian Idelberger for all the
+/* xnu.c - load xnu kernel. Thanks to Florian Idelberger for all the
time he spent testing this
*/
/*
#define GRUB_XNU_HEAP_ALLOC_BLOCK 0x2000000
static grub_err_t
-grub_xnu_register_memory (char *prefix, int *suffix,
+grub_xnu_register_memory (char *prefix, int *suffix,
void *addr, grub_size_t size);
void *
grub_xnu_heap_malloc (int size)
void *val;
#if 0
- /* This way booting is faster but less reliable.
+ /* This way booting is faster but less reliable.
Once we have advanced mm second way will be as fast as this one. */
val = grub_xnu_heap_start = (char *) 0x100000;
#else
/* The page after the heap is used for stack. Ensure it's usable. */
if (grub_xnu_heap_size)
- oldblknum = (grub_xnu_heap_size + GRUB_XNU_PAGESIZE
+ oldblknum = (grub_xnu_heap_size + GRUB_XNU_PAGESIZE
+ GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
else
oldblknum = 0;
- newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE
+ newblknum = (grub_xnu_heap_size + size + GRUB_XNU_PAGESIZE
+ GRUB_XNU_HEAP_ALLOC_BLOCK - 1) / GRUB_XNU_HEAP_ALLOC_BLOCK;
if (oldblknum != newblknum)
- /* FIXME: instruct realloc to allocate at 1MB if possible once
+ /* FIXME: instruct realloc to allocate at 1MB if possible once
advanced mm is ready. */
- val = grub_realloc (grub_xnu_heap_start,
+ val = grub_realloc (grub_xnu_heap_start,
newblknum * GRUB_XNU_HEAP_ALLOC_BLOCK);
else
val = grub_xnu_heap_start;
if (! val)
{
- grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
"not enough space on xnu memory heap");
return 0;
}
return (char *) val;
}
-/* Make sure next block of the heap will be aligned.
- Please notice: aligned are pointers AFTER relocation
+/* Make sure next block of the heap will be aligned.
+ Please notice: aligned are pointers AFTER relocation
and not the current ones. */
grub_err_t
grub_xnu_align_heap (int align)
else if (cur->data)
grub_free (cur->data);
d = cur->next;
- grub_free (cur);
+ grub_free (cur);
cur = d;
- }
+ }
}
/* Compute the size of device tree in xnu format. */
{
grub_size_t ret;
struct grub_xnu_devtree_key *cur;
-
+
/* Key header. */
ret = 2 * sizeof (grub_uint32_t);
/* "name" value. */
ret += 32 + sizeof (grub_uint32_t)
- + grub_strlen (name) + 4
+ + grub_strlen (name) + 4
- (grub_strlen (name) % 4);
for (cur = start; cur; cur = cur->next)
if (cur->datasize != -1)
{
int align_overhead;
-
+
align_overhead = 4 - (cur->datasize % 4);
if (align_overhead == 4)
align_overhead = 0;
/* Write devtree in XNU format at curptr assuming the head is named NAME.*/
static void *
-grub_xnu_writetree_toheap_real (void *curptr,
+grub_xnu_writetree_toheap_real (void *curptr,
struct grub_xnu_devtree_key *start, char *name)
{
struct grub_xnu_devtree_key *cur;
nvals++;
}
/* For the name. */
- nvals++;
-
+ nvals++;
+
*((grub_uint32_t *) curptr) = nvals;
curptr = ((grub_uint32_t *) curptr) + 1;
*((grub_uint32_t *) curptr) = nkeys;
if (cur->datasize != -1)
{
int align_overhead;
-
+
align_overhead = 4 - (cur->datasize % 4);
if (align_overhead == 4)
align_overhead = 0;
grub_memset (curptr, 0, align_overhead);
curptr = ((grub_uint8_t *) curptr) + align_overhead;
}
-
+
/* And then the keys. Recursively use this function. */
for (cur = start; cur; cur = cur->next)
if (cur->datasize == -1)
if (!(curptr = grub_xnu_writetree_toheap_real (curptr,
- cur->first_child,
+ cur->first_child,
cur->name)))
return 0;
return curptr;
struct grub_xnu_devtree_key *driverkey;
struct grub_xnu_extdesc *extdesc;
grub_err_t err;
-
+
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
if (err)
return err;
-
+
/* Device tree itself is in the memory map of device tree. */
/* Create a dummy value in memory-map. */
chosen = grub_xnu_create_key (&grub_xnu_devtree_root, "chosen");
driverkey->datasize = sizeof (*extdesc);
driverkey->next = memorymap->first_child;
memorymap->first_child = driverkey;
- driverkey->data = extdesc
+ driverkey->data = extdesc
= (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
if (! driverkey->data)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't write device tree");
/* Allocate the space based on the size with dummy value. */
*size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
- *start = grub_xnu_heap_malloc (*size + GRUB_XNU_PAGESIZE
+ *start = grub_xnu_heap_malloc (*size + GRUB_XNU_PAGESIZE
- *size % GRUB_XNU_PAGESIZE);
/* Put real data in the dummy. */
- extdesc->addr = (char *) *start - grub_xnu_heap_start
+ extdesc->addr = (char *) *start - grub_xnu_heap_start
+ grub_xnu_heap_will_be_at;
extdesc->size = (grub_uint32_t) *size;
if (! grub_macho_contains_macho32 (macho))
{
grub_macho_close (macho);
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"Kernel doesn't contain suitable architecture");
}
return err;
}
- grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
+ grub_dprintf ("xnu", "endcode = %lx, startcode = %lx\n",
(unsigned long) endcode, (unsigned long) startcode);
loadaddr = grub_xnu_heap_malloc (endcode - startcode);
{
grub_macho_close (macho);
grub_xnu_unload ();
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"not enough memory to load kernel");
}
ptr = grub_xnu_cmdline;
for (i = 1; i < argc; i++)
{
- if (ptr + grub_strlen (args[i]) + 1
+ if (ptr + grub_strlen (args[i]) + 1
>= grub_xnu_cmdline + sizeof (grub_xnu_cmdline))
break;
grub_memcpy (ptr, args[i], grub_strlen (args[i]));
/* Replace last space by '\0'. */
if (ptr != grub_xnu_cmdline)
- *(ptr - 1) = 0;
+ *(ptr - 1) = 0;
err = grub_cpu_xnu_fill_devicetree ();
if (err)
return err;
- grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
+ grub_loader_set (grub_xnu_boot, grub_xnu_unload, 0);
grub_xnu_lock ();
return 0;
}
-/* Register a memory in a memory map under name PREFIXSUFFIX
+/* Register a memory in a memory map under name PREFIXSUFFIX
and increment SUFFIX. */
static grub_err_t
-grub_xnu_register_memory (char *prefix, int *suffix,
+grub_xnu_register_memory (char *prefix, int *suffix,
void *addr, grub_size_t size)
{
struct grub_xnu_devtree_key *chosen;
driverkey->datasize = sizeof (*extdesc);
driverkey->next = memorymap->first_child;
memorymap->first_child = driverkey;
- driverkey->data = extdesc
+ driverkey->data = extdesc
= (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
if (! driverkey->data)
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "can't register extension");
- extdesc->addr = grub_xnu_heap_will_be_at +
+ extdesc->addr = grub_xnu_heap_will_be_at +
((grub_uint8_t *) addr - (grub_uint8_t *) grub_xnu_heap_start);
extdesc->size = (grub_uint32_t) size;
return GRUB_ERR_NONE;
if (! grub_xnu_heap_size)
return grub_error (GRUB_ERR_BAD_OS, "no xnu kernel loaded");
-
+
/* Compute the needed space. */
if (binaryfile)
{
{
if (macho)
grub_macho_close (macho);
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"Extension doesn't contain suitable architecture");
}
machosize = grub_macho32_filesize (macho);
/* Load the plist. */
if (infoplist)
{
- exthead->infoplistaddr = (buf - grub_xnu_heap_start)
+ exthead->infoplistaddr = (buf - grub_xnu_heap_start)
+ grub_xnu_heap_will_be_at;
exthead->infoplistsize = infoplistsize + 1;
if (grub_file_read (infoplist, buf, infoplistsize)
/* Announce to kernel */
return grub_xnu_register_memory ("Driver-", &driversnum, exthead,
- neededspace);
+ neededspace);
}
/* Load mkext. */
file = grub_gzfile_open (args[0], 1);
if (! file)
- return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"Couldn't load driver package");
/* Sometimes caches are fat binary. Errgh. */
if (grub_file_read (file, (char *) &head, sizeof (head))
!= (grub_ssize_t) (sizeof (head)))
{
- /* I don't know the internal structure of package but
+ /* I don't know the internal structure of package but
can hardly imagine a valid package shorter than 20 bytes. */
grub_file_close (file);
grub_error_push ();
{
grub_file_close (file);
grub_error_push ();
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Couldn't read file %s", args[0]);
-
+
}
- if (grub_file_read (file, (char *) archs,
+ if (grub_file_read (file, (char *) archs,
sizeof (struct grub_macho_fat_arch) * narchs)
!= (grub_ssize_t) sizeof(struct grub_macho_fat_arch) * narchs)
{
}
for (i = 0; i < narchs; i++)
{
- if (GRUB_MACHO_CPUTYPE_IS_HOST32
+ if (GRUB_MACHO_CPUTYPE_IS_HOST32
(grub_be_to_cpu32 (archs[i].cputype)))
{
readoff = grub_be_to_cpu32 (archs[i].offset);
/* Pass it to kernel. */
return grub_xnu_register_memory ("DriversPackage-", &driverspackagenum,
- loadto, readlen);
+ loadto, readlen);
}
static grub_err_t
file = grub_gzfile_open (args[0], 1);
if (! file)
- return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND,
"Couldn't load ramdisk");
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
return err;
size = grub_file_size (file);
-
+
loadto = grub_xnu_heap_malloc (size);
if (! loadto)
return grub_errno;
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]);
}
- return grub_xnu_register_memory ("RAMDisk", 0, loadto, size);
+ return grub_xnu_register_memory ("RAMDisk", 0, loadto, size);
}
-/* Parse a devtree file. It uses the following format:
+/* Parse a devtree file. It uses the following format:
valuename:valuedata;
keyname{
contents
if (*ptr == '}')
return ptr + 1;
namelen = 0;
-
+
/* Parse the name. */
- for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2)
+ for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2)
|| (*ptr2 >= '0' && *ptr2 <= '9')
|| (*ptr2 >= 'a' && *ptr2 <= 'f')
- || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+ || (*ptr2 >= 'A' && *ptr2 <= 'F'));
ptr2++)
if (! grub_isspace (*ptr2))
namelen++;
hex = *ptr - 'a' + 10;
if (*ptr >= 'A' && *ptr <= 'F')
hex = *ptr - 'A' + 10;
-
+
if (i % 2 == 0)
name[i / 2] = hex << 4;
else
/* If it describes a key recursively invoke the function. */
if (*ptr == '{')
{
- struct grub_xnu_devtree_key *newkey
+ struct grub_xnu_devtree_key *newkey
= grub_xnu_create_key (parent, name);
grub_free (name);
if (! newkey)
return 0;
ptr++;
datalen = 0;
- for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2)
+ for (ptr2 = ptr; ptr2 < end && (grub_isspace (*ptr2)
|| (*ptr2 >= '0' && *ptr2 <= '9')
|| (*ptr2 >= 'a' && *ptr2 <= 'f')
- || (*ptr2 >= 'A' && *ptr2 <= 'F'));
+ || (*ptr2 >= 'A' && *ptr2 <= 'F'));
ptr2++)
if (! grub_isspace (*ptr2))
datalen++;
hex = *ptr - 'a' + 10;
if (*ptr >= 'A' && *ptr <= 'F')
hex = *ptr - 'A' + 10;
-
+
if (i % 2 == 0)
data[i / 2] = hex << 4;
else
while (ptr < end && grub_isspace (*ptr))
ptr++;
{
- struct grub_xnu_devtree_key *newkey
+ struct grub_xnu_devtree_key *newkey
= grub_xnu_create_value (parent, name);
grub_free (name);
if (! newkey)
return ptr;
}
-/* Returns true if the kext should be loaded according to plist
+/* Returns true if the kext should be loaded according to plist
and osbundlereq. Also fill BINNAME. */
static int
grub_xnu_check_os_bundle_required (char *plistname, char *osbundlereq,
file = grub_gzfile_open (plistname, 1);
if (! file)
{
- grub_file_close (file);
+ grub_file_close (file);
grub_error_push ();
grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", plistname);
return 0;
buf = grub_malloc (size);
if (! buf)
{
- grub_file_close (file);
+ grub_file_close (file);
grub_error_push ();
grub_error (GRUB_ERR_OUT_OF_MEMORY, "Couldn't read file %s", plistname);
return 0;
}
if (grub_file_read (file, buf, size) != (grub_ssize_t) (size))
{
- grub_file_close (file);
+ grub_file_close (file);
grub_error_push ();
grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", plistname);
return 0;
}
- grub_file_close (file);
+ grub_file_close (file);
/* Set the return value for the case when no OSBundleRequired tag is found. */
if (osbundlereq)
ret = grub_strword (osbundlereq, "all") || grub_strword (osbundlereq, "-");
else
ret = 1;
-
+
/* Parse plist. It's quite dirty and inextensible but does its job. */
for (ptr1 = buf; ptr1 < buf + size; ptr1++)
switch (*ptr1)
case '<':
tagstart = ptr1;
*ptr1 = 0;
- if (keyptr && depth == 4
+ if (keyptr && depth == 4
&& grub_strcmp (keyptr, "OSBundleRequired") == 0)
osbundlekeyfound = 1;
- if (keyptr && depth == 4 &&
+ if (keyptr && depth == 4 &&
grub_strcmp (keyptr, "CFBundleExecutable") == 0)
binnamekeyfound = 1;
if (stringptr && osbundlekeyfound && osbundlereq && depth == 4)
{
for (ptr2 = stringptr; *ptr2; ptr2++)
*ptr2 = grub_tolower (*ptr2);
- ret = grub_strword (osbundlereq, stringptr)
+ ret = grub_strword (osbundlereq, stringptr)
|| grub_strword (osbundlereq, "all");
}
if (stringptr && binnamekeyfound && binname && depth == 4)
if (depth == 3 && grub_strcmp (tagstart + 1, "key") == 0)
keyptr = ptr1 + 1;
if (depth == 3 && grub_strcmp (tagstart + 1, "string") == 0)
- stringptr = ptr1 + 1;
+ stringptr = ptr1 + 1;
else if (grub_strcmp (tagstart + 1, "/key") != 0)
{
osbundlekeyfound = 0;
binnamekeyfound = 0;
}
*ptr1 = '>';
-
+
if (tagstart[1] == '/')
depth--;
else
}
grub_free (buf);
- return ret;
+ return ret;
}
/* Load all loadable kexts placed under DIRNAME and matching OSBUNDLEREQUIRED */
grub_err_t
-grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
+grub_xnu_scan_dir_for_kexts (char *dirname, char *osbundlerequired,
int maxrecursion)
{
grub_device_t dev;
grub_fs_t fs;
const char *path;
- auto int load_hook (const char *filename,
+ auto int load_hook (const char *filename,
const struct grub_dirhook_info *info);
int load_hook (const char *filename, const struct grub_dirhook_info *info)
{
grub_memcmp (filename + grub_strlen (filename) - 5, ".kext", 5) != 0)
return 0;
- newdirname
+ newdirname
= grub_malloc (grub_strlen (dirname) + grub_strlen (filename) + 2);
/* It's a .kext. Try to load it. */
newdirname[grub_strlen (newdirname) + 1] = 0;
newdirname[grub_strlen (newdirname)] = '/';
grub_strcpy (newdirname + grub_strlen (newdirname), filename);
- grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
+ grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
maxrecursion);
if (grub_errno == GRUB_ERR_BAD_OS)
grub_errno = GRUB_ERR_NONE;
/* Load extension DIRNAME. (extensions are directories in xnu) */
grub_err_t
-grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
+grub_xnu_load_kext_from_dir (char *dirname, char *osbundlerequired,
int maxrecursion)
{
grub_device_t dev;
int usemacos = 0;
grub_file_t binfile;
- auto int load_hook (const char *filename,
+ auto int load_hook (const char *filename,
const struct grub_dirhook_info *info);
int load_hook (const char *filename, const struct grub_dirhook_info *info)
{
if (grub_strlen (filename) > 15)
return 0;
- grub_strcpy (newdirname + grub_strlen (dirname) + 1, filename);
+ grub_strcpy (newdirname + grub_strlen (dirname) + 1, filename);
- /* If the kext contains directory "Contents" all real stuff is in
+ /* If the kext contains directory "Contents" all real stuff is in
this directory. */
if (info->dir && grub_strcasecmp (filename, "Contents") == 0)
grub_xnu_load_kext_from_dir (newdirname, osbundlerequired,
/* Directory "Plugins" contains nested kexts. */
if (info->dir && grub_strcasecmp (filename, "Plugins") == 0)
- grub_xnu_scan_dir_for_kexts (newdirname, osbundlerequired,
+ grub_xnu_scan_dir_for_kexts (newdirname, osbundlerequired,
maxrecursion - 1);
- /* Directory "MacOS" contains executable, otherwise executable is
+ /* Directory "MacOS" contains executable, otherwise executable is
on the top. */
if (info->dir && grub_strcasecmp (filename, "MacOS") == 0)
usemacos = 1;
-
+
/* Info.plist is the file which governs our future actions. */
- if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
+ if (! info->dir && grub_strcasecmp (filename, "Info.plist") == 0
&& ! plistname)
plistname = grub_strdup (newdirname);
return 0;
return grub_error (GRUB_ERR_OUT_OF_MEMORY, "couldn't allocate buffer");
grub_strcpy (newdirname, dirname);
newdirname[grub_strlen (dirname)] = '/';
- newdirname[grub_strlen (dirname) + 1] = 0;
+ newdirname[grub_strlen (dirname) + 1] = 0;
device_name = grub_file_get_device_name (dirname);
dev = grub_device_open (device_name);
if (dev)
newpath = newdirname;
else
newpath++;
-
+
/* Look at the directory. */
if (fs)
(fs->dir) (dev, path, load_hook);
- if (plistname && grub_xnu_check_os_bundle_required
+ if (plistname && grub_xnu_check_os_bundle_required
(plistname, osbundlerequired, &binsuffix))
{
if (binsuffix)
{
/* Open the binary. */
- char *binname = grub_malloc (grub_strlen (dirname)
- + grub_strlen (binsuffix)
+ char *binname = grub_malloc (grub_strlen (dirname)
+ + grub_strlen (binsuffix)
+ sizeof ("/MacOS/"));
grub_strcpy (binname, dirname);
if (usemacos)
grub_strcpy (binname + grub_strlen (binname), binsuffix);
grub_dprintf ("xnu", "%s:%s\n", plistname, binname);
binfile = grub_gzfile_open (binname, 1);
- if (! binfile)
+ if (! binfile)
grub_errno = GRUB_ERR_NONE;
- /* Load the extension. */
+ /* Load the extension. */
grub_xnu_load_driver (plistname, binfile);
grub_free (binname);
grub_free (binsuffix);
if (! data)
{
grub_file_close (file);
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"Could load device tree into memory");
}
if (grub_file_read (file, data, datalen) != (grub_ssize_t) datalen)
{
- grub_file_close (file);
+ grub_file_close (file);
grub_free (data);
grub_error_push ();
return grub_error (GRUB_ERR_BAD_OS, "Couldn't read file %s", args[0]);
}
}
return grub_xnu_load_driver (grub_strcmp (args[0], "-") ? args[0] : 0,
- binfile);
+ binfile);
}
/* load kext normally. */
return grub_error (GRUB_ERR_BAD_ARGUMENT, "directory name required");
if (argc == 1)
- return grub_xnu_scan_dir_for_kexts (args[0],
+ return grub_xnu_scan_dir_for_kexts (args[0],
"console,root,local-root,network-root",
10);
else
char *osbundlerequired = grub_strdup (args[1]), *ptr;
grub_err_t err;
if (! osbundlerequired)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate string temporary space");
for (ptr = osbundlerequired; *ptr; ptr++)
*ptr = grub_tolower (*ptr);
{
grub_err_t err;
if (argc != 1)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
+
err = grub_video_bitmap_load (&grub_xnu_bitmap, args[0]);
if (err)
grub_xnu_bitmap = 0;
{
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
-
+
return grub_xnu_resume (args[0]);
}
#endif
locked = 0;
}
-static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, cmd_kextdir,
+static grub_command_t cmd_kernel, cmd_mkext, cmd_kext, cmd_kextdir,
cmd_ramdisk, cmd_devtree, cmd_resume, cmd_splash;
GRUB_MOD_INIT(xnu)
"Load XNU extension package.");
cmd_kext = grub_register_command ("xnu_kext", grub_cmd_xnu_kext, 0,
"Load XNU extension.");
- cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
+ cmd_kextdir = grub_register_command ("xnu_kextdir", grub_cmd_xnu_kextdir,
"xnu_kextdir DIRECTORY [OSBundleRequired]",
"Load XNU extension directory");
cmd_ramdisk = grub_register_command ("xnu_ramdisk", grub_cmd_xnu_ramdisk, 0,
"Load a splash image for XNU");
#ifndef GRUB_UTIL
- cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
+ cmd_resume = grub_register_command ("xnu_resume", grub_cmd_xnu_resume,
0, "Load XNU hibernate image.");
#endif
my_mod=mod;
file = grub_file_open (imagename);
if (! file)
return 0;
-
+
/* Read the header. */
if (grub_file_read (file, (char *) &hibhead, sizeof (hibhead))
!=sizeof (hibhead))
{
grub_file_close (file);
- return grub_error (GRUB_ERR_READ_ERROR,
+ return grub_error (GRUB_ERR_READ_ERROR,
"cannot read the hibernate header");
}
if (hibhead.magic != GRUB_XNU_HIBERNATE_MAGIC)
{
grub_file_close (file);
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"hibernate header has incorrect magic number");
}
if (hibhead.encoffset)
{
grub_file_close (file);
- return grub_error (GRUB_ERR_BAD_OS,
+ return grub_error (GRUB_ERR_BAD_OS,
"encrypted images aren't supported yet");
}
if (grub_xnu_hibernate_image)
grub_free (grub_xnu_hibernate_image);
- /* Try to allocate necessary space.
+ /* Try to allocate necessary space.
FIXME: mm isn't good enough yet to handle huge allocations.
*/
grub_xnu_hibernate_image = buf = grub_malloc (hibhead.image_size);
if (! buf)
{
grub_file_close (file);
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"not enough memory to load image");
}
/* Read image. */
- if (grub_file_seek (file, 0) == (grub_off_t)-1
+ if (grub_file_seek (file, 0) == (grub_off_t)-1
|| grub_file_read (file, buf, hibhead.image_size)
!= (grub_ssize_t) hibhead.image_size)
{
/* Prepare asm helper. */
grub_memcpy (codetmp, ((grub_uint8_t *) buf) + total_header_size, codesize);
- grub_memcpy (codetmp + codesize, grub_xnu_launcher_start,
- grub_xnu_launcher_end - grub_xnu_launcher_start);
+ grub_memcpy (codetmp + codesize, grub_xnu_launcher_start,
+ grub_xnu_launcher_end - grub_xnu_launcher_start);
/* We're ready now. */
- grub_loader_set ((grub_err_t (*) (void)) (codetmp + codesize),
+ grub_loader_set ((grub_err_t (*) (void)) (codetmp + codesize),
grub_xnu_resume_unload, 0);
/* Prevent module from unloading. */
((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size)))
grub_err_t
-grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
- grub_uint64_t,
+grub_machine_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+ grub_uint64_t,
grub_uint32_t))
{
grub_efi_uintn_t mmap_size = 0;
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{
grub_dprintf ("mmap", "EFI memory region 0x%llx-0x%llx: %d\n",
- (unsigned long long) desc->physical_start,
+ (unsigned long long) desc->physical_start,
(unsigned long long) desc->physical_start
+ desc->num_pages * 4096, desc->type);
switch (desc->type)
{
case GRUB_EFI_RUNTIME_SERVICES_CODE:
- hook (desc->physical_start, desc->num_pages * 4096,
+ hook (desc->physical_start, desc->num_pages * 4096,
GRUB_MACHINE_MEMORY_CODE);
break;
case GRUB_EFI_MEMORY_MAPPED_IO:
case GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE:
case GRUB_EFI_PAL_CODE:
- hook (desc->physical_start, desc->num_pages * 4096,
+ hook (desc->physical_start, desc->num_pages * 4096,
GRUB_MACHINE_MEMORY_RESERVED);
break;
case GRUB_EFI_BOOT_SERVICES_CODE:
case GRUB_EFI_BOOT_SERVICES_DATA:
case GRUB_EFI_CONVENTIONAL_MEMORY:
- hook (desc->physical_start, desc->num_pages * 4096,
+ hook (desc->physical_start, desc->num_pages * 4096,
GRUB_MACHINE_MEMORY_AVAILABLE);
break;
case GRUB_EFI_ACPI_RECLAIM_MEMORY:
- hook (desc->physical_start, desc->num_pages * 4096,
+ hook (desc->physical_start, desc->num_pages * 4096,
GRUB_MACHINE_MEMORY_ACPI);
break;
case GRUB_EFI_ACPI_MEMORY_NVS:
- hook (desc->physical_start, desc->num_pages * 4096,
+ hook (desc->physical_start, desc->num_pages * 4096,
GRUB_MACHINE_MEMORY_NVS);
break;
}
return GRUB_ERR_NONE;
}
-static inline grub_efi_memory_type_t
+static inline grub_efi_memory_type_t
make_efi_memtype (int type)
{
switch (type)
case GRUB_MACHINE_MEMORY_CODE:
return GRUB_EFI_RUNTIME_SERVICES_CODE;
- /* No way to remove a chunk of memory from EFI mmap.
+ /* No way to remove a chunk of memory from EFI mmap.
So mark it as unusable. */
case GRUB_MACHINE_MEMORY_HOLE:
-
+
default:
case GRUB_MACHINE_MEMORY_RESERVED:
case GRUB_MACHINE_MEMORY_NVS:
return GRUB_EFI_ACPI_RECLAIM_MEMORY;
-
+
}
}
curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
if (! curover)
return 0;
-
+
b = grub_efi_system_table->boot_services;
address = start & (~0x3ffULL);
pages = (end - address + 0x3ff) >> 12;
grub_free (curover);
return 0;
}
- status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS,
+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ADDRESS,
make_efi_memtype (type), pages, &address);
if (status != GRUB_EFI_SUCCESS)
{
return curover->handle;
}
-grub_err_t
+grub_err_t
grub_mmap_unregister (int handle)
{
struct overlay *curover, *prevover;
b = grub_efi_system_table->boot_services;
-
- for (curover = overlays, prevover = 0; curover;
+
+ for (curover = overlays, prevover = 0; curover;
prevover = curover, curover = curover->next)
{
if (curover->handle == handle)
/* Result is always page-aligned. */
void *
-grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)),
+grub_mmap_malign_and_register (grub_uint64_t align __attribute__ ((unused)),
grub_uint64_t size,
- int *handle, int type,
+ int *handle, int type,
int flags __attribute__ ((unused)))
{
grub_efi_physical_address_t address;
curover = (struct overlay *) grub_malloc (sizeof (struct overlay));
if (! curover)
return 0;
-
+
b = grub_efi_system_table->boot_services;
address = 0xffffffff;
#endif
pages = (size + 0x3ff) >> 12;
- status = efi_call_4 (b->allocate_pages, atype,
+ status = efi_call_4 (b->allocate_pages, atype,
make_efi_memtype (type), pages, &address);
if (status != GRUB_EFI_SUCCESS)
{
/* Uggh, the address 0 was allocated... This is too annoying,
so reallocate another one. */
address = 0xffffffff;
- status = efi_call_4 (b->allocate_pages, atype,
+ status = efi_call_4 (b->allocate_pages, atype,
make_efi_memtype (type), pages, &address);
grub_efi_free_pages (0, pages);
if (status != GRUB_EFI_SUCCESS)
return 0;
}
-
+
curover->next = overlays;
curover->handle = curhandle++;
curover->address = address;
return UINT_TO_PTR (curover->address);
}
-void
+void
grub_mmap_free_and_unregister (int handle)
{
grub_mmap_unregister (handle);
{
grub_uint64_t highestlow = 0;
- auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
+ auto int NESTED_FUNC_ATTR find_hook (grub_uint64_t, grub_uint64_t,
grub_uint32_t);
- int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize,
+ int NESTED_FUNC_ATTR find_hook (grub_uint64_t start, grub_uint64_t rangesize,
grub_uint32_t memtype)
{
grub_uint64_t end = start + rangesize;
{
grub_free (ret);
return 0;
- }
+ }
return ret;
}
return;
addr = cur->start;
-
+
grub_mmap_unregister (handle);
if (addr >= 0x100000)
} __attribute__((packed));
-static grub_err_t
+static grub_err_t
preboot (int noreturn __attribute__ ((unused)))
{
struct grub_e820_mmap_entry *hookmmap, *hookmmapcur;
- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
+ auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
grub_uint32_t);
- int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size,
+ int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr, grub_uint64_t size,
grub_uint32_t type)
{
grub_dprintf ("mmap", "mmap chunk %llx-%llx:%x\n", addr, addr + size, type);
}
if (! hooktarget)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"no space is allocated for memory hook");
grub_dprintf ("mmap", "installing preboot handlers\n");
- hookmmapcur = hookmmap = (struct grub_e820_mmap_entry *)
- ((grub_uint8_t *) hooktarget + (&grub_machine_mmaphook_end
+ hookmmapcur = hookmmap = (struct grub_e820_mmap_entry *)
+ ((grub_uint8_t *) hooktarget + (&grub_machine_mmaphook_end
- &grub_machine_mmaphook_start));
- grub_mmap_iterate (fill_hook);
+ grub_mmap_iterate (fill_hook);
grub_machine_mmaphook_mmap_num = hookmmapcur - hookmmap;
grub_machine_mmaphook_kblow = grub_mmap_get_lower () >> 10;
- grub_machine_mmaphook_kbin16mb
+ grub_machine_mmaphook_kbin16mb
= min (grub_mmap_get_upper (),0x3f00000ULL) >> 10;
- grub_machine_mmaphook_64kbin4gb
+ grub_machine_mmaphook_64kbin4gb
= min (grub_mmap_get_post64 (), 0xfc000000ULL) >> 16;
/* Correct BDA. */
*((grub_uint16_t *) 0x4a) = PTR_TO_UINT32 (hooktarget) >> 4;
*((grub_uint16_t *) 0x56) = PTR_TO_UINT32 (hooktarget) >> 4;
- *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12
+ *((grub_uint16_t *) 0x48) = &grub_machine_mmaphook_int12
- &grub_machine_mmaphook_start;
*((grub_uint16_t *) 0x54) = &grub_machine_mmaphook_int15
- &grub_machine_mmaphook_start;
return GRUB_ERR_NONE;
}
-static grub_err_t
+static grub_err_t
malloc_hook (void)
{
static int reentry = 0;
static int slots_available = 0;
int hooksize;
int regcount = 0;
- auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
+ auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
grub_uint32_t);
- int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
+ int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
grub_uint32_t type __attribute__ ((unused)))
{
regcount++;
+ regcount * sizeof (struct grub_e820_mmap_entry);
/* Allocate an integer number of KiB. */
hooksize = ((hooksize - 1) | 0x3ff) + 1;
- slots_available = (hooksize - (&grub_machine_mmaphook_end
+ slots_available = (hooksize - (&grub_machine_mmaphook_end
- &grub_machine_mmaphook_start))
/ sizeof (struct grub_e820_mmap_entry);
reentry = 1;
- hooktarget
- = grub_mmap_malign_and_register (16, hooksize, &mmapregion,
+ hooktarget
+ = grub_mmap_malign_and_register (16, hooksize, &mmapregion,
GRUB_MACHINE_MEMORY_RESERVED,
GRUB_MMAP_MALLOC_LOW);
reentry = 0;
}
grub_err_t
-grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
- grub_uint64_t size __attribute__ ((unused)),
+grub_machine_mmap_register (grub_uint64_t start __attribute__ ((unused)),
+ grub_uint64_t size __attribute__ ((unused)),
int type __attribute__ ((unused)),
int handle __attribute__ ((unused)))
{
if (! preb_handle)
{
grub_dprintf ("mmap", "adding preboot\n");
- preb_handle
- = grub_loader_register_preboot_hook (preboot, preboot_rest,
+ preb_handle
+ = grub_loader_register_preboot_hook (preboot, preboot_rest,
GRUB_LOADER_PREBOOT_HOOK_PRIO_MEMORY);
if (! preb_handle)
return grub_errno;
#define DS(x) ((x) - segstart)
-segstart:
+segstart:
VARIABLE(grub_machine_mmaphook_start)
.code16
VARIABLE(grub_machine_mmaphook_int12)
.word 0
VARIABLE (grub_machine_mmaphook_int15segment)
.word 0
-
+
e801:
popf
push %ds
cmpw DS(EXT_C(grub_machine_mmaphook_mmap_num)), %bx
#endif
jb noclean
- xor %bx, %bx
-noclean:
+ xor %bx, %bx
+noclean:
mov $0x534d4150, %eax
pop %ds
clc
pop %ds
stc
xor %bx, %bx
- iret
-
+ iret
+
VARIABLE(grub_machine_mmaphook_mmap_num)
.word 0
VARIABLE(grub_machine_mmaphook_kblow)
#include <grub/mm.h>
#include <grub/misc.h>
-grub_uint64_t
+grub_uint64_t
grub_mmap_get_lower (void)
{
grub_uint64_t lower = 0;
return lower;
}
-grub_uint64_t
+grub_uint64_t
grub_mmap_get_upper (void)
{
grub_uint64_t upper = 0;
}
/* Count the continuous bytes after 64 MiB. */
-grub_uint64_t
+grub_uint64_t
grub_mmap_get_post64 (void)
{
grub_uint64_t post64 = 0;
#endif
grub_err_t
-grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
+grub_mmap_iterate (int NESTED_FUNC_ATTR (*hook) (grub_uint64_t,
grub_uint64_t, grub_uint32_t))
{
/* This function resolves overlapping regions and sorts the memory map.
It uses scanline (sweeping) algorithm.
*/
- /* If same page is used by multiple types it's resolved
+ /* If same page is used by multiple types it's resolved
according to priority:
1 - free memory
2 - memory usable by firmware-aware code
/* Number of mmap chunks. */
int mmap_num;
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
struct grub_mmap_region *cur;
#endif
-
- auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
+
+ auto int NESTED_FUNC_ATTR count_hook (grub_uint64_t, grub_uint64_t,
grub_uint32_t);
int NESTED_FUNC_ATTR count_hook (grub_uint64_t addr __attribute__ ((unused)),
grub_uint64_t size __attribute__ ((unused)),
return 0;
}
- auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
+ auto int NESTED_FUNC_ATTR fill_hook (grub_uint64_t, grub_uint64_t,
grub_uint32_t);
int NESTED_FUNC_ATTR fill_hook (grub_uint64_t addr,
grub_uint64_t size,
return 0;
}
-
+
mmap_num = 0;
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
for (cur = grub_mmap_overlays; cur; cur = cur->next)
mmap_num++;
#endif
grub_machine_mmap_iterate (count_hook);
-
+
/* Initialize variables. */
grub_memset (present, 0, sizeof (present));
- scanline_events = (struct grub_mmap_scan *)
+ scanline_events = (struct grub_mmap_scan *)
grub_malloc (sizeof (struct grub_mmap_scan) * 2 * mmap_num);
-
+
if (! scanline_events)
{
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate space for new memory map");
}
i = 0;
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
/* Register scanline events. */
for (cur = grub_mmap_overlays; cur; cur = cur->next)
{
scanline_events[i].pos = cur->start;
scanline_events[i].type = 0;
- if (cur->type == GRUB_MACHINE_MEMORY_HOLE
+ if (cur->type == GRUB_MACHINE_MEMORY_HOLE
|| (cur->type >= 0 && cur->type <= GRUB_MACHINE_MEMORY_MAX_TYPE
&& priority[cur->type]))
scanline_events[i].memtype = cur->type;
grub_machine_mmap_iterate (fill_hook);
- /* Primitive bubble sort. It has complexity O(n^2) but since we're
- unlikely to have more than 100 chunks it's probably one of the
+ /* Primitive bubble sort. It has complexity O(n^2) but since we're
+ unlikely to have more than 100 chunks it's probably one of the
fastest for one purpose. */
done = 1;
while (done)
for (i = 0; i < 2 * mmap_num - 1; i++)
if (scanline_events[i + 1].pos < scanline_events[i].pos
|| (scanline_events[i + 1].pos == scanline_events[i].pos
- && scanline_events[i + 1].type == 0
+ && scanline_events[i + 1].type == 0
&& scanline_events[i].type == 1))
{
t = scanline_events[i + 1];
curtype = k;
/* Announce region to the hook if necessary. */
- if ((curtype == -1 || curtype != lasttype)
+ if ((curtype == -1 || curtype != lasttype)
&& lastaddr != scanline_events[i].pos
&& lasttype != -1
&& lasttype != GRUB_MACHINE_MEMORY_HOLE
}
/* Update last values if necessary. */
- if (curtype == -1 || curtype != lasttype)
+ if (curtype == -1 || curtype != lasttype)
{
lasttype = curtype;
lastaddr = scanline_events[i].pos;
return GRUB_ERR_NONE;
}
-#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
+#ifndef GRUB_MMAP_REGISTER_BY_FIRMWARE
int
grub_mmap_register (grub_uint64_t start, grub_uint64_t size, int type)
{
grub_dprintf ("mmap", "registering\n");
- cur = (struct grub_mmap_region *)
+ cur = (struct grub_mmap_region *)
grub_malloc (sizeof (struct grub_mmap_region));
if (! cur)
{
- grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate memory map overlay");
return 0;
}
#define CHUNK_SIZE 0x400
-static inline grub_uint64_t
+static inline grub_uint64_t
fill_mask (grub_uint64_t addr, grub_uint64_t mask, grub_uint64_t iterator)
{
int i, j;
grub_uint64_t badaddr, badmask;
auto int NESTED_FUNC_ATTR hook (grub_uint64_t, grub_uint64_t, grub_uint32_t);
- int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
- grub_uint64_t size,
+ int NESTED_FUNC_ATTR hook (grub_uint64_t addr,
+ grub_uint64_t size,
grub_uint32_t type __attribute__ ((unused)))
{
grub_uint64_t iterator, low, high, cur;
int tail, var;
int i;
- grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr,
- (unsigned long long) size);
+ grub_dprintf ("badram", "hook %llx+%llx\n", (unsigned long long) addr,
+ (unsigned long long) size);
/* How many trailing zeros? */
for (tail = 0; ! (badmask & (1ULL << tail)); tail++);
{
low = 0;
high = ~0ULL;
- /* Find starting value. Keep low and high such that
+ /* Find starting value. Keep low and high such that
fill_mask (low) < addr and fill_mask (high) >= addr;
*/
while (high - low > 1)
}
for (; iterator < (1ULL << (var - tail))
- && (cur = fill_mask (badaddr, badmask, iterator)) < addr + size;
+ && (cur = fill_mask (badaddr, badmask, iterator)) < addr + size;
iterator++)
{
- grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
- (long long) cur, (long long) (1ULL << tail) - 1);
+ grub_dprintf ("badram", "%llx (size %llx) is a badram range\n",
+ (long long) cur, (long long) (1ULL << tail) - 1);
grub_mmap_register (cur, (1ULL << tail) - 1, GRUB_MACHINE_MEMORY_HOLE);
}
return 0;
no point in providing sub-page chunks. */
badmask &= ~(CHUNK_SIZE - 1);
- grub_dprintf ("badram", "badram %llx:%llx\n",
+ grub_dprintf ("badram", "badram %llx:%llx\n",
(unsigned long long) badaddr, (unsigned long long) badmask);
grub_mmap_iterate (hook);
GRUB_MOD_INIT(mmap)
{
cmd = grub_register_command ("badram", grub_cmd_badram,
- "badram ADDR1,MASK1[,ADDR2,MASK2[,...]]",
+ "badram ADDR1,MASK1[,ADDR2,MASK2[,...]]",
"declare memory regions as badram");
}
/* Copy the older part. */
grub_memmove (hist_lines, old_hist_lines + hist_pos,
(hist_size - hist_pos) * sizeof (char *));
-
+
/* Copy the newer part. */
grub_memmove (hist_lines + hist_size - hist_pos, old_hist_lines,
hist_end * sizeof (char *));
what = "things";
break;
}
-
+
grub_printf ("\nPossible %s are:\n", what);
}
xpos = (plen + lpos) % 79;
ypos = ystart + (plen + lpos) / 79;
grub_gotoxy (xpos, ypos);
-
+
grub_refresh ();
}
-
+
void cl_print (int pos, int c)
{
char *p;
if (xpos++ > 78)
{
grub_putchar ('\n');
-
+
xpos = 1;
if (ypos == (unsigned) (grub_getxy () & 0xFF))
ystart--;
grub_putchar (*p);
}
}
-
+
void cl_insert (const char *str)
{
grub_size_t len = grub_strlen (str);
cl_print (lpos - len, echo_char);
cl_set_pos ();
}
-
+
grub_refresh ();
}
cl_print (lpos, ' ');
lpos = saved_lpos;
cl_set_pos ();
-
+
grub_memmove (buf + lpos, buf + lpos + len, llen - lpos + 1);
llen -= len;
cl_print (lpos, echo_char);
cl_set_pos ();
}
-
+
grub_refresh ();
}
-
+
plen = grub_strlen (prompt);
lpos = llen = 0;
buf[0] = '\0';
if ((grub_getxy () >> 8) != 0)
grub_putchar ('\n');
-
+
grub_printf (prompt);
-
+
xpos = plen;
ystart = ypos = (grub_getxy () & 0xFF);
-
+
cl_insert (cmdline);
if (hist_used == 0)
{
char *insert;
int restore;
-
+
/* Backup the next character and make it 0 so it will
be easy to use string functions. */
char backup = buf[lpos];
buf[lpos] = '\0';
-
+
insert = grub_normal_do_completion (buf, &restore,
print_completion);
/* Restore the original string. */
buf[lpos] = backup;
-
+
if (restore)
{
/* Restore the prompt. */
if (lpos > 0)
{
grub_size_t n = lpos;
-
+
if (kill_buf)
grub_free (kill_buf);
else
break;
/* fall through */
-
+
case 4: /* Ctrl-d */
if (lpos < llen)
cl_delete (1);
grub_history_replace (histpos, buf);
grub_history_add ("");
}
-
+
grub_memcpy (cmdline, buf + lpos, llen - lpos + 1);
return 1;
case 2:
if (print_func)
print_func (match, type, 0);
-
+
/* Fall through. */
default:
if (print_func)
print_func (completion, type, num_found - 1);
-
+
/* Detect the matched portion. */
while (*s && *t && *s == *t)
{
break;
}
}
-
+
return 0;
}
char *partition_name = grub_partition_get_name (p);
char *name;
int ret;
-
+
if (! partition_name)
return 1;
grub_sprintf (name, "%s,%s", disk_name, partition_name);
grub_free (partition_name);
-
+
ret = add_completion (name, ")", GRUB_COMPLETION_TYPE_PARTITION);
grub_free (name);
return ret;
if (add_completion (fname, "", GRUB_COMPLETION_TYPE_FILE))
return 1;
}
-
+
return 0;
}
iterate_dev (const char *devname)
{
grub_device_t dev;
-
+
/* Complete the partition part. */
dev = grub_device_open (devname);
-
+
if (dev)
{
if (dev->disk && dev->disk->has_partitions)
return 1;
}
}
-
+
grub_errno = GRUB_ERR_NONE;
return 0;
}
return 1;
}
}
-
+
return 0;
}
/* Check if this is a device or a partition. */
char *p = grub_strchr (++current_word, ',');
grub_device_t dev;
-
+
if (! p)
{
/* Complete the disk part. */
dev = grub_device_open (current_word);
*p = ',';
grub_errno = GRUB_ERR_NONE;
-
+
if (dev)
{
if (dev->disk && dev->disk->has_partitions)
return 1;
}
}
-
+
grub_device_close (dev);
}
else
grub_fs_t fs;
grub_device_t dev;
int ret = 0;
-
+
device = grub_file_get_device_name (current_word);
if (grub_errno != GRUB_ERR_NONE)
return 1;
-
+
dev = grub_device_open (device);
if (! dev)
{
ret = 1;
goto fail;
}
-
+
fs = grub_fs_probe (dev);
if (! fs)
{
if (dir)
{
char *dirfile;
-
+
current_word = last_dir + 1;
-
+
dir = grub_strdup (dir);
if (! dir)
{
ret = 1;
goto fail;
}
-
+
/* Cut away the filename part. */
dirfile = grub_strrchr (dir, '/');
dirfile[1] = '\0';
-
+
/* Iterate the directory. */
(fs->dir) (dev, dir, iterate_dir);
-
+
grub_free (dir);
-
+
if (grub_errno)
{
ret = 1;
ret = 1;
goto fail;
}
-
+
suffix = "";
num_found = 1;
}
const struct grub_arg_option *option;
char shortarg[] = "- ";
- cmd = grub_command_find (command);
+ cmd = grub_command_find (command);
if (!cmd || !(cmd->flags & GRUB_COMMAND_FLAG_EXTCMD))
return 0;
if (num_found == 1)
grub_strcat (ret, suffix);
-
+
if (*ret == '\0')
{
grub_free (ret);
goto fail;
}
-
+
grub_free (argv[0]);
grub_free (match);
return ret;
{
int i;
int div;
- grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- /* In the period of validity of unixtime all years divisible by 4
+ grub_uint8_t months[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ /* In the period of validity of unixtime all years divisible by 4
are bissextile*/
- /* Convenience: let's have 3 consecutive non-bissextile years
+ /* Convenience: let's have 3 consecutive non-bissextile years
at the beginning of the epoch. So count from 1973 instead of 1970 */
nix -= 3*SECPERYEAR + SECPERDAY;
/* Transform C divisions and modulos to mathematical ones */
datetime->year += nix / SECPERYEAR;
nix %= SECPERYEAR;
}
- for (i = 0; i < 12
- && nix >= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
+ for (i = 0; i < 12
+ && nix >= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
? 29 : months[i]))*SECPERDAY; i++)
- nix -= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
+ nix -= ((grub_int32_t) (i==1 && datetime->year % 4 == 0
? 29 : months[i]))*SECPERDAY;
- datetime->month = i + 1;
+ datetime->month = i + 1;
datetime->day = 1 + (nix / SECPERDAY);
nix %= SECPERDAY;
- datetime->hour = (nix / SECPERHOUR);
+ datetime->hour = (nix / SECPERHOUR);
nix %= SECPERHOUR;
datetime->minute = nix / SECPERMIN;
datetime->second = nix % SECPERMIN;
grub_free (cmdline);
cmdline = 0;
}
-
+
return cmdline;
}
{
grub_file_t file;
grub_parser_t old_parser = 0;
-
+
auto grub_err_t getline (char **line, int cont);
grub_err_t getline (char **line, int cont __attribute__ ((unused)))
{
grub_command_execute ("parser.sh", 0, 0);
reader_nested = nested;
-
+
if (config)
{
menu = read_config_file (config);
so that it won't get broken by longjmp. */
static char *config;
const char *prefix;
-
+
prefix = grub_env_get ("prefix");
if (prefix)
{
{
int i;
char *p;
-
+
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
y + GRUB_TERM_FIRST_ENTRY_Y);
print_empty_line (int y)
{
int i;
-
+
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
y + GRUB_TERM_FIRST_ENTRY_Y);
{
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
GRUB_TERM_FIRST_ENTRY_Y);
-
+
if (flag)
grub_putcode (GRUB_TERM_DISP_UP);
else
grub_putchar (' ');
}
-
+
/* Print a down arrow. */
static void
print_down (int flag)
{
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
-
+
if (flag)
grub_putcode (GRUB_TERM_DISP_DOWN);
else
grub_putchar (' ');
}
-
+
/* Draw the lines of the screen SCREEN. */
static void
update_screen (struct screen *screen, int region_start, int region_column,
int y;
int i;
struct line *linep;
-
+
/* Check if scrolling is necessary. */
if (screen->y < 0 || screen->y >= GRUB_TERM_NUM_ENTRIES)
{
screen->y = 0;
else
screen->y = GRUB_TERM_NUM_ENTRIES - 1;
-
+
region_start = 0;
region_column = 0;
up = 1;
linep--;
y -= get_logical_num_lines (linep);
}
-
+
if (y < 0 || i > 0)
up_flag = 1;
-
+
do
{
int column;
-
+
for (column = 0;
column <= linep->len && y < GRUB_TERM_NUM_ENTRIES;
column += GRUB_TERM_ENTRY_WIDTH, y++)
{
if (y < 0)
continue;
-
+
if (i == region_start)
{
if (region_column >= column
else if (i > region_start && mode == ALL_LINES)
print_line (linep, column, 0, y);
}
-
+
if (y == GRUB_TERM_NUM_ENTRIES)
{
if (column <= linep->len || i + 1 < screen->num_lines)
down_flag = 1;
}
-
+
linep++;
i++;
if (mode == ALL_LINES && i == screen->num_lines)
for (; y < GRUB_TERM_NUM_ENTRIES; y++)
print_empty_line (y);
-
+
}
while (y < GRUB_TERM_NUM_ENTRIES);
-
+
/* Draw up and down arrows. */
if (up)
print_up (up_flag);
if (down)
print_down (down_flag);
}
-
+
/* Place the cursor. */
grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1 + screen->x,
GRUB_TERM_FIRST_ENTRY_Y + screen->y);
-
+
grub_refresh ();
}
struct line *current_linep;
struct line *next_linep;
int size;
-
+
/* Make a new line. */
screen->num_lines++;
screen->lines = grub_realloc (screen->lines,
if (! init_line (screen->lines + screen->line + 1))
return 0;
-
+
/* Fold the line. */
current_linep = screen->lines + screen->line;
next_linep = current_linep + 1;
size = current_linep->len - screen->column;
-
+
if (! ensure_space (next_linep, size))
return 0;
-
+
grub_memmove (next_linep->buf,
current_linep->buf + screen->column,
size);
mode = ALL_LINES;
down = 1; /* XXX not optimal. */
-
+
/* Move the cursor. */
screen->column = screen->real_column = 0;
screen->line++;
region_start = screen->line;
region_column = screen->column;
}
-
+
if (orig_num != new_num)
{
mode = ALL_LINES;
screen->x += size;
screen->y += screen->x / GRUB_TERM_ENTRY_WIDTH;
screen->x %= GRUB_TERM_ENTRY_WIDTH;
-
+
s = p;
}
}
if (update)
update_screen (screen, region_start, region_column, 0, down, mode);
-
+
return 1;
}
for (i = 0; i < screen->num_lines; i++)
{
struct line *linep = screen->lines + i;
-
+
if (linep)
grub_free (linep->buf);
}
forward_char (struct screen *screen, int update)
{
struct line *linep;
-
+
linep = screen->lines + screen->line;
if (screen->column < linep->len)
{
else if (screen->line > 0)
{
struct line *linep;
-
+
screen->line--;
linep = screen->lines + screen->line;
screen->column = linep->len;
if (update)
update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
+
return 1;
}
{
struct line *linep;
int dy;
-
+
/* How many physical lines from the current position
to the first physical line? */
dy = screen->column / GRUB_TERM_ENTRY_WIDTH;
-
+
screen->line--;
-
+
linep = screen->lines + screen->line;
if (linep->len < screen->real_column)
screen->column = linep->len;
else
screen->column = screen->real_column;
-
+
/* How many physical lines from the current position
to the last physical line? */
dy += (linep->len / GRUB_TERM_ENTRY_WIDTH
- screen->column / GRUB_TERM_ENTRY_WIDTH);
-
+
screen->y -= dy + 1;
screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
}
if (update)
update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
+
return 1;
}
{
struct line *linep;
int dy;
-
+
/* How many physical lines from the current position
to the last physical line? */
linep = screen->lines + screen->line;
dy = (linep->len / GRUB_TERM_ENTRY_WIDTH
- screen->column / GRUB_TERM_ENTRY_WIDTH);
-
+
screen->line++;
-
+
linep++;
if (linep->len < screen->real_column)
screen->column = linep->len;
else
screen->column = screen->real_column;
-
+
/* How many physical lines from the current position
to the first physical line? */
dy += screen->column / GRUB_TERM_ENTRY_WIDTH;
-
+
screen->y += dy + 1;
screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
}
if (update)
update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
+
return 1;
}
if (update)
update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
+
return 1;
}
end_of_line (struct screen *screen, int update)
{
struct line *linep;
-
+
linep = screen->lines + screen->line;
screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH
- screen->column / GRUB_TERM_ENTRY_WIDTH);
if (update)
update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
-
+
return 1;
}
int start = screen->num_lines;
int column = 0;
int down = 0;
-
+
linep = screen->lines + screen->line;
if (linep->len > screen->column)
{
int orig_num, new_num;
orig_num = get_logical_num_lines (linep);
-
+
grub_memmove (linep->buf + screen->column,
linep->buf + screen->column + 1,
linep->len - screen->column - 1);
(screen->num_lines - screen->line - 2)
* sizeof (struct line));
screen->num_lines--;
-
+
mode = ALL_LINES;
start = screen->line;
column = screen->column;
saved_column = screen->column;
saved_line = screen->line;
-
+
if (! backward_char (screen, 0))
return 0;
char *p;
int size;
int offset;
-
+
p = screen->killed_text;
if (! continuous && p)
p[0] = '\0';
-
+
linep = screen->lines + screen->line;
size = linep->len - screen->column;
-
+
if (p)
offset = grub_strlen (p);
else
offset = 0;
-
+
if (size > 0)
{
enum update_mode mode = SINGLE_LINE;
int down = 0;
int orig_num, new_num;
-
+
p = grub_realloc (p, offset + size + 1);
if (! p)
return 0;
p[offset + size - 1] = '\0';
screen->killed_text = p;
-
+
orig_num = get_logical_num_lines (linep);
linep->len = screen->column;
new_num = get_logical_num_lines (linep);
p[offset + 1] = '\0';
screen->killed_text = p;
-
+
return delete_char (screen, update);
}
-
+
return 1;
}
open_line (struct screen *screen, int update)
{
int saved_y = screen->y;
-
+
if (! insert_string (screen, "\n", 0))
return 0;
store_completion (const char *item, grub_completion_type_t type, int count)
{
char *p;
-
+
if (count == 0)
{
/* If this is the first time, print a label. */
what = "things";
break;
}
-
+
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
grub_printf (" Possible %s are:\n ", what);
}
+ (int) grub_strlen (item) + 1 + 1))
{
grub_size_t new_len;
-
+
new_len = completion_buffer.len + grub_strlen (item) + 80;
p = grub_realloc (completion_buffer.buf, new_len);
if (! p)
count++;
else
count = 0;
-
+
pos = grub_getxy ();
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
-
+
completion_buffer.buf = 0;
completion_buffer.len = 0;
completion_buffer.max_len = 0;
insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
linep->buf[screen->column] = saved_char;
-
+
if (restore)
{
char *p = completion_buffer.buf;
screen->completion_shown = 1;
-
+
if (p)
{
int num_sections = ((completion_buffer.len + GRUB_TERM_WIDTH - 8 - 1)
grub_putcode (GRUB_TERM_DISP_LEFT);
else
grub_putchar (' ');
-
+
while (*p && p < endp)
grub_putchar (*p++);
-
+
if (*p)
grub_putcode (GRUB_TERM_DISP_RIGHT);
}
}
grub_gotoxy (pos >> 8, pos & 0xFF);
-
+
if (insert)
{
insert_string (screen, insert, update);
}
else if (update)
grub_refresh ();
-
+
grub_free (completion_buffer.buf);
return 1;
}
{
grub_uint16_t pos;
int i, j;
-
+
pos = grub_getxy ();
grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
-
+
for (i = 0; i < 2; i++)
{
for (j = 0; j < GRUB_TERM_WIDTH - 1; j++)
grub_putchar (' ');
grub_putchar ('\n');
}
-
+
grub_gotoxy (pos >> 8, pos & 0xFF);
grub_refresh ();
}
currline++;
return 0;
}
-
+
grub_cls ();
grub_printf (" Booting a command list\n\n");
{
struct screen *screen;
int prev_c;
-
+
screen = make_screen (entry);
if (! screen)
return;
update_screen (screen, 0, 0, 1, 1, ALL_LINES);
grub_setcursor (1);
prev_c = '\0';
-
+
while (1)
{
int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
clear_completions ();
screen->completion_shown = 0;
}
-
+
switch (c)
{
case 16: /* C-p */
if (! forward_char (screen, 1))
goto fail;
break;
-
+
case 2: /* C-b */
if (! backward_char (screen, 1))
goto fail;
if (! end_of_line (screen, 1))
goto fail;
break;
-
+
case '\t': /* C-i */
if (! complete (screen, prev_c == c, 1))
goto fail;
break;
-
+
case 4: /* C-d */
if (! delete_char (screen, 1))
goto fail;
if (! backward_delete_char (screen, 1))
goto fail;
break;
-
+
case 11: /* C-k */
if (! kill_line (screen, prev_c == c, 1))
goto fail;
break;
-
+
case 21: /* C-u */
/* FIXME: What behavior is good for this key? */
break;
-
+
case 25: /* C-y */
if (! yank (screen, 1))
goto fail;
case 12: /* C-l */
/* FIXME: centering. */
goto refresh;
-
+
case 15: /* C-o */
if (! open_line (screen, 1))
goto fail;
case '\e':
destroy_screen (screen);
return;
-
+
case 3: /* C-c */
grub_cmdline_run (1);
goto refresh;
-
+
case 24: /* C-x */
if (! run (screen))
goto fail;
case 20: /* C-t */
/* FIXME */
break;
-
+
default:
if (grub_isprint (c))
{
fail:
destroy_screen (screen);
-
+
grub_cls ();
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
grub_menu_viewer_show_menu (grub_menu_t menu, int nested)
{
grub_menu_viewer_t cur = get_current_menu_viewer ();
- if (!cur)
+ if (!cur)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "No menu viewer available.");
return cur->show_menu (menu, nested);
grub_printf ("\tPartition %s: ", name);
else
grub_printf ("Device %s: ", name);
-
+
dev = grub_device_open (name);
if (! dev)
grub_printf ("Filesystem cannot be accessed");
grub_printf ("Unknown filesystem");
else
grub_printf ("Partition table");
-
+
grub_device_close (dev);
}
grub_disk_addr_t sector;
grub_err_t err;
grub_partition_t p;
-
+
/* Enforce raw disk access. */
raw.partition = 0;
grub_uint32_t badblcklst;
grub_uint32_t partitionlst;
grub_uint32_t fslst;
-
+
/* The other information is not important for us. */
} __attribute__ ((packed));
grub_uint32_t unused5[3];
grub_uint32_t lowcyl;
grub_uint32_t highcyl;
-
+
grub_uint32_t firstcyl;
} __attribute__ ((packed));
int partno = 0;
int next = -1;
unsigned pos;
-
+
/* Enforce raw disk access. */
raw = *disk;
raw.partition = 0;
-
+
/* The RDSK block is one of the first 15 blocks. */
for (pos = 0; pos < 15; pos++)
{
/* Read the RDSK block which is a descriptor for the entire disk. */
if (grub_disk_read (&raw, pos, 0, sizeof (rdsk), &rdsk))
return grub_errno;
-
+
if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
{
/* Found the first PART block. */
if (next == -1)
return grub_error (GRUB_ERR_BAD_PART_TABLE,
"Amiga partition map not found.");
-
+
/* The end of the partition list is marked using "-1". */
while (next != -1)
{
struct grub_amiga_partition apart;
-
+
/* Read the RDSK block which is a descriptor for the entire disk. */
if (grub_disk_read (&raw, next, 0, sizeof (apart), &apart))
return grub_errno;
-
+
/* Calculate the first block and the size of the partition. */
- part.start = (grub_be_to_cpu32 (apart.lowcyl)
+ part.start = (grub_be_to_cpu32 (apart.lowcyl)
* grub_be_to_cpu32 (apart.heads)
* grub_be_to_cpu32 (apart.block_per_track));
part.len = ((grub_be_to_cpu32 (apart.highcyl)
- grub_be_to_cpu32 (apart.lowcyl) + 1)
* grub_be_to_cpu32 (apart.heads)
* grub_be_to_cpu32 (apart.block_per_track));
-
+
part.offset = (grub_off_t) next * 512;
part.index = partno;
part.partmap = &grub_amiga_partition_map;
-
+
if (hook (disk, &part))
return grub_errno;
-
+
next = grub_be_to_cpu32 (apart.next);
partno++;
}
-
+
return 0;
}
char *s = (char *) str;
auto int find_func (grub_disk_t d, const grub_partition_t partition);
-
+
int find_func (grub_disk_t d __attribute__ ((unused)),
const grub_partition_t partition)
{
p = (grub_partition_t) grub_malloc (sizeof (*p));
if (! p)
return 1;
-
+
grub_memcpy (p, partition, sizeof (*p));
return 1;
}
-
+
return 0;
}
-
+
/* Get the partition number. */
partnum = grub_strtoul (s, 0, 10) - 1;
if (grub_errno)
/* Reserved. */
grub_uint32_t reserved2;
-
+
/* The entry point of the bootcode. */
grub_uint32_t bootcode_entrypoint;
char *s = (char *) str;
auto int find_func (grub_disk_t d, const grub_partition_t partition);
-
+
int find_func (grub_disk_t d __attribute__ ((unused)),
const grub_partition_t partition)
{
p = (grub_partition_t) grub_malloc (sizeof (*p));
if (! p)
return 1;
-
+
grub_memcpy (p, partition, sizeof (*p));
return 1;
}
-
+
return 0;
}
-
+
/* Get the partition number. */
partnum = grub_strtoul (s, 0, 10) - 1;
if (grub_errno)
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
return 0;
}
-
+
if (apple_partition_map_iterate (disk, find_func))
goto fail;
char *s = (char *) str;
auto int find_func (grub_disk_t d, const grub_partition_t partition);
-
+
int find_func (grub_disk_t d __attribute__ ((unused)),
const grub_partition_t partition)
{
p = (grub_partition_t) grub_malloc (sizeof (*p));
if (! p)
return 1;
-
+
grub_memcpy (p, partition, sizeof (*p));
return 1;
}
-
+
return 0;
}
-
+
/* Get the partition number. */
partnum = grub_strtoul (s, 0, 10) - 1;
if (grub_errno)
{
grub_partition_t p;
struct grub_pc_partition *pcdata;
-
+
char *s = (char *) str;
-
+
p = (grub_partition_t) grub_malloc (sizeof (*p));
if (! p)
return 0;
-
+
pcdata = (struct grub_pc_partition *) grub_malloc (sizeof (*pcdata));
if (! pcdata)
goto fail;
-
+
p->data = pcdata;
p->partmap = &grub_pc_partition_map;
-
+
/* Initialize some of the fields with invalid values. */
pcdata->bsd_part = pcdata->dos_type = pcdata->bsd_type = p->index = -1;
/* Get the DOS partition number. The number is counted from one for
the user interface, and from zero internally. */
pcdata->dos_part = grub_strtoul (s, &s, 0) - 1;
-
+
if (grub_errno)
{
/* Not found. Maybe only a BSD label is specified. */
goto fail;
return p;
-
+
fail:
grub_free (p);
grub_free (pcdata);
/* Enforce raw disk access. */
raw = *disk;
raw.partition = 0;
-
+
p.offset = 0;
pcdata.ext_offset = 0;
pcdata.dos_part = -1;
p.data = &pcdata;
p.partmap = &grub_pc_partition_map;
-
+
while (1)
{
int i;
struct grub_pc_partition_entry *e;
-
+
/* Read the MBR. */
if (grub_disk_read (&raw, p.offset, 0, sizeof (mbr), &mbr))
goto finish;
for (p.index = 0; p.index < 4; p.index++)
{
e = mbr.entries + p.index;
-
+
p.start = p.offset + grub_le_to_cpu32 (e->start);
p.len = grub_le_to_cpu32 (e->length);
pcdata.bsd_part = -1;
&& ! grub_pc_partition_is_extended (e->type))
{
pcdata.dos_part++;
-
+
if (hook (disk, &p))
return 1;
p.start = grub_le_to_cpu32 (be->offset);
p.len = grub_le_to_cpu32 (be->size);
pcdata.bsd_type = be->fs_type;
-
+
if (be->fs_type != GRUB_PC_PARTITION_BSD_TYPE_UNUSED)
if (hook (disk, &p))
return 1;
for (i = 0; i < 4; i++)
{
e = mbr.entries + i;
-
+
if (grub_pc_partition_is_extended (e->type))
{
p.offset = pcdata.ext_offset + grub_le_to_cpu32 (e->start);
{
grub_partition_t p;
struct grub_pc_partition *pcdata;
-
+
auto int find_func (grub_disk_t d, const grub_partition_t partition);
int find_func (grub_disk_t d __attribute__ ((unused)),
grub_memcpy (pcdata, partdata, sizeof (*pcdata));
return 1;
}
-
+
return 0;
}
-
+
p = grub_partition_parse (str);
if (! p)
return 0;
-
+
pcdata = p->data;
pc_partition_map_iterate (disk, find_func);
if (grub_errno)
{
char *name;
struct grub_pc_partition *pcdata = p->data;
-
+
name = grub_malloc (13);
if (! name)
return 0;
{
grub_uint16_t *pos;
grub_uint16_t sum = 0;
-
+
for (pos = (grub_uint16_t *) label;
pos < (grub_uint16_t *) (label + 1);
pos++)
sum ^= *pos;
-
+
return ! sum;
}
struct grub_disk raw;
struct grub_sun_block block;
int partnum;
-
+
raw = *disk;
raw.partition = 0;
-
+
p = (grub_partition_t) grub_malloc (sizeof (struct grub_partition));
if (! p)
return grub_errno;
{
if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
-
+
if (! grub_sun_is_valid (&block))
grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
-
+
/* Maybe another error value would be better, because partition
table _is_ recognized but invalid. */
for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
{
struct grub_sun_partition_descriptor *desc;
-
+
if (block.infos[partnum].id == 0
|| block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
continue;
}
}
}
-
+
grub_free (p);
return grub_errno;
char *s = (char *) str;
auto int find_func (grub_disk_t d, const grub_partition_t partition);
-
+
int find_func (grub_disk_t d __attribute__ ((unused)),
const grub_partition_t partition)
{
p = (grub_partition_t) grub_malloc (sizeof (*p));
if (p)
grub_memcpy (p, partition, sizeof (*p));
-
+
return 1;
}
-
+
return 0;
}
grub_error (GRUB_ERR_BAD_FILENAME, "invalid partition");
p = 0;
}
-
+
return p;
}
sun_partition_map_get_name (const grub_partition_t p)
{
char *name;
-
+
name = grub_malloc (13);
if (name)
grub_sprintf (name, "%d", p->index + 1);
-
+
return name;
}
{0, 0, 0}
};
-static grub_err_t grub_pcpart_boot (const grub_device_t dev,
+static grub_err_t grub_pcpart_boot (const grub_device_t dev,
const struct grub_parttool_args *args)
{
int i, index;
{0, 0, 0}
};
-static grub_err_t grub_pcpart_type (const grub_device_t dev,
+static grub_err_t grub_pcpart_type (const grub_device_t dev,
const struct grub_parttool_args *args)
{
int index;
dev->disk->partition = 0;
/* Read the parttable. */
- if (grub_disk_read (dev->disk, part->offset, 0,
+ if (grub_disk_read (dev->disk, part->offset, 0,
sizeof (mbr), &mbr))
{
dev->disk->partition = part;
type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
}
- if (grub_pc_partition_is_empty (type)
+ if (grub_pc_partition_is_empty (type)
|| grub_pc_partition_is_extended (type))
{
dev->disk->partition = part;
grub_printf ("Setting partition type to 0x%x\n", type);
/* Write the parttable. */
- grub_disk_write (dev->disk, part->offset, 0,
+ grub_disk_write (dev->disk, part->offset, 0,
sizeof (mbr), &mbr);
dev->disk->partition = part;
GRUB_MOD_INIT (pcpart)
{
- activate_table_handle = grub_parttool_register ("pc_partition_map",
+ activate_table_handle = grub_parttool_register ("pc_partition_map",
grub_pcpart_boot,
grub_pcpart_bootargs);
- type_table_handle = grub_parttool_register ("pc_partition_map",
+ type_table_handle = grub_parttool_register ("pc_partition_map",
grub_pcpart_type,
grub_pcpart_typeargs);
-
+
}
GRUB_MOD_FINI(pcpart)
{
static grub_script_function_t grub_script_function_list;
grub_script_function_t
-grub_script_function_create (struct grub_script_arg *functionname_arg,
+grub_script_function_create (struct grub_script_arg *functionname_arg,
struct grub_script *cmd)
{
grub_script_function_t func;
for (;! state->done && (*state->script || firstrun); firstrun = 0)
{
-
+
if (! *state->script)
{
/* Check if more tokens are requested by the parser. */
}
newstate = grub_parser_cmdline_state (state->state, *state->script, &use);
-
+
/* Check if it is a text. */
if (check_textstate (newstate))
{
buffer = grub_script_malloc (parsestate, 2048);
if (! buffer)
return 0;
-
+
bp = buffer;
-
+
/* Read one token, possible quoted. */
while (*state->script)
{
newstate = grub_parser_cmdline_state (state->state,
*state->script, &use);
-
+
/* Check if a variable name starts. */
if (check_varstate (newstate))
break;
-
+
/* If the string is not quoted or escaped, stop processing
when a special token was found. It will be recognized
next time when this function is called. */
&& state->state != GRUB_PARSER_STATE_ESC)
{
int breakout = 0;
-
+
switch (use)
{
case ' ':
}
else if (use)
*(bp++) = use;
-
+
state->state = newstate;
nextchar (state);
}
grub_dprintf ("scripting", "token=`%s'\n", buffer);
yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
GRUB_SCRIPT_ARG_TYPE_STR, buffer);
-
+
}
else if (newstate == GRUB_PARSER_STATE_VAR
|| newstate == GRUB_PARSER_STATE_QVAR)
buffer = grub_script_malloc (parsestate, 2096);
if (! buffer)
return 0;
-
+
bp = buffer;
-
+
/* This is a variable, read the variable name. */
while (*state->script)
{
newstate = grub_parser_cmdline_state (state->state,
*state->script, &use);
-
+
/* Check if this character is not part of the variable name
anymore. */
if (! (check_varstate (newstate)))
state->state = newstate;
break;
}
-
+
if (use)
*(bp++) = use;
nextchar (state);
state->state = newstate;
}
-
+
*bp = '\0';
state->state = newstate;
yylval->arg = grub_script_arg_add (parsestate, yylval->arg,
GRUB_SCRIPT_ARG_TYPE_VAR, buffer);
- grub_dprintf ("scripting", "vartoken=`%s'\n", buffer);
+ grub_dprintf ("scripting", "vartoken=`%s'\n", buffer);
}
else
{
return 0;
}
}
-
+
if (yylval->arg == 0)
{
int token = state->tokenonhold;
{
grub_efi_char16_t str[2];
grub_efi_simple_text_output_interface_t *o;
-
+
o = grub_efi_system_table->con_out;
-
+
/* For now, do not try to use a surrogate pair. */
if (c > 0xffff)
c = '?';
/* Should this test be cached? */
if (c > 0x7f && efi_call_2 (o->test_string, o, str) != GRUB_EFI_SUCCESS)
return;
-
+
efi_call_2 (o->output_string, o, str);
}
grub_efi_simple_input_interface_t *i;
grub_efi_input_key_t key;
grub_efi_status_t status;
-
+
if (read_key >= 0)
return 1;
case GRUB_EFI_SUCCESS:
{
grub_uint16_t xy;
-
+
xy = grub_getxy ();
grub_gotoxy (0, 0);
grub_printf ("scan_code=%x,unicode_char=%x ",
break;
}
#endif
-
+
if (status == GRUB_EFI_SUCCESS)
{
switch (key.scan_code)
status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index);
if (status != GRUB_EFI_SUCCESS)
return -1;
-
+
grub_console_checkkey ();
}
while (read_key < 0);
-
+
key = read_key;
read_key = -1;
return key;
{
grub_efi_simple_text_output_interface_t *o;
grub_efi_uintn_t columns, rows;
-
+
o = grub_efi_system_table->con_out;
if (efi_call_4 (o->query_mode, o, o->mode->mode, &columns, &rows) != GRUB_EFI_SUCCESS)
{
grub_console_getxy (void)
{
grub_efi_simple_text_output_interface_t *o;
-
+
o = grub_efi_system_table->con_out;
return ((o->mode->cursor_column << 8) | o->mode->cursor_row);
}
grub_console_gotoxy (grub_uint8_t x, grub_uint8_t y)
{
grub_efi_simple_text_output_interface_t *o;
-
+
o = grub_efi_system_table->con_out;
efi_call_3 (o->set_cursor_position, o, x, y);
}
{
grub_efi_simple_text_output_interface_t *o;
grub_efi_int32_t orig_attr;
-
+
o = grub_efi_system_table->con_out;
orig_attr = o->mode->attribute;
efi_call_2 (o->set_attributes, o, GRUB_EFI_BACKGROUND_BLACK);
grub_uint8_t normal_color_setting;
grub_uint8_t highlight_color_setting;
grub_uint8_t term_color;
-
+
/* Color settings. */
grub_video_color_t fg_color;
grub_video_color_t bg_color;
static int dirty_region_is_empty (void);
-static void dirty_region_add (int x, int y,
+static void dirty_region_add (int x, int y,
unsigned int width, unsigned int height);
static unsigned int calculate_normal_character_width (grub_font_t font);
/* Map terminal color to text layer compatible video colors. */
virtual_screen.fg_color = grub_video_map_color(term_color & 0x0f);
-
+
/* Special case: use black as transparent color. */
if (((term_color >> 4) & 0x0f) == 0)
{
virtual_screen.bg_color = grub_video_map_rgba(0, 0, 0, 0);
- }
+ }
else
{
virtual_screen.bg_color = grub_video_map_color((term_color >> 4) & 0x0f);
virtual_screen.standard_color_setting = DEFAULT_STANDARD_COLOR;
virtual_screen.normal_color_setting = DEFAULT_NORMAL_COLOR;
virtual_screen.highlight_color_setting = DEFAULT_HIGHLIGHT_COLOR;
-
+
virtual_screen.term_color = virtual_screen.normal_color_setting;
-
+
set_term_color (virtual_screen.term_color);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
err = grub_video_set_mode (DEFAULT_VIDEO_MODE, video_hook);
else
{
- tmp = grub_malloc (grub_strlen (modevar)
+ tmp = grub_malloc (grub_strlen (modevar)
+ sizeof (DEFAULT_VIDEO_MODE) + 1);
grub_sprintf (tmp, "%s;" DEFAULT_VIDEO_MODE, modevar);
err = grub_video_set_mode (tmp, video_hook);
}
static void
-redraw_screen_rect (unsigned int x, unsigned int y,
+redraw_screen_rect (unsigned int x, unsigned int y,
unsigned int width, unsigned int height)
{
grub_video_color_t color;
if (bitmap)
{
/* Render bitmap as background. */
- grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y,
+ grub_video_blit_bitmap (bitmap, GRUB_VIDEO_BLIT_REPLACE, x, y,
x, y,
width, height);
-
- /* If bitmap is smaller than requested blit area, use background
+
+ /* If bitmap is smaller than requested blit area, use background
color. */
color = virtual_screen.bg_color;
{
h = bitmap_height - y;
}
-
+
if (bitmap_width > tx)
{
tx = bitmap_width;
}
-
+
/* Render background layer. */
grub_video_fill_rect (color, tx, y, w, h);
}
-
+
/* Fill bottom side of the bitmap if needed. */
if (y + height >= bitmap_height)
{
int h = (y + height) - bitmap_height;
unsigned int ty = y;
-
+
if (bitmap_height > ty)
{
ty = bitmap_height;
}
-
+
/* Render background layer. */
grub_video_fill_rect (color, x, ty, width, h);
}
dirty_region.top_left_y = y;
dirty_region.bottom_right_x = x + width - 1;
dirty_region.bottom_right_y = y + height - 1;
- }
+ }
else
{
if (x < dirty_region.top_left_x)
if ((y + (int)height - 1) > dirty_region.bottom_right_y)
dirty_region.bottom_right_y = y + height - 1;
}
-}
+}
static void
dirty_region_add_virtualscreen (void)
/* Get glyph for character. */
glyph = grub_font_get_glyph (virtual_screen.font, p->code);
ascent = grub_font_get_ascent (virtual_screen.font);
-
+
width = virtual_screen.normal_char_width * calculate_character_width(glyph);
height = virtual_screen.normal_char_height;
-
+
color = p->fg_color;
bgcolor = p->bg_color;
/* Redraw only changed regions. */
dirty_region_redraw ();
}
-
+
/* Scroll text buffer with one line to up. */
grub_memmove (virtual_screen.text_buffer,
virtual_screen.text_buffer + virtual_screen.columns,
color = virtual_screen.bg_color;
grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
-
+
/* If we have bitmap, re-draw screen, otherwise scroll physical screen too. */
if (bitmap)
{
dirty_region_add_virtualscreen ();
}
else
- {
+ {
/* Clear new border area. */
grub_video_fill_rect (color,
virtual_screen.offset_x, virtual_screen.offset_y,
case GRUB_TERM_COLOR_STANDARD:
virtual_screen.term_color = virtual_screen.standard_color_setting;
break;
-
+
case GRUB_TERM_COLOR_NORMAL:
virtual_screen.term_color = virtual_screen.normal_color_setting;
break;
-
+
case GRUB_TERM_COLOR_HIGHLIGHT:
virtual_screen.term_color = virtual_screen.highlight_color_setting;
break;
-
+
default:
break;
}
/* Check that we have video adapter active. */
if (grub_video_get_info(NULL) != GRUB_ERR_NONE)
return grub_errno;
-
+
/* Destroy existing background bitmap if loaded. */
if (bitmap)
{
grub_video_bitmap_destroy (bitmap);
bitmap = 0;
-
+
/* Mark whole screen as dirty. */
dirty_region_reset ();
dirty_region_add (0, 0, mode_info.width, mode_info.height);
if (argc >= 1)
{
/* Try to load new one. */
- grub_video_bitmap_load (&bitmap, args[0]);
+ grub_video_bitmap_load (&bitmap, args[0]);
if (grub_errno != GRUB_ERR_NONE)
return grub_errno;
/* Determine bitmap dimensions. */
bitmap_width = grub_video_bitmap_get_width (bitmap);
bitmap_height = grub_video_bitmap_get_width (bitmap);
-
+
/* Mark whole screen as dirty. */
dirty_region_reset ();
dirty_region_add (0, 0, mode_info.width, mode_info.height);
}
}
-
+
/* All was ok. */
grub_errno = GRUB_ERR_NONE;
return grub_errno;
{'H', 1},
{'4', 4}
};
-
+
static struct
{
short key;
if (npending >= 3)
{
unsigned int i;
-
+
for (i = 0;
i < sizeof (three_code_table) / sizeof (three_code_table[0]);
i++)
{
unsigned int i;
short key = *((short *) (input_buf + 2));
-
+
for (i = 0;
i < sizeof (four_code_table) / sizeof (four_code_table[0]);
i++)
for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
{
int c;
-
+
c = serial_hw_fetch ();
if (c >= 0)
{
input_buf[npending++] = c;
-
+
/* Reset the counter to zero, to wait for the same interval. */
i = 0;
}
-
+
if (nowait)
break;
}
case GRUB_TERM_DISP_LEFT:
c = '<';
break;
-
+
case GRUB_TERM_DISP_UP:
c = '^';
break;
-
+
case GRUB_TERM_DISP_RIGHT:
c = '>';
break;
-
+
case GRUB_TERM_DISP_DOWN:
c = 'v';
break;
-
+
case GRUB_TERM_DISP_HLINE:
c = '-';
break;
-
+
case GRUB_TERM_DISP_VLINE:
c = '|';
break;
-
+
case GRUB_TERM_DISP_UL:
case GRUB_TERM_DISP_UR:
case GRUB_TERM_DISP_LL:
case GRUB_TERM_DISP_LR:
c = '+';
break;
-
+
default:
c = '?';
break;
}
}
-
+
switch (c)
{
case '\a':
break;
-
+
case '\b':
case 127:
if (xpos > 0)
xpos--;
break;
-
+
case '\n':
if (ypos < TEXT_HEIGHT)
ypos++;
break;
-
+
case '\r':
xpos = 0;
break;
-
+
default:
if (xpos >= TEXT_WIDTH)
{
break;
}
}
-
+
serial_hw_put (c);
}
keep_track = 0;
grub_terminfo_gotoxy (x, y);
keep_track = 1;
-
+
xpos = x;
ypos = y;
}
if (!serial_settings.port)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad unit number.");
}
-
+
if (state[1].set)
serial_settings.port = (unsigned short) grub_strtoul (state[1].arg, 0, 0);
-
+
if (state[2].set)
{
unsigned long speed;
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad speed");
}
}
-
+
if (state[3].set)
{
if (! grub_strcmp (state[3].arg, "5"))
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad word length");
}
}
-
+
if (state[4].set)
{
if (! grub_strcmp (state[4].arg, "no"))
return grub_error (GRUB_ERR_BAD_ARGUMENT, "bad parity");
}
}
-
+
if (state[5].set)
{
if (! grub_strcmp (state[5].arg, "1"))
/* Initialize with new settings. */
hwiniterr = serial_hw_init ();
-
+
if (hwiniterr == GRUB_ERR_NONE)
{
/* Register terminal if not yet registered. */
}
}
}
-
+
return hwiniterr;
}
grub_virtual_screen_invalidate_char (struct grub_colored_char *p)
{
p->code = 0xFFFF;
-
+
if (p->width)
{
struct grub_colored_char *q;
if (virtual_screen.cursor_x > 0)
virtual_screen.cursor_x--;
break;
-
+
case '\n':
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
scroll_up ();
else
virtual_screen.cursor_y++;
break;
-
+
case '\r':
virtual_screen.cursor_x = 0;
break;
{
unsigned width;
struct grub_colored_char *p;
-
+
grub_virtual_screen_get_glyph (c, 0, &width);
if (virtual_screen.cursor_x + width > virtual_screen.columns)
p[i].index = i;
}
}
-
+
write_char ();
-
+
virtual_screen.cursor_x += width;
if (virtual_screen.cursor_x >= virtual_screen.columns)
{
virtual_screen.cursor_x = 0;
-
+
if (virtual_screen.cursor_y >= virtual_screen.rows - 1)
scroll_up ();
else
grub_vesafb_getcharwidth (grub_uint32_t c)
{
unsigned width;
-
+
if (! grub_virtual_screen_get_glyph (c, 0, &width))
return 0;
grub_virtual_screen_cls ();
grub_memset (framebuffer,
- 0,
+ 0,
mode_info.y_resolution * bytes_per_scan_line);
}
{
unsigned char old_addr;
unsigned char old_data;
-
+
old_addr = grub_inb (SEQUENCER_ADDR_PORT);
grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
-
+
old_data = grub_inb (SEQUENCER_DATA_PORT);
-
+
grub_outb (old_addr, SEQUENCER_ADDR_PORT);
return old_data;
set_map_mask (unsigned char mask)
{
unsigned char old_addr;
-
+
old_addr = grub_inb (SEQUENCER_ADDR_PORT);
grub_outb (MAP_MASK_REGISTER, SEQUENCER_ADDR_PORT);
-
+
grub_outb (mask, SEQUENCER_DATA_PORT);
-
+
grub_outb (old_addr, SEQUENCER_ADDR_PORT);
}
set_read_map (unsigned char map)
{
unsigned char old_addr;
-
+
old_addr = grub_inb (GRAPHICS_ADDR_PORT);
grub_outb (READ_MAP_REGISTER, GRAPHICS_ADDR_PORT);
set_start_address (unsigned int start)
{
unsigned char old_addr;
-
+
old_addr = grub_inb (CRTC_ADDR_PORT);
-
+
grub_outb (START_ADDR_LOW_REGISTER, CRTC_ADDR_PORT);
grub_outb (start & 0xFF, CRTC_DATA_PORT);
-
+
grub_outb (START_ADDR_HIGH_REGISTER, CRTC_ADDR_PORT);
grub_outb (start >> 8, CRTC_DATA_PORT);
font = grub_font_get (""); /* Choose any font, for now. */
if (!font)
return grub_error (GRUB_ERR_BAD_FONT, "No font loaded.");
-
+
return GRUB_ERR_NONE;
}
unsigned char *mem_base;
unsigned plane;
- mem_base = (VGA_MEM + xpos +
+ mem_base = (VGA_MEM + xpos +
ypos * CHAR_HEIGHT * TEXT_WIDTH + PAGE_OFFSET (page)) - p->index;
p -= p->index;
/* Get glyph for character. */
glyph = grub_font_get_glyph (font, p->code);
-
+
for (plane = 0x01; plane <= 0x08; plane <<= 1)
{
unsigned y;
for (i = 0; i < char_width && offset < 32; i++)
{
unsigned char fg_mask, bg_mask;
-
+
fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0;
bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0;
offset++;
if (check_vga_mem (mem + i))
mem[i] = (fg_mask | bg_mask);
}
-#endif /* 0 */
+#endif /* 0 */
}
}
+ (ypos * CHAR_HEIGHT + CHAR_HEIGHT - 3) * TEXT_WIDTH);
if (check_vga_mem (mem))
*mem = 0xff;
-
+
mem += TEXT_WIDTH;
if (check_vga_mem (mem))
*mem = 0xff;
{
unsigned i;
unsigned plane;
-
+
/* Do all the work in the other page. */
grub_memmove (text_buf, text_buf + TEXT_WIDTH,
sizeof (struct colored_char) * TEXT_WIDTH * (TEXT_HEIGHT - 1));
-
+
for (i = TEXT_WIDTH * (TEXT_HEIGHT - 1); i < TEXT_WIDTH * TEXT_HEIGHT; i++)
{
text_buf[i].code = ' ';
grub_memset (VGA_MEM + PAGE_OFFSET (1 - page)
+ VGA_WIDTH * (VGA_HEIGHT - CHAR_HEIGHT) / 8, 0,
VGA_WIDTH * CHAR_HEIGHT / 8);
-
+
/* Activate the other page. */
page = 1 - page;
wait_vretrace ();
#if DEBUG_VGA
static int show = 1;
#endif
-
+
if (c == '\a')
/* FIXME */
return;
/* Erase current cursor, if any. */
if (cursor_state)
write_char ();
-
+
switch (c)
{
case '\b':
if (xpos > 0)
xpos--;
break;
-
+
case '\n':
if (ypos >= TEXT_HEIGHT - 1)
scroll_up ();
else
ypos++;
break;
-
+
case '\r':
xpos = 0;
break;
struct grub_font_glyph *glyph;
struct colored_char *p;
unsigned char_width = 1;
-
+
glyph = grub_font_get_glyph(font, c);
if (xpos + char_width > TEXT_WIDTH)
p[i].index = i;
}
}
-
+
write_char ();
-
+
xpos += char_width;
if (xpos >= TEXT_WIDTH)
{
xpos = 0;
-
+
if (ypos >= TEXT_HEIGHT - 1)
scroll_up ();
else
{
#if 0
struct grub_font_glyph glyph;
-
+
glyph = grub_font_get_glyph (c);
-
+
return glyph.char_width;
#else
(void) c; /* Prevent warning. */
char chr = *(str++);
grub_ieee1275_write (stdout_ihandle, &chr, 1, 0);
}
-
+
}
static void
*key = '\e';
return 1;
}
-
+
if (c != 91)
return 0;
-
+
grub_ieee1275_read (stdin_ihandle, &c, 1, &actual);
if (actual <= 0)
return 0;
-
+
switch (c)
{
case 65:
/* Up: Ctrl-p. */
- c = 16;
+ c = 16;
break;
case 66:
/* Down: Ctrl-n. */
break;
}
}
-
+
*key = c;
return actual > 0;
}
{
int key;
int read;
-
+
if (grub_buflen)
return 1;
grub_buflen = 1;
return 1;
}
-
+
return -1;
}
}
while (! grub_ofconsole_readkey (&key));
-
+
return key;
}
grub_terminfo_free (&term.reverse_video_off);
grub_terminfo_free (&term.cursor_on);
grub_terminfo_free (&term.cursor_off);
-
+
if (grub_strcmp ("vt100", str) == 0)
{
term.name = grub_strdup ("vt100");
term.cursor_off = grub_strdup ("\e[?25l");
return grub_errno;
}
-
+
return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown terminfo type.");
}
int usb_iterate (grub_usb_device_t dev)
{
descdev = &dev->descdev;
-
+
grub_dprintf ("usb_keyboard", "%x %x %x\n",
descdev->class, descdev->subclass, descdev->protocol);
c = '?';
break;
}
-
+
addch (c | grub_console_attr);
}
static void
grub_ncurses_setcolorstate (grub_term_color_state state)
{
- switch (state)
+ switch (state)
{
case GRUB_TERM_COLOR_STANDARD:
grub_console_cur_color = grub_console_standard_color;
grub_ncurses_checkkey (void)
{
int c;
-
+
/* Check for SAVED_CHAR. This should not be true, because this
means checkkey is called twice continuously. */
if (saved_char != ERR)
return saved_char;
-
+
wtimeout (stdscr, 100);
c = getch ();
/* If C is not ERR, then put it back in the input queue. */
grub_ncurses_getkey (void)
{
int c;
-
+
/* If checkkey has already got a character, then return it. */
if (saved_char != ERR)
{
case KEY_RIGHT:
c = 6;
break;
-
+
case KEY_UP:
c = 16;
break;
case KEY_BACKSPACE:
/* XXX: For some reason ncurses on xterm does not return
KEY_BACKSPACE. */
- case 127:
+ case 127:
c = 8;
break;
p[0] = '\0';
break;
}
-
+
p++;
}
}
char *abs_dir, *prev_dir;
char *prefix;
struct stat st, prev_st;
-
+
/* Save the current directory. */
saved_cwd = xgetcwd ();
abs_dir = xgetcwd ();
strip_extra_slashes (abs_dir);
prev_dir = xstrdup (abs_dir);
-
+
if (stat (".", &prev_st) < 0)
grub_util_error ("Cannot stat `%s'", dir);
DIR *dp;
char *saved_cwd;
struct dirent *ent;
-
+
dp = opendir (dir);
if (! dp)
return 0;
closedir (dp);
return 0;
}
-
+
while ((ent = readdir (dp)) != 0)
{
struct stat st;
-
+
/* Avoid:
- dotfiles (like "/dev/.tmp.md0") since they could be duplicates.
- dotdirs (like "/dev/.static") since they could contain duplicates. */
if (S_ISLNK (st.st_mode))
/* Don't follow symbolic links. */
continue;
-
+
if (S_ISDIR (st.st_mode))
{
/* Find it recursively. */
{
if (chdir (saved_cwd) < 0)
grub_util_error ("Cannot restore the original directory");
-
+
free (saved_cwd);
closedir (dp);
return res;
{
struct stat st;
char *os_dev;
-
+
if (stat (dir, &st) < 0)
grub_util_error ("Cannot stat `%s'", dir);
offset++;
}
}
-
+
break;
case GRUB_DEV_ABSTRACTION_RAID:
}
else
grub_util_error ("Unknown kind of RAID device `%s'", os_dev);
-
+
break;
default: /* GRUB_DEV_ABSTRACTION_NONE */
{
FILE *fp;
char *buf;
-
+
buf = malloc (DEFAULT_ENVBLK_SIZE);
if (! buf)
grub_util_error ("out of memory");
memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#',
DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
-
+
if (fwrite (buf, 1, DEFAULT_ENVBLK_SIZE, fp) != DEFAULT_ENVBLK_SIZE)
grub_util_error ("cannot write to the file %s", name);
char *buf;
size_t size;
grub_envblk_t envblk;
-
+
fp = fopen (name, "rb");
if (! fp)
{
buf = malloc (size);
if (! buf)
grub_util_error ("out of memory");
-
+
if (fread (buf, 1, size, fp) != size)
grub_util_error ("cannot read the file %s", name);
fclose (fp);
-
+
envblk = grub_envblk_open (buf, size);
if (! envblk)
grub_util_error ("invalid environment block");
list_variables (const char *name)
{
grub_envblk_t envblk;
-
+
auto int print_var (const char *name, const char *value);
int print_var (const char *name, const char *value)
{
write_envblk (const char *name, grub_envblk_t envblk)
{
FILE *fp;
-
+
fp = fopen (name, "wb");
if (! fp)
grub_util_error ("cannot open the file %s", name);
-
+
if (fwrite (grub_envblk_buffer (envblk), 1, grub_envblk_size (envblk), fp)
!= grub_envblk_size (envblk))
grub_util_error ("cannot write to the file %s", name);
set_variables (const char *name, int argc, char *argv[])
{
grub_envblk_t envblk;
-
+
envblk = open_envblk_file (name);
while (argc)
{
unset_variables (const char *name, int argc, char *argv[])
{
grub_envblk_t envblk;
-
+
envblk = open_envblk_file (name);
while (argc)
{
{
char *filename;
char *command;
-
+
progname = "grub-editenv";
-
+
/* Check for options. */
while (1)
{
fprintf (stderr, "no command specified\n");
usage (1);
}
-
+
filename = argv[optind];
command = argv[optind + 1];
{ 0, 0, 0, 0 }
};
-static int
+static int
usage (int status)
{
if (status)
char *dev_map = DEFAULT_DEVICE_MAP;
volatile int hold = 0;
int opt;
-
+
progname = "grub-emu";
while ((opt = getopt_long (argc, argv, "r:d:m:vH:hV", options, 0)) != -1)
sleep (1);
}
-
+
signal (SIGINT, SIG_IGN);
grub_console_init ();
prefix = xmalloc (strlen (root_dev) + 2 + strlen (dir) + 1);
sprintf (prefix, "(%s)%s", root_dev, dir);
free (dir);
-
+
/* Start GRUB! */
if (setjmp (main_env) == 0)
grub_main ();
grub_fini_all ();
grub_machine_fini ();
-
+
return 0;
}
#include <stdlib.h>
/* XXX: this file assumes particular Mach-O layout and does no checks. */
-/* However as build system ensures correct usage of this tool this
+/* However as build system ensures correct usage of this tool this
shouldn't be a problem. */
int
fclose (out);
printf ("Couldn't allocate buffer\n");
return 3;
- }
+ }
fread (buf, 1, bufsize, in);
head = (struct grub_macho_header32 *) buf;
if (grub_le_to_cpu32 (head->magic) != GRUB_MACHO_MAGIC32)
free (buf);
printf ("Invalid Mach-O fle\n");
return 4;
- }
+ }
curcmd = (struct grub_macho_segment32 *) (buf + sizeof (*head));
- for (i = 0; i < grub_le_to_cpu32 (head->ncmds); i++,
- curcmd = (struct grub_macho_segment32 *)
+ for (i = 0; i < grub_le_to_cpu32 (head->ncmds); i++,
+ curcmd = (struct grub_macho_segment32 *)
(((char *) curcmd) + curcmd->cmdsize))
{
if (curcmd->cmd != GRUB_MACHO_CMD_SEGMENT32)
continue;
- fwrite (buf + grub_le_to_cpu32 (curcmd->fileoff), 1,
+ fwrite (buf + grub_le_to_cpu32 (curcmd->fileoff), 1,
grub_le_to_cpu32 (curcmd->filesize), out);
- if (grub_le_to_cpu32 (curcmd->vmsize)
+ if (grub_le_to_cpu32 (curcmd->vmsize)
> grub_le_to_cpu32 (curcmd->filesize))
{
- bssstart = grub_le_to_cpu32 (curcmd->vmaddr)
+ bssstart = grub_le_to_cpu32 (curcmd->vmaddr)
+ grub_le_to_cpu32 (curcmd->filesize) ;
- bssend = grub_le_to_cpu32 (curcmd->vmaddr)
+ bssend = grub_le_to_cpu32 (curcmd->vmaddr)
+ grub_le_to_cpu32 (curcmd->vmsize) ;
}
}
;;
--output=)
grub_cfg=`echo "$option" | sed 's/--output=//'`
- ;;
+ ;;
-*)
echo "Unrecognized option \`$option'" 1>&2
usage
fp = stdout;
else
fp = fopen (device_map, "w");
-
+
if (! fp)
grub_util_error ("cannot open %s", device_map);
Report bugs to <%s>.\n\
",
DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
-
+
exit (status);
}
{
char *dev_map = 0;
int floppy_disks = 1;
-
+
progname = "grub-mkdevicemap";
-
+
/* Check for options. */
while (1)
{
int c = getopt_long (argc, argv, "snm:r:hVv", options, 0);
-
+
if (c == -1)
break;
else
case 's':
floppy_disks = 2;
break;
-
+
case 'h':
usage (0);
break;
make_device_map (dev_map ? : DEFAULT_DEVICE_MAP, floppy_disks);
free (dev_map);
-
+
return 0;
}
{
char *name;
char *underscore;
-
+
if (disk->partition == NULL)
{
grub_util_info ("No partition map found for %s", disk->name);
return;
}
-
+
name = strdup (disk->partition->partmap->name);
if (! name)
grub_util_error ("Not enough memory");
-
+
underscore = strchr (name, '_');
if (! underscore)
grub_util_error ("Invalid partition map %s", name);
-
+
*underscore = '\0';
printf ("%s\n", name);
free (name);
int abstraction_type;
grub_device_t dev = NULL;
grub_fs_t fs;
-
+
if (path == NULL)
{
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
abstraction_type = grub_util_get_dev_abstraction (device_name);
/* No need to check for errors; lack of abstraction is permissible. */
-
+
if (print == PRINT_ABSTRACTION)
{
char *abstraction_name;
drive_name = grub_util_get_grub_dev (device_name);
if (! drive_name)
grub_util_error ("Cannot find a GRUB drive for %s. Check your device.map.\n", device_name);
-
+
if (print == PRINT_DRIVE)
{
printf ("(%s)\n", drive_name);
grub_file_t file;
grub_util_info ("reading %s via OS facilities", path);
filebuf_via_sys = grub_util_read_image (path);
-
+
grub_util_info ("reading %s via GRUB facilities", path);
asprintf (&grub_path, "(%s)%s", drive_name, path);
file = grub_file_open (grub_path);
filebuf_via_grub = xmalloc (file->size);
grub_file_read (file, filebuf_via_grub, file->size);
-
+
grub_util_info ("comparing");
-
+
if (memcmp (filebuf_via_grub, filebuf_via_sys, file->size))
grub_util_error ("files differ");
}
Report bugs to <%s>.\n\
",
DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
-
+
exit (status);
}
{
char *dev_map = 0;
char *argument;
-
+
progname = "grub-probe";
-
+
/* Check for options. */
while (1)
{
int c = getopt_long (argc, argv, "dm:t:hVv", options, 0);
-
+
if (c == -1)
break;
else
}
argument = argv[optind];
-
+
/* Initialize the emulated biosdisk driver. */
grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
-
+
/* Initialize all modules. */
grub_init_all ();
probe (NULL, argument);
else
probe (argument, NULL);
-
+
/* Free resources. */
grub_fini_all ();
grub_util_biosdisk_fini ();
-
+
free (dev_map);
-
+
return 0;
}
esac
for i in /hurd/${hurd_fs}.static /hurd/exec ; do
- if test -e "$i" ; then
+ if test -e "$i" ; then
echo "Found Hurd module: $i" >&2
at_least_one=true
else
;;
linux)
LINUXPROBED="`linux-boot-prober ${DEVICE} 2> /dev/null | tr ' ' '^' | paste -s -d ' '`"
-
+
for LINUX in ${LINUXPROBED} ; do
LROOT="`echo ${LINUX} | cut -d ':' -f 1`"
LBOOT="`echo ${LINUX} | cut -d ':' -f 2`"
{
int drive;
struct stat st;
-
+
drive = find_grub_drive (name);
if (drive < 0)
return grub_error (GRUB_ERR_BAD_DEVICE,
"no mapping exists for `%s'", name);
-
+
disk->has_partitions = 1;
disk->id = drive;
close (fd);
goto fail;
}
-
+
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
# else
if (nr % 512)
grub_util_error ("unaligned device size");
-
+
grub_util_info ("the size of %s is %llu", name, disk->total_sectors);
-
+
return GRUB_ERR_NONE;
}
return grub_error (GRUB_ERR_BAD_DEVICE, "cannot stat `%s'", map[drive].device);
disk->total_sectors = st.st_size >> GRUB_DISK_SECTOR_BITS;
-
+
grub_util_info ("the size of %s is %lu", name, disk->total_sectors);
-
+
return GRUB_ERR_NONE;
}
#ifdef O_BINARY
flags |= O_BINARY;
#endif
-
+
#ifdef __linux__
/* Linux has a bug that the disk cache for a whole disk is not consistent
with the one for a partition of the disk. */
{
int is_partition = 0;
char dev[PATH_MAX];
-
+
strcpy (dev, map[disk->id].device);
if (disk->partition && strncmp (map[disk->id].device, "/dev/", 5) == 0)
is_partition = linux_find_partition (dev, disk->partition->start);
-
+
/* Open the partition. */
grub_dprintf ("hostdisk", "opening the device `%s' in open_device()", dev);
fd = open (dev, flags);
return fd;
}
-
+
/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
error occurs, otherwise return LEN. */
static ssize_t
nread (int fd, char *buf, size_t len)
{
ssize_t size = len;
-
+
while (len)
{
ssize_t ret = read (fd, buf, len);
-
+
if (ret <= 0)
{
if (errno == EINTR)
else
return ret;
}
-
+
len -= ret;
buf += ret;
}
-
+
return size;
}
nwrite (int fd, const char *buf, size_t len)
{
ssize_t size = len;
-
+
while (len)
{
ssize_t ret = write (fd, buf, len);
-
+
if (ret <= 0)
{
if (errno == EINTR)
else
return ret;
}
-
+
len -= ret;
buf += ret;
}
-
+
return size;
}
fd = open_device (disk, sector, O_RDONLY);
if (fd < 0)
return grub_errno;
-
+
#ifdef __linux__
if (sector == 0 && size > 1)
{
/* Work around a bug in Linux ez remapping. Linux remaps all
sectors that are read together with the MBR in one read. It
- should only remap the MBR, so we split the read in two
+ should only remap the MBR, so we split the read in two
parts. -jochen */
if (nread (fd, buf, GRUB_DISK_SECTOR_SIZE) != GRUB_DISK_SECTOR_SIZE)
{
close (fd);
return grub_errno;
}
-
+
buf += GRUB_DISK_SECTOR_SIZE;
size--;
}
#endif /* __linux__ */
-
+
if (nread (fd, buf, size << GRUB_DISK_SECTOR_BITS)
!= (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
grub_error (GRUB_ERR_READ_ERROR, "cannot read from `%s'", map[disk->id].device);
fd = open_device (disk, sector, O_WRONLY);
if (fd < 0)
return grub_errno;
-
+
if (nwrite (fd, buf, size << GRUB_DISK_SECTOR_BITS)
!= (ssize_t) (size << GRUB_DISK_SECTOR_BITS))
grub_error (GRUB_ERR_WRITE_ERROR, "cannot write to `%s'", map[disk->id].device);
{
grub_util_error ("%s:%d: %s", dev_map, lineno, msg);
}
-
+
fp = fopen (dev_map, "r");
if (! fp)
grub_util_error ("Cannot open `%s'", dev_map);
char *p = buf;
char *e;
int drive;
-
+
lineno++;
-
+
/* Skip leading spaces. */
while (*p && isspace (*p))
p++;
grub_util_biosdisk_fini (void)
{
unsigned i;
-
+
for (i = 0; i < sizeof (map) / sizeof (map[0]); i++)
{
if (map[i].drive)
free (map[i].device);
map[i].drive = map[i].device = NULL;
}
-
+
grub_disk_dev_unregister (&grub_util_biosdisk_dev);
}
*/
p = xmalloc (len + 2);
sprintf (p, "%s", map[drive].drive);
-
+
if (dos_part >= 0)
sprintf (p + strlen (p), ",%d", dos_part + 1);
-
+
if (bsd_part >= 0)
sprintf (p + strlen (p), ",%c", bsd_part + 'a');
-
+
return p;
}
char *path = xmalloc (PATH_MAX);
if (! realpath (os_dev, path))
return 0;
-
+
if (strncmp ("/dev/", path, 5) == 0)
{
char *p = path + 5;
p = strstr (p, "part");
if (p)
strcpy (p, "disc");
-
+
return path;
}
-
+
/* If this is a SCSI disk. */
if (strncmp ("scsi/", p, 5) == 0)
{
p = strstr (p, "part");
if (p)
strcpy (p, "disc");
-
+
return path;
}
-
+
/* If this is a DAC960 disk. */
if (strncmp ("rd/c", p, 4) == 0)
{
return path;
}
-
+
/* If this is a CCISS disk. */
if (strncmp ("cciss/c", p, sizeof ("cciss/c") - 1) == 0)
{
return path;
}
-
+
/* If this is a Compaq Intelligent Drive Array. */
if (strncmp ("ida/c", p, sizeof ("ida/c") - 1) == 0)
{
return path;
}
-
+
/* If this is an I2O disk. */
if (strncmp ("i2o/hd", p, sizeof ("i2o/hd") - 1) == 0)
{
p[sizeof ("i2o/hda") - 1] = '\0';
return path;
}
-
+
/* If this is a MultiMediaCard (MMC). */
if (strncmp ("mmcblk", p, sizeof ("mmcblk") - 1) == 0)
{
return path;
}
-
+
/* If this is an IDE, SCSI or Virtio disk. */
if (strncmp ("vdisk", p, 5) == 0
&& p[5] >= 'a' && p[5] <= 'z')
}
return path;
-
+
#elif defined(__GNU__)
char *path = xstrdup (os_dev);
if (strncmp ("/dev/sd", path, 7) == 0 || strncmp ("/dev/hd", path, 7) == 0)
os_disk = convert_system_partition_to_system_disk (os_dev);
if (! os_disk)
return -1;
-
+
for (i = 0; i < (int) (sizeof (map) / sizeof (map[0])); i++)
if (map[i].device && strcmp (map[i].device, os_disk) == 0)
{
return 0;
}
- if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev))
+ if (grub_strcmp (os_dev, convert_system_partition_to_system_disk (os_dev))
== 0)
return make_device_name (drive, -1, -1);
-
+
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (! S_ISCHR (st.st_mode))
#else
if (! S_ISBLK (st.st_mode))
#endif
return make_device_name (drive, -1, -1);
-
+
#if defined(__linux__) || defined(__CYGWIN__)
/* Linux counts partitions uniformly, whether a BSD partition or a DOS
partition, so mapping them to GRUB devices is not trivial.
int bsd_part = -1;
auto int find_partition (grub_disk_t disk,
const grub_partition_t partition);
-
+
int find_partition (grub_disk_t disk __attribute__ ((unused)),
const grub_partition_t partition)
{
if (strcmp (partition->partmap->name, "pc_partition_map") == 0)
pcdata = partition->data;
-
+
if (pcdata)
{
if (pcdata->bsd_part < 0)
grub_util_info ("Partition %d starts from %lu",
partition->index, partition->start);
}
-
+
if (hdg.start == partition->start)
{
if (pcdata)
}
return 1;
}
-
+
return 0;
}
-
+
name = make_device_name (drive, -1, -1);
-
+
if (MAJOR (st.st_rdev) == FLOPPY_MAJOR)
return name;
-
+
fd = open (os_dev, O_RDONLY);
if (fd == -1)
{
free (name);
return 0;
}
-
+
if (ioctl (fd, HDIO_GETGEO, &hdg))
{
grub_error (GRUB_ERR_BAD_DEVICE,
free (name);
return 0;
}
-
+
close (fd);
grub_util_info ("%s starts from %lu", os_dev, hdg.start);
-
+
if (hdg.start == 0 && device_is_wholedisk (os_dev))
return name;
grub_util_info ("opening the device %s", name);
disk = grub_disk_open (name);
free (name);
-
+
if (! disk)
return 0;
-
+
grub_partition_iterate (disk, find_partition);
if (grub_errno != GRUB_ERR_NONE)
{
grub_disk_close (disk);
return 0;
}
-
+
if (dos_part < 0)
{
grub_disk_close (disk);
"cannot find the partition of `%s'", os_dev);
return 0;
}
-
+
return make_device_name (drive, dos_part, bsd_part);
}
-
+
#elif defined(__GNU__)
/* GNU uses "/dev/[hs]d[0-9]+(s[0-9]+[a-z]?)?". */
{
char *p;
int dos_part = -1;
int bsd_part = -1;
-
+
p = strrchr (os_dev, 's');
if (p)
{
long int n;
char *q;
-
+
p++;
n = strtol (p, &q, 10);
if (p != q && n != GRUB_LONG_MIN && n != GRUB_LONG_MAX)
{
dos_part = (int) n;
-
+
if (*q >= 'a' && *q <= 'g')
bsd_part = *q - 'a';
}
}
-
+
return make_device_name (drive, dos_part, bsd_part);
}
-
+
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
/* FreeBSD uses "/dev/[a-z]+[0-9]+(s[0-9]+[a-z]?)?". */
{
int dos_part = -1;
int bsd_part = -1;
-
+
if (strncmp ("/dev/", os_dev, 5) == 0)
{
char *p, *q;
break;
}
}
-
+
return make_device_name (drive, dos_part, bsd_part);
}
#endif
static grub_err_t
-grub_hostfs_dir (grub_device_t device, const char *path,
- int (*hook) (const char *filename,
+grub_hostfs_dir (grub_device_t device, const char *path,
+ int (*hook) (const char *filename,
const struct grub_dirhook_info *info))
{
DIR *dir;
{
char *kernel_image;
char *kernel_path;
-
+
kernel_path = grub_util_get_path (dir, "kernel.mod");
*size = grub_util_get_image_size (kernel_path);
kernel_image = grub_util_read_image (kernel_path);
Elf_Addr current_address;
Elf_Addr *section_addresses;
Elf_Shdr *s;
-
+
section_addresses = xmalloc (sizeof (*section_addresses) * num_sections);
memset (section_addresses, 0, sizeof (*section_addresses) * num_sections);
{
Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
-
+
if (align)
current_address = align_address (current_address, align);
-
+
grub_util_info ("locating the section %s at 0x%x",
name, current_address);
section_addresses[i] = current_address;
{
Elf_Word align = grub_le_to_cpu32 (s->sh_addralign);
const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
-
+
if (align)
current_address = align_address (current_address, align);
-
+
grub_util_info ("locating the section %s at 0x%x",
name, current_address);
section_addresses[i] = current_address;
{
int i;
Elf_Shdr *s;
-
+
for (i = 0, s = sections;
i < num_sections;
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
{
Elf_Shdr *s;
char *strtab;
-
+
s = (Elf_Shdr *) ((char *) sections
+ grub_le_to_cpu16 (e->e_shstrndx) * section_entsize);
strtab = (char *) e + grub_le_to_cpu32 (s->sh_offset);
Elf_Word i;
Elf_Shdr *strtab_section;
const char *strtab;
-
+
strtab_section
= (Elf_Shdr *) ((char *) sections
+ (grub_le_to_cpu32 (symtab_section->sh_link)
* section_entsize));
strtab = (char *) e + grub_le_to_cpu32 (strtab_section->sh_offset);
-
+
symtab_size = grub_le_to_cpu32 (symtab_section->sh_size);
sym_size = grub_le_to_cpu32 (symtab_section->sh_entsize);
symtab_offset = grub_le_to_cpu32 (symtab_section->sh_offset);
{
Elf_Section index;
const char *name;
-
+
name = strtab + grub_le_to_cpu32 (sym->st_name);
-
+
index = grub_le_to_cpu16 (sym->st_shndx);
if (index == STN_ABS)
{
}
else if (index >= num_sections)
grub_util_error ("section %d does not exist", index);
-
+
sym->st_value = (grub_le_to_cpu32 (sym->st_value)
+ section_addresses[index]);
grub_util_info ("locating %s at 0x%x", name, sym->st_value);
get_symbol_address (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i)
{
Elf_Sym *sym;
-
+
sym = (Elf_Sym *) ((char *) e
+ grub_le_to_cpu32 (s->sh_offset)
+ i * grub_le_to_cpu32 (s->sh_entsize));
{
Elf_Half i;
Elf_Shdr *s;
-
+
for (i = 0, s = sections;
i < num_sections;
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
Elf_Addr sym_addr;
Elf_Addr *target;
Elf_Addr addend;
-
+
offset = grub_le_to_cpu (r->r_offset);
target = get_target_address (e, target_section, offset);
info = grub_le_to_cpu (r->r_info);
break;
case R_X86_64_64:
- *target = grub_cpu_to_le64 (grub_le_to_cpu64 (*target)
+ *target = grub_cpu_to_le64 (grub_le_to_cpu64 (*target)
+ addend + sym_addr);
grub_util_info ("relocating an R_X86_64_64 entry to 0x%llx at the offset 0x%llx",
*target, offset);
FILE *out)
{
struct grub_pe32_fixup_block *b = *block;
-
+
/* First, check if it is necessary to write out the current block. */
if (b)
{
Elf_Addr next_address;
unsigned padding_size;
size_t index;
-
+
next_address = current_address + b->block_size;
padding_size = ((align_pe32_section (next_address)
- next_address)
{
grub_uint16_t entry;
size_t index;
-
+
/* If not allocated yet, allocate a block with enough entries. */
if (! b)
{
make_header_space (FILE *out)
{
Elf_Addr addr;
-
+
addr = get_starting_section_address ();
write_padding (out, addr);
Elf_Half i;
Elf_Shdr *s;
Elf_Addr addr;
-
+
for (i = 0, s = sections;
i < num_sections;
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
Elf_Word size = grub_le_to_cpu32 (s->sh_size);
const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
-
+
if (align)
{
addr = align_address (current_address, align);
current_address = addr;
}
}
-
+
grub_util_info ("writing the text section %s at 0x%x",
name, current_address);
-
+
if (fwrite ((char *) e + offset, size, 1, out) != 1)
grub_util_error ("write failed");
-
+
current_address += size;
}
addr - current_address);
write_padding (out, addr - current_address);
}
-
+
return addr;
}
Elf_Half i;
Elf_Shdr *s;
Elf_Addr addr;
-
+
for (i = 0, s = sections;
i < num_sections;
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
Elf_Off offset = grub_le_to_cpu32 (s->sh_offset);
Elf_Word size = grub_le_to_cpu32 (s->sh_size);
const char *name = strtab + grub_le_to_cpu32 (s->sh_name);
-
+
if (align)
{
addr = align_address (current_address, align);
current_address = addr;
}
}
-
+
grub_util_info ("writing the data section %s at 0x%x",
name, current_address);
-
+
if (s->sh_type == grub_cpu_to_le32 (SHT_NOBITS))
write_padding (out, size);
else
if (fwrite ((char *) e + offset, size, 1, out) != 1)
grub_util_error ("write failed");
-
+
current_address += size;
}
-
+
addr = align_pe32_section (current_address);
if (addr != current_address)
{
addr - current_address);
write_padding (out, addr - current_address);
}
-
+
return addr;
}
memset (&modinfo, 0, sizeof (modinfo));
path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods);
-
+
total_module_size = sizeof (struct grub_module_info);
for (p = path_list; p; p = p->next)
{
struct grub_module_header header;
size_t mod_size;
char *mod_image;
-
+
memset (&header, 0, sizeof (header));
-
+
grub_util_info ("adding module %s", p->name);
-
+
mod_size = grub_util_get_image_size (p->name);
header.type = grub_cpu_to_le32 (OBJ_TYPE_ELF);
header.size = grub_cpu_to_le32 (mod_size + sizeof (header));
-
+
mod_image = grub_util_read_image (p->name);
if (fwrite (&header, sizeof (header), 1, out) != 1
free (mod_image);
}
-
+
for (p = path_list; p; )
{
struct grub_util_path_list *q;
free (p);
p = q;
}
-
+
current_address += total_module_size;
-
+
addr = align_pe32_section (current_address);
if (addr != current_address)
{
Elf_Half i;
Elf_Shdr *s;
struct grub_pe32_fixup_block *fixup_block = 0;
-
+
for (i = 0, s = sections;
i < num_sections;
i++, s = (Elf_Shdr *) ((char *) s + section_entsize))
Elf_Off rtab_offset;
Elf_Addr section_address;
Elf_Word j;
-
+
grub_util_info ("translating the relocation section %s",
strtab + grub_le_to_cpu32 (s->sh_name));
-
+
rtab_size = grub_le_to_cpu32 (s->sh_size);
r_size = grub_le_to_cpu32 (s->sh_entsize);
rtab_offset = grub_le_to_cpu32 (s->sh_offset);
num_rs = rtab_size / r_size;
-
+
section_address = section_addresses[grub_le_to_cpu32 (s->sh_info)];
for (j = 0, r = (Elf_Rel *) ((char *) e + rtab_offset);
o->image_size = grub_cpu_to_le32 (end_address);
o->header_size = grub_cpu_to_le32 (text_address);
o->subsystem = grub_cpu_to_le16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION);
-
+
/* Do these really matter? */
o->stack_reserve_size = grub_cpu_to_le32 (0x10000);
o->stack_commit_size = grub_cpu_to_le32 (0x10000);
o->heap_commit_size = grub_cpu_to_le32 (0x10000);
o->num_data_directories = grub_cpu_to_le32 (GRUB_PE32_NUM_DATA_DIRECTORIES);
-
+
o->base_relocation_table.rva = grub_cpu_to_le32 (reloc_address);
o->base_relocation_table.size = grub_cpu_to_le32 (end_address
- reloc_address);
e = (Elf_Ehdr *) kernel_image;
if (! check_elf_header (e, kernel_size))
grub_util_error ("invalid ELF header");
-
+
section_offset = grub_cpu_to_le32 (e->e_shoff);
section_entsize = grub_cpu_to_le16 (e->e_shentsize);
num_sections = grub_cpu_to_le16 (e->e_shnum);
if (GRUB_KERNEL_MACHINE_PREFIX + strlen (prefix) + 1 > GRUB_KERNEL_MACHINE_DATA_END)
grub_util_error ("prefix too long");
-
+
strcpy (kernel_image + offset + GRUB_KERNEL_MACHINE_PREFIX, prefix);
break;
}
-
+
/* Relocate sections then symbols in the virtual address space. */
section_addresses = locate_sections (sections, section_entsize,
num_sections, strtab);
-
+
symtab_section = find_symtab_section (sections,
section_entsize, num_sections);
if (! symtab_section)
grub_util_error ("no symbol table");
-
+
start_address = relocate_symbols (e, sections, symtab_section,
section_addresses, section_entsize,
num_sections);
{
lzo_uint size;
char *wrkmem;
-
+
grub_util_info ("kernel_img=%p, kernel_size=0x%x", kernel_img, kernel_size);
if (kernel_size < GRUB_KERNEL_MACHINE_RAW_SIZE)
grub_util_error ("the core image is too small");
-
+
if (lzo_init () != LZO_E_OK)
grub_util_error ("cannot initialize LZO");
wrkmem = xmalloc (LZO1X_999_MEM_COMPRESS);
memcpy (*core_img, kernel_img, GRUB_KERNEL_MACHINE_RAW_SIZE);
-
+
grub_util_info ("compressing the core image");
if (lzo1x_999_compress ((const lzo_byte *) (kernel_img
+ GRUB_KERNEL_MACHINE_RAW_SIZE),
size_t mod_size;
mod_size = grub_util_get_image_size (p->name);
-
+
header = (struct grub_module_header *) (kernel_img + offset);
header->type = grub_cpu_to_le32 (OBJ_TYPE_ELF);
header->size = grub_cpu_to_le32 (mod_size + sizeof (*header));
if (memdisk_path)
{
struct grub_module_header *header;
-
+
header = (struct grub_module_header *) (kernel_img + offset);
header->type = grub_cpu_to_le32 (OBJ_TYPE_MEMDISK);
header->size = grub_cpu_to_le32 (memdisk_size + sizeof (*header));
&core_img, &core_size);
grub_util_info ("the core size is 0x%x", core_size);
-
+
num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS);
if (num > 0xffff)
grub_util_error ("the core image is too big");
boot_size = grub_util_get_image_size (boot_path);
if (boot_size != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("diskboot.img is not one sector size");
-
+
boot_img = grub_util_read_image (boot_path);
-
+
/* i386 is a little endian architecture. */
*((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE
- GRUB_BOOT_MACHINE_LIST_SIZE + 8))
grub_util_write_image (boot_img, boot_size, out);
free (boot_img);
free (boot_path);
-
+
module_addr = (path_list
? (GRUB_BOOT_MACHINE_KERNEL_ADDR + GRUB_DISK_SECTOR_SIZE
+ kernel_size)
if (core_size > GRUB_MEMORY_MACHINE_UPPER - GRUB_MEMORY_MACHINE_LINK_ADDR)
grub_util_error ("Core image is too big (%p > %p)\n", core_size,
GRUB_MEMORY_MACHINE_UPPER - GRUB_MEMORY_MACHINE_LINK_ADDR);
-
+
grub_util_write_image (core_img, core_size, out);
free (kernel_img);
free (core_img);
FILE *fp = stdout;
progname = "grub-mkimage";
-
+
while (1)
{
int c = getopt_long (argc, argv, "d:p:m:c:o:hVv", options, 0);
case 'o':
if (output)
free (output);
-
+
output = xstrdup (optarg);
break;
free (memdisk);
memdisk = xstrdup (optarg);
-
+
if (prefix)
free (prefix);
FILE *fp;
struct { grub_uint64_t start; grub_uint64_t end; } embed_region;
embed_region.start = embed_region.end = ~0UL;
-
+
auto void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset,
unsigned length);
auto void NESTED_FUNC_ATTR save_blocklists (grub_disk_addr_t sector, unsigned offset,
const grub_partition_t p)
{
struct grub_pc_partition *pcdata = p->data;
-
+
/* There's always an embed region, and it starts right after the MBR. */
embed_region.start = 1;
-
+
/* For its end offset, include as many dummy partitions as we can. */
if (! grub_pc_partition_is_empty (pcdata->dos_type)
&& ! grub_pc_partition_is_bsd (pcdata->dos_type)
&& embed_region.end > p->start)
embed_region.end = p->start;
-
+
return 1;
}
-
+
auto int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk,
const grub_partition_t p);
int NESTED_FUNC_ATTR find_usable_region_gpt (grub_disk_t disk __attribute__ ((unused)),
const grub_partition_t p)
{
struct grub_gpt_partentry *gptdata = p->data;
-
+
/* If there's an embed region, it is in a dedicated partition. */
if (! memcmp (&gptdata->type, &grub_gpt_partition_type_bios_boot, 16))
{
embed_region.start = p->start;
embed_region.end = p->start + p->len;
-
+
return 1;
}
-
+
return 0;
}
-
+
void NESTED_FUNC_ATTR save_first_sector (grub_disk_addr_t sector, unsigned offset,
unsigned length)
{
grub_util_info ("the first sector is <%llu,%u,%u>",
sector, offset, length);
-
+
if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("The first sector of the core file is not sector-aligned");
grub_util_info ("saving <%llu,%u,%u> with the segment 0x%x",
sector, offset, length, (unsigned) current_segment);
-
+
if (offset != 0 || last_length != GRUB_DISK_SECTOR_SIZE)
grub_util_error ("Non-sector-aligned data is found in the core file");
if (block->len)
grub_util_error ("The sectors of the core file are too fragmented");
}
-
+
last_length = length;
current_segment += GRUB_DISK_SECTOR_SIZE >> 4;
}
-
+
/* Read the boot image by the OS service. */
boot_path = grub_util_get_path (dir, boot_file);
boot_size = grub_util_get_image_size (boot_path);
+ GRUB_BOOT_MACHINE_KERNEL_SECTOR);
boot_drive_check = (grub_uint16_t *) (boot_img
+ GRUB_BOOT_MACHINE_DRIVE_CHECK);
-
+
core_path = grub_util_get_path (dir, core_file);
core_size = grub_util_get_image_size (core_path);
core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1)
grub_util_error ("The size of `%s' is too small", core_path);
else if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE)
grub_util_error ("The size of `%s' is too large", core_path);
-
+
core_img = grub_util_read_image (core_path);
/* Have FIRST_BLOCK to point to the first blocklist. */
GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC);
free (tmp_img);
-
+
/* If DEST_DRIVE is a hard disk, enable the workaround, which is
for buggy BIOSes which don't pass boot drive correctly. Instead,
they pass 0x00 or 0x01 even when booted from 0x80. */
dos_part = grub_le_to_cpu32 (*install_dos_part);
bsd_part = grub_le_to_cpu32 (*install_bsd_part);
}
-
+
grub_util_info ("dos partition is %d, bsd partition is %d",
dos_part, bsd_part);
grub_util_warn ("Attempting to install GRUB to a partition instead of the MBR. This is a BAD idea.");
goto unable_to_embed;
}
-
+
/* Unlike root_dev, with dest_dev we're interested in the partition map even
if dest_dev itself is a whole disk. */
auto int NESTED_FUNC_ATTR identify_partmap (grub_disk_t disk,
return 1;
}
grub_partition_iterate (dest_dev->disk, identify_partmap);
-
+
grub_partition_iterate (dest_dev->disk, (strcmp (dest_partmap, "pc_partition_map") ?
find_usable_region_gpt : find_usable_region_msdos));
if (embed_region.end == embed_region.start)
grub_util_info ("will embed the core image at sector 0x%llx", embed_region.start);
-
+
*install_dos_part = grub_cpu_to_le32 (dos_part);
*install_bsd_part = grub_cpu_to_le32 (bsd_part);
-
+
/* The first blocklist contains the whole sectors. */
first_block->start = grub_cpu_to_le64 (embed_region.start + 1);
first_block->len = grub_cpu_to_le16 (core_sectors - 1);
first_block->segment
= grub_cpu_to_le16 (GRUB_BOOT_MACHINE_KERNEL_SEG
+ (GRUB_DISK_SECTOR_SIZE >> 4));
-
+
/* Make sure that the second blocklist is a terminator. */
block = first_block - 1;
block->start = 0;
block->len = 0;
block->segment = 0;
-
+
/* Write the core image onto the disk. */
if (grub_disk_write (dest_dev->disk, embed_region.start, 0, core_size, core_img))
grub_util_error ("%s", grub_errmsg);
-
+
/* FIXME: can this be skipped? */
*boot_drive = 0xFF;
*root_drive = 0xFF;
-
+
*kernel_sector = grub_cpu_to_le64 (embed_region.start);
-
+
/* Write the boot image onto the disk. */
if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE,
boot_img))
grub_util_error ("%s", grub_errmsg);
-
+
goto finish;
-
+
unable_to_embed:
-
+
if (must_embed)
grub_util_error ("Embedding is not possible, but this is required when "
"the root device is on a RAID array or LVM volume.");
-
+
grub_util_warn ("Embedding is not possible. GRUB can only be installed in this "
"setup by using blocklists. However, blocklists are UNRELIABLE and "
"its use is discouraged.");
if (! force)
grub_util_error ("If you really want blocklists, use --force.");
-
+
/* Make sure that GRUB reads the identical image as the OS. */
tmp_img = xmalloc (core_size);
core_path_dev = grub_util_get_path (dir, core_file);
-
+
/* It is a Good Thing to sync two times. */
sync ();
sync ();
#define MAX_TRIES 5
-
+
for (i = 0; i < MAX_TRIES; i++)
{
grub_util_info ("attempting to read the core image `%s' from GRUB%s",
core_path_dev, (i == 0) ? "" : " again");
-
+
grub_disk_cache_invalidate_all ();
-
+
file = grub_file_open (core_path_dev);
if (file)
{
#if 0
FILE *dump;
FILE *dump2;
-
+
dump = fopen ("dump.img", "wb");
if (dump)
{
fwrite (core_img, 1, core_size, dump2);
fclose (dump2);
}
-
-#endif
+
+#endif
grub_util_info ("succeeded in opening the core image but the data is different");
}
else
if (grub_errno)
grub_util_info ("error message = %s", grub_errmsg);
-
+
grub_errno = GRUB_ERR_NONE;
sync ();
sleep (1);
block->segment = 0;
block--;
-
+
if ((char *) block <= core_img)
grub_util_error ("No terminator in the core image");
}
-
+
/* Now read the core image to determine where the sectors are. */
file = grub_file_open (core_path_dev);
if (! file)
grub_util_error ("%s", grub_errmsg);
-
+
file->read_hook = save_first_sector;
if (grub_file_read (file, tmp_img, GRUB_DISK_SECTOR_SIZE)
!= GRUB_DISK_SECTOR_SIZE)
grub_util_error ("Failed to read the rest sectors of the core image");
grub_file_close (file);
-
+
free (core_path_dev);
free (tmp_img);
-
+
*kernel_sector = grub_cpu_to_le64 (first_sector);
/* FIXME: can this be skipped? */
/* Sync is a Good Thing. */
sync ();
-
+
free (core_path);
free (core_img);
free (boot_img);
get_device_name (char *dev)
{
size_t len = strlen (dev);
-
+
if (dev[0] != '(' || dev[len - 1] != ')')
return 0;
char *root_dev = 0;
char *dest_dev;
int must_embed = 0, force = 0;
-
+
progname = "grub-setup";
/* Check for options. */
dir = xstrdup (optarg);
break;
-
+
case 'm':
if (dev_map)
free (dev_map);
root_dev = xstrdup (optarg);
break;
-
+
case 'f':
force = 1;
break;
/* Initialize all modules. */
grub_init_all ();
-
+
dest_dev = get_device_name (argv[optind]);
if (! dest_dev)
{
if (! tmp)
grub_util_error ("Invalid root device `%s'", root_dev);
-
+
tmp = xstrdup (tmp);
free (root_dev);
root_dev = tmp;
#ifdef __linux__
if (grub_util_lvm_isvolume (root_dev))
must_embed = 1;
-
+
if (root_dev[0] == 'm' && root_dev[1] == 'd'
&& root_dev[2] >= '0' && root_dev[2] <= '9')
{
/* Free resources. */
grub_fini_all ();
grub_util_biosdisk_fini ();
-
+
free (boot_file);
free (core_file);
free (dir);
free (dev_map);
free (root_dev);
free (dest_dev);
-
+
return 0;
}
char *devname;
struct stat st;
int err;
-
+
devname = xmalloc (strlen (name) + 13);
strcpy (devname, "/dev/mapper/");
grub_util_warn (const char *fmt, ...)
{
va_list ap;
-
+
fprintf (stderr, "%s: warn: ", progname);
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
if (verbosity > 0)
{
va_list ap;
-
+
fprintf (stderr, "%s: info: ", progname);
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
grub_util_error (const char *fmt, ...)
{
va_list ap;
-
+
fprintf (stderr, "%s: error: ", progname);
va_start (ap, fmt);
vfprintf (stderr, fmt, ap);
{
va_list ap;
int ret;
-
+
va_start (ap, fmt);
ret = vfprintf (stderr, fmt, ap);
va_end (ap);
xmalloc (size_t size)
{
void *p;
-
+
p = malloc (size);
if (! p)
grub_util_error ("out of memory");
{
size_t len;
char *dup;
-
+
len = strlen (str);
dup = (char *) xmalloc (len + 1);
memcpy (dup, str, len + 1);
grub_util_get_path (const char *dir, const char *file)
{
char *path;
-
+
path = (char *) xmalloc (strlen (dir) + 1 + strlen (file) + 1);
sprintf (path, "%s/%s", dir, file);
return path;
grub_util_get_fp_size (FILE *fp)
{
struct stat st;
-
+
if (fflush (fp) == EOF)
grub_util_error ("fflush failed");
if (fstat (fileno (fp), &st) == -1)
grub_util_error ("fstat failed");
-
+
return st.st_size;
}
grub_util_get_image_size (const char *path)
{
struct stat st;
-
+
grub_util_info ("getting the size of %s", path);
-
+
if (stat (path, &st) == -1)
grub_util_error ("cannot stat %s", path);
-
+
return st.st_size;
}
char *img;
FILE *fp;
size_t size;
-
+
grub_util_info ("reading %s", path);
size = grub_util_get_image_size (path);
grub_util_read_at (img, size, 0, fp);
fclose (fp);
-
+
return img;
}
{
FILE *fp;
size_t size;
-
+
grub_util_info ("reading %s", path);
size = grub_util_get_image_size (path);
-
+
fp = fopen (path, "rb");
if (! fp)
grub_util_error ("cannot open %s", path);
(void) size;
grub_util_error ("grub_memalign is not supported");
#endif
-
+
if (! p)
grub_util_error ("out of memory");
-
+
return p;
}
struct timeval tv;
gettimeofday (&tv, 0);
-
+
return (tv.tv_sec * GRUB_TICKS_PER_SECOND
+ (((tv.tv_sec % GRUB_TICKS_PER_SECOND) * 1000000 + tv.tv_usec)
* GRUB_TICKS_PER_SECOND / 1000000));
struct timeval tv;
gettimeofday (&tv, 0);
-
+
return (tv.tv_sec * 1000 + tv.tv_usec / 1000);
}
#endif
-void
+void
grub_arch_sync_caches (void *address __attribute__ ((unused)),
grub_size_t len __attribute__ ((unused)))
{
sprintf (name, "/dev/sd%c", 'a' + minor / 16);
else
grub_util_error ("Unknown device number: %d, %d", major, minor);
-
+
return name;
}
if (version.major != 0 || version.minor != 90)
grub_util_error ("Unsupported RAID version: %d.%d",
version.major, version.minor);
-
+
ret = ioctl (fd, GET_ARRAY_INFO, &info);
if (ret != 0)
grub_util_error ("ioctl GET_ARRAY_INFO error: %s", strerror (errno));
}
devicelist[j] = NULL;
-
+
return devicelist;
}
read_dep_list (FILE *fp)
{
struct dep_list *dep_list = 0;
-
+
while (fgets (buf, sizeof (buf), fp))
{
char *p;
dep = xmalloc (sizeof (*dep));
dep->name = xstrdup (buf);
dep->list = 0;
-
+
dep->next = dep_list;
dep_list = dep;
p++;
*p++ = '\0';
-
+
mod = (struct mod_list *) xmalloc (sizeof (*mod));
mod->name = xstrdup (name);
mod->next = dep->list;
{
char *base;
char *ext;
-
+
base = strrchr (str, '/');
if (! base)
base = (char *) str;
if (ext && strcmp (ext, ".mod") == 0)
{
char *name;
-
+
name = xmalloc (ext - base + 1);
memcpy (name, base, ext - base);
name[ext - base] = '\0';
return name;
}
-
+
return xstrdup (base);
}
char *base;
char *ext;
char *ret;
-
+
ext = strrchr (str, '.');
if (ext && strcmp (ext, ".mod") == 0)
base = xstrdup (str);
base = xmalloc (strlen (str) + 4 + 1);
sprintf (base, "%s.mod", str);
}
-
+
dir = strchr (str, '/');
if (dir)
return base;
struct grub_util_path_list *path;
struct mod_list *mod;
struct dep_list *dep;
-
+
mod_name = get_module_name (name);
/* Check if the module has already been added. */
if (grub_libusb_devices ())
return grub_errno;
- grub_usb_controller_dev_register (&usb_controller);
+ grub_usb_controller_dev_register (&usb_controller);
return 0;
}
/* Creates new bitmap, saves created bitmap on success to *bitmap. */
grub_err_t
-grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
+grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
unsigned int width, unsigned int height,
enum grub_video_blit_format blit_format)
{
switch (blit_format)
{
case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
- mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
+ mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
| GRUB_VIDEO_MODE_TYPE_ALPHA;
mode_info->bpp = 32;
mode_info->bytes_per_pixel = 4;
/* Calculate size needed for the data. */
size = (width * mode_info->bytes_per_pixel) * height;
- (*bitmap)->data = grub_malloc (size);
+ (*bitmap)->data = grub_malloc (size);
if (! (*bitmap)->data)
{
grub_free (*bitmap);
/* Loads bitmap using registered bitmap readers. */
grub_err_t
-grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
+grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
const char *filename)
{
grub_video_bitmap_reader_t reader = bitmap_readers_list;
not going to support developer area & extensions at this point. */
/* Read TGA header from beginning of file. */
- if (grub_file_read (file, (char*)&header, sizeof (header))
+ if (grub_file_read (file, (char*)&header, sizeof (header))
!= sizeof (header))
{
grub_file_close (file);
if (argc != 1)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "file name required");
- grub_video_reader_tga (&bitmap, args[0]);
+ grub_video_reader_tga (&bitmap, args[0]);
if (grub_errno != GRUB_ERR_NONE)
return grub_errno;
next_mode = modevar;
if (! modevar)
- return grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
"couldn't allocate space for local modevar copy");
if (grub_memcmp (next_mode, "keep", sizeof ("keep")) == 0
struct grub_video_mode_info mode_info;
int suitable = 1;
grub_err_t err;
-
+
grub_memset (&mode_info, 0, sizeof (mode_info));
if (grub_video_adapter_active)
if (! *next_mode)
{
grub_free (modevar);
-
+
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"No suitable mode found.");
}
-
+
/* Skip separator. */
next_mode++;
}
grub_video_adapter_active->fini ();
if (grub_errno != GRUB_ERR_NONE)
grub_errno = GRUB_ERR_NONE;
-
+
/* Mark active adapter as not set. */
grub_video_adapter_active = 0;
}
-
+
/* Loop until all modes has been tested out. */
while (next_mode != NULL)
{
/* Use last next_mode as current mode. */
tmp = next_mode;
-
+
/* Reset video mode settings. */
width = -1;
height = -1;
depth = -1;
flags = 0;
-
+
/* Save position of next mode and separate modes. */
for (; *next_mode; next_mode++)
if (*next_mode == ',' || *next_mode == ';')
}
else
next_mode = 0;
-
+
/* Skip whitespace. */
while (grub_isspace (*tmp))
tmp++;
-
+
/* Initialize token holders. */
current_mode = tmp;
param = tmp;
value = NULL;
- /* XXX: we assume that we're in pure text mode if
+ /* XXX: we assume that we're in pure text mode if
no video mode is initialized. Is it always true? */
if (grub_strcmp (param, "text") == 0)
{
struct grub_video_mode_info mode_info;
-
+
grub_memset (&mode_info, 0, sizeof (mode_info));
mode_info.mode_type = GRUB_VIDEO_MODE_TYPE_PURE_TEXT;
}
/* Parse <width>x<height>[x<depth>]*/
-
+
/* Find width value. */
value = param;
param = grub_strchr(param, 'x');
if (param == NULL)
{
grub_err_t rc;
-
+
/* First setup error message. */
rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
-
+
/* Free memory before returning. */
grub_free (modevar);
-
+
return rc;
}
-
+
*param = 0;
param++;
-
+
width = grub_strtoul (value, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
{
grub_err_t rc;
-
+
/* First setup error message. */
rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
-
+
/* Free memory before returning. */
grub_free (modevar);
-
+
return rc;
}
-
+
/* Find height value. */
value = param;
param = grub_strchr(param, 'x');
if (grub_errno != GRUB_ERR_NONE)
{
grub_err_t rc;
-
+
/* First setup error message. */
rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
-
+
/* Free memory before returning. */
grub_free (modevar);
-
+
return rc;
}
}
/* We have optional color depth value. */
*param = 0;
param++;
-
+
height = grub_strtoul (value, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
{
grub_err_t rc;
-
+
/* First setup error message. */
rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
-
+
/* Free memory before returning. */
grub_free (modevar);
-
+
return rc;
}
-
+
/* Convert color depth value. */
value = param;
depth = grub_strtoul (value, 0, 0);
if (grub_errno != GRUB_ERR_NONE)
{
grub_err_t rc;
-
+
/* First setup error message. */
rc = grub_error (GRUB_ERR_BAD_ARGUMENT,
"Invalid mode: %s\n",
current_mode);
-
+
/* Free memory before returning. */
grub_free (modevar);
}
/* Try out video mode. */
-
+
/* If we have 8 or less bits, then assume that it is indexed color mode. */
if ((depth <= 8) && (depth != -1))
flags |= GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
/* We have more than 8 bits, then assume that it is RGB color mode. */
if (depth > 8)
flags |= GRUB_VIDEO_MODE_TYPE_RGB;
-
+
/* If user requested specific depth, forward that information to driver. */
if (depth != -1)
flags |= (depth << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
& GRUB_VIDEO_MODE_TYPE_DEPTH_MASK;
-
+
/* Try to initialize requested mode. Ignore any errors. */
grub_video_adapter_t p;
{
grub_err_t err;
struct grub_video_mode_info mode_info;
-
+
grub_memset (&mode_info, 0, sizeof (mode_info));
/* Try to initialize adapter, if it fails, skip to next adapter. */
grub_errno = GRUB_ERR_NONE;
continue;
}
-
+
/* Valid mode found from adapter, and it has been activated.
Specify it as active adapter. */
grub_video_adapter_active = p;
-
+
/* Free memory. */
grub_free (modevar);
-
+
return GRUB_ERR_NONE;
}
/* Free memory. */
grub_free (modevar);
-
+
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"No suitable mode found.");
}