merge trunk

This commit is contained in:
Colin Watson 2011-03-14 22:01:32 +00:00
commit 7bdeb3987a
83 changed files with 1453 additions and 383 deletions

View file

@ -50,7 +50,7 @@ grub_script.yy.h: script/yylex.l
grub_script.yy.c: grub_script.yy.h
rs_decoder.S: $(srcdir)/lib/reed_solomon.c
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3
kern/i386/pc/startup.S: $(builddir)/rs_decoder.S
@ -303,7 +303,7 @@ platform_DATA += moddep.lst
CLEANFILES += config.log syminfo.lst moddep.lst
$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT)
sh $^ $@
TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@
platform_DATA += $(MOD_FILES)
CLEANFILES += $(MOD_FILES)

View file

@ -324,6 +324,7 @@ image = {
name = fwstart;
mips_yeeloong = boot/mips/yeeloong/fwstart.S;
objcopyflags = '-O binary';
ldflags = '-static-libgcc -lgcc -Wl,-N,-S,-Ttext,0xbfc00000,-Bstatic';
enable = mips_yeeloong;
};
@ -1149,6 +1150,7 @@ module = {
module = {
name = linux16;
i386_pc = loader/i386/pc/linux.c;
i386_pc = lib/cmdline.c;
enable = i386_pc;
};
@ -1183,6 +1185,7 @@ module = {
mips = loader/mips/linux.c;
powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
common = lib/cmdline.c;
enable = noemu;
};
@ -1461,7 +1464,6 @@ module = {
name = ieee1275_fb;
ieee1275 = video/ieee1275.c;
enable = powerpc;
enable = sparc64;
};
module = {

View file

@ -178,8 +178,13 @@ real_code_2:
pushw %es
popw %ds
#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200
movl $0x200, %ecx
addl %ecx, %esi
#else
movl $(GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4), %ecx
addl $0x200, %esi
#endif
movl $DATA_ADDR, %edi
call LOCAL(move_memory)
@ -196,7 +201,11 @@ real_code_2:
1:
movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
#if GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4 < 0x200
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
#else
addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - (GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_PART + 4)), %ecx
#endif
2:
call LOCAL(move_memory)

View file

@ -38,7 +38,7 @@ write_bases (void)
for (i = 0; i < GRUB_MACHINE_PCI_NUM_WIN; i++)
reg |= (((base_win[i] >> GRUB_MACHINE_PCI_WIN_SHIFT)
& GRUB_MACHINE_PCI_WIN_MASK)
>> (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE));
<< (i * GRUB_MACHINE_PCI_WIN_MASK_SIZE));
GRUB_MACHINE_PCI_IO_CTRL_REG = reg;
}

View file

@ -83,9 +83,13 @@ legacy_file (const char *filename)
{
char *oldname = NULL;
char *newsuffix;
char *ptr;
for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
oldname = entryname;
parsed = grub_legacy_parse (buf, &entryname, &newsuffix);
parsed = grub_legacy_parse (ptr, &entryname, &newsuffix);
grub_free (buf);
buf = NULL;
if (newsuffix)
{
@ -209,7 +213,7 @@ grub_cmd_legacy_source (struct grub_command *cmd,
grub_menu_t menu;
menu = grub_env_get_menu ();
if (menu && menu->size)
grub_show_menu (menu, 1);
grub_show_menu (menu, 1, 0);
if (!extractor)
grub_env_context_close ();
}

View file

@ -210,11 +210,11 @@ grub_cmd_terminal_input (grub_command_t cmd __attribute__ ((unused)),
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, init);
(void) GRUB_FIELD_MATCH (grub_term_inputs, struct abstract_terminal *, fini);
return handle_command (argc, args,
(struct abstract_terminal **) &grub_term_inputs,
(struct abstract_terminal **) &grub_term_inputs_disabled,
grub_term_input_autoload,
N_ ("Active input terminals:"),
N_ ("Available input terminals:"));
(struct abstract_terminal **) (void *) &grub_term_inputs,
(struct abstract_terminal **) (void *) &grub_term_inputs_disabled,
grub_term_input_autoload,
N_ ("Active input terminals:"),
N_ ("Available input terminals:"));
}
static grub_err_t
@ -225,11 +225,12 @@ grub_cmd_terminal_output (grub_command_t cmd __attribute__ ((unused)),
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, name);
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, init);
(void) GRUB_FIELD_MATCH (grub_term_outputs, struct abstract_terminal *, fini);
return handle_command (argc, args, (struct abstract_terminal **) &grub_term_outputs,
(struct abstract_terminal **) &grub_term_outputs_disabled,
grub_term_output_autoload,
N_ ("Active output terminals:"),
N_ ("Available output terminals:"));
return handle_command (argc, args,
(struct abstract_terminal **) (void *) &grub_term_outputs,
(struct abstract_terminal **) (void *) &grub_term_outputs_disabled,
grub_term_output_autoload,
N_ ("Active output terminals:"),
N_ ("Available output terminals:"));
}
static grub_command_t cmd_terminal_input, cmd_terminal_output;

View file

@ -62,11 +62,10 @@ ofdisk_hash_find (const char *devpath)
}
static struct ofdisk_hash_ent *
ofdisk_hash_add (char *devpath)
ofdisk_hash_add_real (char *devpath)
{
struct ofdisk_hash_ent *p;
struct ofdisk_hash_ent **head = &ofdisk_hash[ofdisk_hash_fn(devpath)];
struct ofdisk_hash_ent *p, *pcan;
char *curcan;
p = grub_malloc(sizeof (*p));
if (!p)
@ -76,17 +75,27 @@ ofdisk_hash_add (char *devpath)
p->next = *head;
p->shortest = 0;
*head = p;
return p;
}
static struct ofdisk_hash_ent *
ofdisk_hash_add (char *devpath, char *curcan)
{
struct ofdisk_hash_ent *p, *pcan;
p = ofdisk_hash_add_real (devpath);
grub_dprintf ("disk", "devpath = %s, canonical = %s\n", devpath, curcan);
curcan = grub_ieee1275_canonicalise_devname (devpath);
if (!curcan)
{
grub_errno = GRUB_ERR_NONE;
p->shortest = devpath;
return p;
}
pcan = ofdisk_hash_find (curcan);
if (!pcan)
pcan = ofdisk_hash_add (curcan);
pcan = ofdisk_hash_add_real (curcan);
else
grub_free (curcan);
@ -118,17 +127,22 @@ scan (void)
return 0;
grub_dprintf ("disk", "disk name = %s\n", alias->name);
grub_dprintf ("disk", "disk name = %s, path = %s\n", alias->name,
alias->path);
op = ofdisk_hash_find (alias->path);
op = ofdisk_hash_find (alias->name);
if (!op)
{
char *name = grub_strdup (alias->name);
if (!name)
char *can = grub_strdup (alias->path);
if (!name || !can)
{
grub_errno = GRUB_ERR_NONE;
grub_free (name);
grub_free (can);
return 0;
}
op = ofdisk_hash_add (name);
op = ofdisk_hash_add (name, can);
}
return 0;
}
@ -247,7 +261,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
struct ofdisk_hash_ent *op;
op = ofdisk_hash_find (devpath);
if (!op)
op = ofdisk_hash_add (devpath);
op = ofdisk_hash_add (devpath, NULL);
else
grub_free (devpath);
if (!op)

View file

@ -143,24 +143,28 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
&sb))
return grub_errno;
if (sb.magic != SB_MAGIC)
if (grub_le_to_cpu32 (sb.magic) != SB_MAGIC
|| grub_le_to_cpu64 (sb.super_offset) != sector)
continue;
{
grub_uint64_t sb_size;
struct grub_raid_super_1x *real_sb;
grub_uint32_t level;
if (sb.major_version != 1)
if (grub_le_to_cpu32 (sb.major_version) != 1)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Unsupported RAID version: %d",
sb.major_version);
grub_le_to_cpu32 (sb.major_version));
level = grub_le_to_cpu32 (sb.level);
/* Multipath. */
if ((int) sb.level == -4)
sb.level = 1;
if ((int) level == -4)
level = 1;
if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
sb.level != 5 && sb.level != 6 && sb.level != 10)
if (level != 0 && level != 1 && level != 4 &&
level != 5 && level != 6 && level != 10)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"Unsupported RAID level: %d", sb.level);
@ -209,7 +213,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
grub_memcpy (array->uuid, real_sb->set_uuid, 16);
*start_sector = real_sb->data_offset;
*start_sector = grub_le_to_cpu64 (real_sb->data_offset);
grub_free (real_sb);
return 0;

View file

@ -167,6 +167,7 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
grub_uint64_t size;
struct grub_raid_super_09 sb;
grub_uint32_t *uuid;
grub_uint32_t level;
/* The sector where the mdraid 0.90 superblock is stored, if available. */
size = grub_disk_get_size (disk);
@ -178,36 +179,40 @@ grub_mdraid_detect (grub_disk_t disk, struct grub_raid_array *array,
return grub_errno;
/* Look whether there is a mdraid 0.90 superblock. */
if (sb.md_magic != SB_MAGIC)
if (grub_le_to_cpu32 (sb.md_magic) != SB_MAGIC)
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not 0.9x raid");
if (sb.major_version != 0 || sb.minor_version != 90)
if (grub_le_to_cpu32 (sb.major_version) != 0
|| grub_le_to_cpu32 (sb.minor_version) != 90)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported RAID version: %d.%d",
sb.major_version, sb.minor_version);
grub_le_to_cpu32 (sb.major_version),
grub_le_to_cpu32 (sb.minor_version));
/* FIXME: Check the checksum. */
level = grub_le_to_cpu32 (sb.level);
/* Multipath. */
if ((int) sb.level == -4)
sb.level = 1;
if ((int) level == -4)
level = 1;
if (sb.level != 0 && sb.level != 1 && sb.level != 4 &&
sb.level != 5 && sb.level != 6 && sb.level != 10)
if (level != 0 && level != 1 && level != 4 &&
level != 5 && level != 6 && level != 10)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported RAID level: %d", sb.level);
if (sb.this_disk.number == 0xffff || sb.this_disk.number == 0xfffe)
"unsupported RAID level: %d", level);
if (grub_le_to_cpu32 (sb.this_disk.number) == 0xffff
|| grub_le_to_cpu32 (sb.this_disk.number) == 0xfffe)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"spares aren't implemented");
array->name = NULL;
array->number = sb.md_minor;
array->level = sb.level;
array->layout = sb.layout;
array->total_devs = sb.raid_disks;
array->disk_size = (sb.size) ? sb.size * 2 : sector;
array->chunk_size = sb.chunk_size >> 9;
array->index = sb.this_disk.number;
array->number = grub_le_to_cpu32 (sb.md_minor);
array->level = level;
array->layout = grub_le_to_cpu32 (sb.layout);
array->total_devs = grub_le_to_cpu32 (sb.raid_disks);
array->disk_size = (sb.size) ? grub_le_to_cpu32 (sb.size) * 2 : sector;
array->chunk_size = grub_le_to_cpu32 (sb.chunk_size) >> 9;
array->index = grub_le_to_cpu32 (sb.this_disk.number);
array->uuid_len = 16;
array->uuid = grub_malloc (16);
if (!array->uuid)

View file

@ -530,8 +530,8 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
/* We found multiple devices with the same number. Again,
this shouldn't happen. */
return grub_error (GRUB_ERR_BAD_DEVICE,
"found two disks with the number %d",
new_array->number);
"found two disks with the index %d for RAID %s",
new_array->index, array->name);
if (new_array->disk_size < array->disk_size)
array->disk_size = new_array->disk_size;
@ -570,7 +570,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
{
for (p = array_list; p != NULL; p = p->next)
{
if (! p->name && p->number == array->number)
if (p->number == array->number)
break;
}
}

View file

@ -45,7 +45,9 @@ grub_raid5_recover (struct grub_raid_array *array, int disknr,
if (i == disknr)
continue;
err = grub_disk_read (array->members[i].device, sector, 0, size, buf2);
err = grub_disk_read (array->members[i].device,
array->members[i].start_sector + sector,
0, size, buf2);
if (err)
{

View file

@ -119,7 +119,8 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
else
{
if ((array->members[pos].device) &&
(! grub_disk_read (array->members[pos].device, sector,
(! grub_disk_read (array->members[pos].device,
array->members[i].start_sector + sector,
0, size, buf)))
{
grub_raid_block_xor (pbuf, buf, size);
@ -150,7 +151,9 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
{
/* One bad device */
if ((array->members[p].device) &&
(! grub_disk_read (array->members[p].device, sector, 0, size, buf)))
(! grub_disk_read (array->members[p].device,
array->members[i].start_sector + sector,
0, size, buf)))
{
grub_raid_block_xor (buf, pbuf, size);
goto quit;
@ -163,7 +166,8 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
}
grub_errno = GRUB_ERR_NONE;
if (grub_disk_read (array->members[q].device, sector, 0, size, buf))
if (grub_disk_read (array->members[q].device,
array->members[i].start_sector + sector, 0, size, buf))
goto quit;
grub_raid_block_xor (buf, qbuf, size);
@ -181,12 +185,16 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
goto quit;
}
if (grub_disk_read (array->members[p].device, sector, 0, size, buf))
if (grub_disk_read (array->members[p].device,
array->members[i].start_sector + sector,
0, size, buf))
goto quit;
grub_raid_block_xor (pbuf, buf, size);
if (grub_disk_read (array->members[q].device, sector, 0, size, buf))
if (grub_disk_read (array->members[q].device,
array->members[i].start_sector + sector,
0, size, buf))
goto quit;
grub_raid_block_xor (qbuf, buf, size);

View file

@ -506,7 +506,7 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
if (scsi->blocksize != GRUB_DISK_SECTOR_SIZE)
{
unsigned spb = scsi->blocksize >> GRUB_DISK_SECTOR_BITS;
if (! (spb != 0 && (scsi->blocksize & GRUB_DISK_SECTOR_SIZE) == 0))
if (spb == 0 || (scsi->blocksize & (GRUB_DISK_SECTOR_SIZE - 1)) != 0)
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"unsupported SCSI block size");

View file

@ -60,6 +60,9 @@ grub_btrfs_mount (grub_disk_t disk)
return data;
fail:
if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");
grub_free (data);
return NULL;
}

View file

@ -281,7 +281,7 @@ grub_pxefs_open (struct grub_file *file, const char *name)
}
file->data = data;
file->not_easly_seekable = 1;
file->not_easily_seekable = 1;
grub_memcpy (file_int, file, sizeof (struct grub_file));
curr_file = file_int;
@ -420,6 +420,7 @@ set_mac_env (grub_uint8_t *mac_addr, grub_size_t mac_len)
grub_env_set ("net_pxe_mac", buf);
/* XXX: Is it possible to change MAC in PXE? */
grub_register_variable_hook ("net_pxe_mac", 0, grub_env_write_readonly);
grub_env_export ("net_pxe_mac");
}
static void
@ -431,6 +432,7 @@ set_env_limn_ro (const char *varname, char *value, grub_size_t len)
grub_env_set (varname, value);
value[len] = c;
grub_register_variable_hook (varname, 0, grub_env_write_readonly);
grub_env_export (varname);
}
static void
@ -624,12 +626,19 @@ GRUB_MOD_INIT(pxe)
grub_env_write_pxe_default_server);
grub_register_variable_hook ("pxe_default_gateway", 0,
grub_env_write_pxe_default_gateway);
/* XXX: Is it possible to change IP in PXE? */
grub_register_variable_hook ("net_pxe_ip", 0,
grub_env_write_readonly);
grub_register_variable_hook ("pxe_blksize", 0,
grub_env_write_pxe_blocksize);
grub_env_export ("pxe_default_server");
grub_env_export ("pxe_default_gateway");
grub_env_export ("net_pxe_ip");
grub_env_export ("pxe_blksize");
grub_disk_dev_register (&grub_pxe_dev);
grub_fs_register (&grub_pxefs_fs);
}

View file

@ -451,18 +451,27 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
{
grub_uint64_t ino;
void *inopos = (((char *) de)
grub_uint8_t *inopos = (((grub_uint8_t *) de)
+ sizeof (struct grub_xfs_dir_entry)
+ de->len - 1);
char name[de->len + 1];
/* inopos might be unaligned. */
if (smallino)
{
ino = grub_be_to_cpu32 (*(grub_uint32_t *) inopos);
ino = grub_cpu_to_be64 (ino);
}
ino = (((grub_uint32_t) inopos[0]) << 24)
| (((grub_uint32_t) inopos[1]) << 16)
| (((grub_uint32_t) inopos[2]) << 8)
| (((grub_uint32_t) inopos[3]) << 0);
else
ino = *(grub_uint64_t *) inopos;
ino = (((grub_uint64_t) inopos[0]) << 56)
| (((grub_uint64_t) inopos[1]) << 48)
| (((grub_uint64_t) inopos[2]) << 40)
| (((grub_uint64_t) inopos[3]) << 32)
| (((grub_uint64_t) inopos[4]) << 24)
| (((grub_uint64_t) inopos[5]) << 16)
| (((grub_uint64_t) inopos[6]) << 8)
| (((grub_uint64_t) inopos[7]) << 0);
ino = grub_cpu_to_be64 (ino);
grub_memcpy (name, de->name, de->len);
name[de->len] = '\0';

View file

@ -603,7 +603,8 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
int idx, level;
blkptr_t *bp_array = dn->dn.dn_blkptr;
int epbs = dn->dn.dn_indblkshift - SPA_BLKPTRSHIFT;
blkptr_t *bp, *tmpbuf = 0;
blkptr_t *bp;
void *tmpbuf = 0;
grub_zfs_endian_t endian;
grub_err_t err = GRUB_ERR_NONE;
@ -646,7 +647,7 @@ dmu_read (dnode_end_t * dn, grub_uint64_t blkid, void **buf,
break;
}
grub_dprintf ("zfs", "endian = %d\n", endian);
err = zio_read (bp, endian, (void **) &tmpbuf, 0, data);
err = zio_read (bp, endian, &tmpbuf, 0, data);
endian = (grub_zfs_to_cpu64 (bp->blk_prop, endian) >> 63) & 1;
if (err)
break;
@ -836,14 +837,12 @@ zap_leaf_lookup (zap_leaf_phys_t * l, grub_zfs_endian_t endian,
name))
{
struct zap_leaf_array *la;
grub_uint8_t *ip;
if (le->le_int_size != 8 || le->le_value_length != 1)
return grub_error (GRUB_ERR_BAD_FS, "invalid leaf chunk entry");
/* get the uint64_t property value */
la = &ZAP_LEAF_CHUNK (l, blksft, le->le_value_chunk).l_array;
ip = la->la_array;
*value = grub_be_to_cpu64 (la->la_array64);
@ -880,7 +879,7 @@ static grub_err_t
fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap,
char *name, grub_uint64_t * value, struct grub_zfs_data *data)
{
zap_leaf_phys_t *l;
void *l;
grub_uint64_t hash, idx, blkid;
int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
zap_dnode->endian) << DNODE_SHIFT);
@ -903,7 +902,7 @@ fzap_lookup (dnode_end_t * zap_dnode, zap_phys_t * zap,
/* Get the leaf block */
if ((1U << blksft) < sizeof (zap_leaf_phys_t))
return grub_error (GRUB_ERR_BAD_FS, "ZAP leaf is too small");
err = dmu_read (zap_dnode, blkid, (void **) &l, &leafendian, data);
err = dmu_read (zap_dnode, blkid, &l, &leafendian, data);
if (err)
return err;
@ -920,6 +919,7 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
struct grub_zfs_data *data)
{
zap_leaf_phys_t *l;
void *l_in;
grub_uint64_t idx, blkid;
grub_uint16_t chunk;
int blksft = zfs_log2 (grub_zfs_to_cpu16 (zap_dnode->dn.dn_datablkszsec,
@ -947,7 +947,8 @@ fzap_iterate (dnode_end_t * zap_dnode, zap_phys_t * zap,
{
blkid = ((grub_uint64_t *) zap)[idx + (1 << (blksft - 3 - 1))];
err = dmu_read (zap_dnode, blkid, (void **) &l, &endian, data);
err = dmu_read (zap_dnode, blkid, &l_in, &endian, data);
l = l_in;
if (err)
{
grub_errno = GRUB_ERR_NONE;
@ -1108,7 +1109,7 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
grub_uint64_t blkid, blksz; /* the block id this object dnode is in */
int epbs; /* shift of number of dnodes in a block */
int idx; /* index within a block */
dnode_phys_t *dnbuf;
void *dnbuf;
grub_err_t err;
grub_zfs_endian_t endian;
@ -1131,7 +1132,7 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
grub_dprintf ("zfs", "endian = %d, blkid=%llx\n", mdn->endian,
(unsigned long long) blkid);
err = dmu_read (mdn, blkid, (void **) &dnbuf, &endian, data);
err = dmu_read (mdn, blkid, &dnbuf, &endian, data);
if (err)
return err;
grub_dprintf ("zfs", "alive\n");
@ -1153,7 +1154,7 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
data->dnode_endian = endian;
}
grub_memmove (&(buf->dn), &dnbuf[idx], DNODE_SIZE);
grub_memmove (&(buf->dn), (dnode_phys_t *) dnbuf + idx, DNODE_SIZE);
buf->endian = endian;
if (type && buf->dn.dn_type != type)
return grub_error(GRUB_ERR_BAD_FS, "incorrect dnode type");
@ -1465,7 +1466,7 @@ get_filesystem_dnode (dnode_end_t * mosmdn, char *fsname,
static grub_err_t
make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
{
objset_phys_t *osp;
void *osp;
blkptr_t *bp;
grub_size_t ospsize;
grub_err_t err;
@ -1473,7 +1474,7 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
grub_dprintf ("zfs", "endian = %d\n", mdn->endian);
bp = &(((dsl_dataset_phys_t *) DN_BONUS (&mdn->dn))->ds_bp);
err = zio_read (bp, mdn->endian, (void **) &osp, &ospsize, data);
err = zio_read (bp, mdn->endian, &osp, &ospsize, data);
if (err)
return err;
if (ospsize < OBJSET_PHYS_SIZE_V14)
@ -1483,7 +1484,8 @@ make_mdn (dnode_end_t * mdn, struct grub_zfs_data *data)
}
mdn->endian = (grub_zfs_to_cpu64 (bp->blk_prop, mdn->endian)>>63) & 1;
grub_memmove ((char *) &(mdn->dn), (char *) &osp->os_meta_dnode, DNODE_SIZE);
grub_memmove ((char *) &(mdn->dn),
(char *) &((objset_phys_t *) osp)->os_meta_dnode, DNODE_SIZE);
grub_free (osp);
return GRUB_ERR_NONE;
}
@ -1960,7 +1962,7 @@ zfs_mount (grub_device_t dev)
int label = 0;
uberblock_phys_t *ub_array, *ubbest = NULL;
vdev_boot_header_t *bh;
objset_phys_t *osp = 0;
void *osp = 0;
grub_size_t ospsize;
grub_err_t err;
int vdevnum;
@ -2038,7 +2040,7 @@ zfs_mount (grub_device_t dev)
? LITTLE_ENDIAN : BIG_ENDIAN);
err = zio_read (&ubbest->ubp_uberblock.ub_rootbp,
ub_endian,
(void **) &osp, &ospsize, data);
&osp, &ospsize, data);
if (err)
{
grub_dprintf ("zfs", "couldn't zio_read\n");
@ -2067,7 +2069,8 @@ zfs_mount (grub_device_t dev)
continue;
#endif
/* Got the MOS. Save it at the memory addr MOS. */
grub_memmove (&(data->mos.dn), &osp->os_meta_dnode, DNODE_SIZE);
grub_memmove (&(data->mos.dn), &((objset_phys_t *) osp)->os_meta_dnode,
DNODE_SIZE);
data->mos.endian = (grub_zfs_to_cpu64 (ubbest->ubp_uberblock.ub_rootbp.blk_prop, ub_endian) >> 63) & 1;
grub_memmove (&(data->current_uberblock),
&ubbest->ubp_uberblock, sizeof (uberblock_t));
@ -2201,7 +2204,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
*/
if (data->dnode.dn.dn_bonustype == DMU_OT_SA)
{
sa_hdr_phys_t *sahdrp;
void *sahdrp;
int hdrsize;
if (data->dnode.dn.dn_bonuslen != 0)
@ -2212,7 +2215,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
{
blkptr_t *bp = &data->dnode.dn.dn_spill;
err = zio_read (bp, data->dnode.endian, (void **) &sahdrp, NULL, data);
err = zio_read (bp, data->dnode.endian, &sahdrp, NULL, data);
if (err)
return err;
}
@ -2221,7 +2224,7 @@ grub_zfs_open (struct grub_file *file, const char *fsfilename)
return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
}
hdrsize = SA_HDR_SIZE (sahdrp);
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
file->size = *(grub_uint64_t *) ((char *) sahdrp + hdrsize + SA_SIZE_OFFSET);
}
else
@ -2280,6 +2283,7 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len)
read = 0;
while (length)
{
void *t;
/*
* Find requested blkid and the offset within that block.
*/
@ -2287,8 +2291,9 @@ grub_zfs_read (grub_file_t file, char *buf, grub_size_t len)
grub_free (data->file_buf);
data->file_buf = 0;
err = dmu_read (&(data->dnode), blkid, (void **) &(data->file_buf),
err = dmu_read (&(data->dnode), blkid, &t,
0, data);
data->file_buf = t;
if (err)
return -1;

View file

@ -364,21 +364,16 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc,
grub_free (nv);
grub_free (nvlist);
if (bootpath && devid)
{
bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu bootpath=%s diskdevid=%s",
poolname, (unsigned long long) mdnobj,
bootpath, devid);
if (!bootfs)
return grub_errno;
}
else
{
bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu",
poolname, (unsigned long long) mdnobj);
if (!bootfs)
return grub_errno;
}
bootfs = grub_xasprintf ("zfs-bootfs=%s/%llu%s%s%s%s%s%s",
poolname, (unsigned long long) mdnobj,
bootpath ? ",bootpath=\"" : "",
bootpath ? : "",
bootpath ? "\"" : "",
devid ? ",diskdevid=\"" : "",
devid ? : "",
devid ? "\"" : "");
if (!bootfs)
return grub_errno;
if (argc >= 2)
grub_env_set (args[1], bootfs);
else

View file

@ -52,8 +52,8 @@ fi
rm -f $t1 $t2
if test x@TARGET_APPLE_CC@ != x1; then
if ! test -z "@TARGET_OBJ2ELF@"; then
./@TARGET_OBJ2ELF@ $tmpfile || exit 1
if ! test -z "${TARGET_OBJ2ELF}"; then
./${TARGET_OBJ2ELF} $tmpfile || exit 1
fi
if test x@platform@ != xemu; then
@STRIP@ --strip-unneeded \

View file

@ -86,18 +86,21 @@ grub_read_hook_datetime (struct grub_env_var *var,
GRUB_MOD_INIT(datehook)
{
int i;
unsigned i;
for (i = 0; i < 7; i++)
grub_register_variable_hook (grub_datetime_names[i],
grub_read_hook_datetime, 0);
for (i = 0; i < ARRAY_SIZE (grub_datetime_names); i++)
{
grub_register_variable_hook (grub_datetime_names[i],
grub_read_hook_datetime, 0);
grub_env_export (grub_datetime_names[i]);
}
}
GRUB_MOD_FINI(datehook)
{
int i;
unsigned i;
for (i = 0; i < 7; i++)
for (i = 0; i < ARRAY_SIZE (grub_datetime_names); i++)
{
grub_register_variable_hook (grub_datetime_names[i], 0, 0);
grub_env_unset (grub_datetime_names[i]);

View file

@ -74,7 +74,7 @@ grub_bufio_open (grub_file_t io, int size)
file->data = bufio;
file->read_hook = 0;
file->fs = &grub_bufio_fs;
file->not_easly_seekable = io->not_easly_seekable;
file->not_easily_seekable = io->not_easily_seekable;
return file;
}

View file

@ -1136,7 +1136,7 @@ grub_gzio_open (grub_file_t io)
file->data = gzio;
file->read_hook = 0;
file->fs = &grub_gzio_fs;
file->not_easly_seekable = 1;
file->not_easily_seekable = 1;
if (! test_header (file))
{

View file

@ -200,7 +200,7 @@ grub_xzio_open (grub_file_t io)
file->read_hook = 0;
file->fs = &grub_xzio_fs;
file->size = GRUB_FILE_SIZE_UNKNOWN;
file->not_easly_seekable = 1;
file->not_easily_seekable = 1;
if (grub_file_tell (xzio->file) != 0)
grub_file_seek (xzio->file, 0);

View file

@ -52,13 +52,13 @@ grub_efi_allocate_pages (grub_efi_physical_address_t address,
grub_efi_status_t status;
grub_efi_boot_services_t *b;
#if GRUB_TARGET_SIZEOF_VOID_P < 8
#if 1
/* Limit the memory access to less than 4GB for 32-bit platforms. */
if (address > 0xffffffff)
return 0;
#endif
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
#if 1
if (address == 0)
{
type = GRUB_EFI_ALLOCATE_MAX_ADDRESS;
@ -251,7 +251,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
{
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
#if 1
&& desc->physical_start <= 0xffffffff
#endif
&& desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000
@ -267,7 +267,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
desc->physical_start = 0x100000;
}
#if GRUB_TARGET_SIZEOF_VOID_P < 8 || defined (MCMODEL_SMALL)
#if 1
if (BYTES_TO_PAGES (filtered_desc->physical_start)
+ filtered_desc->num_pages
> BYTES_TO_PAGES (0x100000000LL))

View file

@ -17,7 +17,9 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config-util.h>
#include <config.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <assert.h>
@ -135,8 +137,12 @@ find_root_device_from_mountinfo (const char *dir)
continue; /* only a subtree is mounted */
enc_path_len = strlen (enc_path);
/* Check that enc_path is a prefix of dir. The prefix must either be
the entire string, or end with a slash, or be immediately followed
by a slash. */
if (strncmp (dir, enc_path, enc_path_len) != 0 ||
(dir[enc_path_len] && dir[enc_path_len] != '/'))
(enc_path_len && dir[enc_path_len - 1] != '/' &&
dir[enc_path_len] && dir[enc_path_len] != '/'))
continue;
/* This is a parent of the requested directory. /proc/self/mountinfo

View file

@ -240,3 +240,23 @@ grub_register_variable_hook (const char *name,
return GRUB_ERR_NONE;
}
grub_err_t
grub_env_export (const char *name)
{
struct grub_env_var *var;
var = grub_env_find (name);
if (! var)
{
grub_err_t err;
err = grub_env_set (name, "");
if (err)
return err;
var = grub_env_find (name);
}
var->global = 1;
return GRUB_ERR_NONE;
}

View file

@ -140,36 +140,27 @@ compact_mem_regions (void)
}
}
/*
*
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
* BIOS call "INT 12H" to get conventional memory size
* The return value in AX.
*/
static inline grub_uint16_t
grub_get_conv_memsize (void)
{
struct grub_bios_int_registers regs;
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
grub_bios_interrupt (0x12, &regs);
return regs.eax & 0xffff;
}
void
grub_machine_init (void)
{
int i;
#if 0
int grub_lower_mem;
#endif
/* Initialize the console as early as possible. */
grub_console_init ();
/* This sanity check is useless since top of GRUB_MEMORY_MACHINE_RESERVED_END
is used for stack and if it's unavailable we wouldn't have gotten so far.
*/
#if 0
grub_lower_mem = grub_get_conv_memsize () << 10;
/* Sanity check. */
if (grub_lower_mem < GRUB_MEMORY_MACHINE_RESERVED_END)
grub_fatal ("too small memory");
#endif
/* FIXME: This prevents loader/i386/linux.c from using low memory. When our
heap implements support for requesting a chunk in low memory, this should

View file

@ -36,6 +36,22 @@ struct grub_machine_mmap_entry
} __attribute__((packed));
/*
*
* grub_get_conv_memsize(i) : return the conventional memory size in KB.
* BIOS call "INT 12H" to get conventional memory size
* The return value in AX.
*/
static inline grub_uint16_t
grub_get_conv_memsize (void)
{
struct grub_bios_int_registers regs;
regs.flags = GRUB_CPU_INT_FLAGS_DEFAULT;
grub_bios_interrupt (0x12, &regs);
return regs.eax & 0xffff;
}
/*
* grub_get_ext_memsize() : return the extended memory size in KB.
* BIOS call "INT 15H, AH=88H" to get extended memory size
@ -155,6 +171,10 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
{
grub_uint32_t eisa_mmap = grub_get_eisa_mmap ();
if (hook (0x0, ((grub_uint32_t) grub_get_conv_memsize ()) << 10,
GRUB_MEMORY_AVAILABLE))
return 0;
if (eisa_mmap)
{
if (hook (0x100000, (eisa_mmap & 0xFFFF) << 10,
@ -162,7 +182,8 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
hook (0x1000000, eisa_mmap & ~0xFFFF, GRUB_MEMORY_AVAILABLE);
}
else
hook (0x100000, grub_get_ext_memsize () << 10, GRUB_MEMORY_AVAILABLE);
hook (0x100000, ((grub_uint32_t) grub_get_ext_memsize ()) << 10,
GRUB_MEMORY_AVAILABLE);
}
return 0;

View file

@ -84,6 +84,9 @@ grub_ieee1275_find_options (void)
if (rc >= 0 && !grub_strcmp (tmp, "Emulated PC"))
is_qemu = 1;
if (grub_strncmp (tmp, "PowerMac", sizeof ("PowerMac") - 1) == 0)
grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS);
if (is_smartfirmware)
{
/* Broken in all versions */

View file

@ -50,6 +50,12 @@ grub_machine_mmap_iterate (grub_memory_hook_t hook)
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
"couldn't examine /memory/available property");
if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS))
{
address_cells = 1;
size_cells = 1;
}
/* Decode each entry and call `hook'. */
i = 0;
available_size /= sizeof (grub_uint32_t);

View file

@ -189,6 +189,8 @@ grub_main (void)
for convenience. */
grub_machine_set_prefix ();
grub_set_root_dev ();
grub_env_export ("root");
grub_env_export ("prefix");
grub_register_core_commands ();

View file

@ -41,6 +41,7 @@ extern void grub_at_keyboard_init (void);
extern void grub_serial_init (void);
extern void grub_terminfo_init (void);
extern void grub_keylayouts_init (void);
extern void grub_boot_init (void);
/* FIXME: use interrupt to count high. */
grub_uint64_t
@ -210,6 +211,8 @@ grub_machine_init (void)
grub_terminfo_init ();
grub_serial_init ();
grub_boot_init ();
}
void

105
grub-core/lib/cmdline.c Normal file
View file

@ -0,0 +1,105 @@
/* cmdline.c - linux command line handling */
/*
* GRUB -- GRand Unified Bootloader
* Copyright (C) 2010 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GRUB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#include <grub/lib/cmdline.h>
#include <grub/misc.h>
static unsigned int check_arg (char *c, int *has_space)
{
int space = 0;
unsigned int size = 0;
while (*c)
{
if (*c == '\\' || *c == '\'' || *c == '"')
size++;
else if (*c == ' ')
space = 1;
size++;
c++;
}
if (space)
size += 2;
if (has_space)
*has_space = space;
return size;
}
unsigned int grub_loader_cmdline_size (int argc, char *argv[])
{
int i;
unsigned int size = 0;
for (i = 0; i < argc; i++)
{
size += check_arg (argv[i], 0);
size++; /* Separator space or NULL. */
}
return size;
}
int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
grub_size_t size)
{
int i, space;
unsigned int arg_size;
char *c;
for (i = 0; i < argc; i++)
{
c = argv[i];
arg_size = check_arg(argv[i], &space);
arg_size++; /* Separator space or NULL. */
if (size < arg_size)
break;
size -= arg_size;
if (space)
*buf++ = '"';
while (*c)
{
if (*c == '\\' || *c == '\'' || *c == '"')
*buf++ = '\\';
*buf++ = *c;
c++;
}
if (space)
*buf++ = '"';
*buf++ = ' ';
}
/* Replace last space with null. */
if (i)
buf--;
*buf = 0;
return i;
}

View file

@ -0,0 +1 @@
#include <sys/types.h>

View file

@ -32,6 +32,11 @@ typedef grub_uint16_t uint16_t;
typedef grub_uint32_t uint32_t;
typedef grub_uint64_t uint64_t;
typedef grub_int8_t int8_t;
typedef grub_int16_t int16_t;
typedef grub_int32_t int32_t;
typedef grub_int64_t int64_t;
#ifdef GRUB_CPU_WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#else

View file

@ -394,7 +394,7 @@ SUFFIX (grub_netbsd_load_elf_meta) (struct grub_relocator *relocator,
grub_err_t err;
Elf_Ehdr e;
Elf_Shdr *s, *symsh, *strsh;
char *shdr;
char *shdr = NULL;
unsigned symsize, strsize;
void *sym_chunk;
grub_uint8_t *curload;

View file

@ -33,6 +33,7 @@
#include <grub/command.h>
#include <grub/i386/relocator.h>
#include <grub/i18n.h>
#include <grub/lib/cmdline.h>
#ifdef GRUB_MACHINE_PCBIOS
#include <grub/i386/pc/vesa_modes_table.h>
@ -135,7 +136,8 @@ find_efi_mmap_size (void)
later, and EFI itself may allocate more. */
mmap_size += (1 << 12);
return page_align (mmap_size);
mmap_size = page_align (mmap_size);
return mmap_size;
}
#endif
@ -312,6 +314,13 @@ grub_linux_setup_video (struct linux_kernel_params *params)
struct grub_video_mode_info mode_info;
void *framebuffer;
grub_err_t err;
grub_video_driver_id_t driver_id;
char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb");
driver_id = grub_video_get_driver_id ();
if (driver_id == GRUB_VIDEO_DRIVER_NONE)
return 1;
err = grub_video_get_info_and_fini (&mode_info, &framebuffer);
@ -338,12 +347,40 @@ grub_linux_setup_video (struct linux_kernel_params *params)
params->reserved_mask_size = mode_info.reserved_mask_size;
params->reserved_field_pos = mode_info.reserved_field_pos;
if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y'))
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
else
{
switch (driver_id)
{
case GRUB_VIDEO_DRIVER_VBE:
params->lfb_size >>= 16;
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
break;
case GRUB_VIDEO_DRIVER_EFI_UGA:
case GRUB_VIDEO_DRIVER_EFI_GOP:
params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB;
break;
/* FIXME: check if better id is available. */
case GRUB_VIDEO_DRIVER_SM712:
case GRUB_VIDEO_DRIVER_VGA:
case GRUB_VIDEO_DRIVER_CIRRUS:
case GRUB_VIDEO_DRIVER_BOCHS:
/* Make gcc happy. */
case GRUB_VIDEO_DRIVER_SDL:
case GRUB_VIDEO_DRIVER_NONE:
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
break;
}
}
#ifdef GRUB_MACHINE_PCBIOS
/* VESA packed modes may come with zeroed mask sizes, which need
to be set here according to DAC Palette width. If we don't,
this results in Linux displaying a black screen. */
if (mode_info.bpp <= 8)
if (driver_id == GRUB_VIDEO_DRIVER_VBE && mode_info.bpp <= 8)
{
struct grub_vbe_info_block controller_info;
int status;
@ -456,15 +493,7 @@ grub_linux_boot (void)
grub_errno = GRUB_ERR_NONE;
}
if (! grub_linux_setup_video (params))
{
/* Use generic framebuffer unless VESA is known to be supported. */
if (params->have_vga != GRUB_VIDEO_LINUX_TYPE_VESA)
params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE;
else
params->lfb_size >>= 16;
}
else
if (grub_linux_setup_video (params))
{
#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU)
params->have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT;
@ -575,7 +604,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_size_t real_size, prot_size;
grub_ssize_t len;
int i;
char *dest;
grub_dl_ref (my_mod);
@ -771,10 +799,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
break;
}
/* We can't detect VESA, but user is implicitly telling us that it
is built-in because `vga=' parameter was used. */
params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA;
linux_mode = &grub_vesa_mode_table[vid_mode
- GRUB_VESA_MODE_TABLE_START];
@ -836,22 +860,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
params->loadflags |= GRUB_LINUX_FLAG_QUIET;
}
/* 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
&& dest + grub_strlen (argv[i]) + 1 < ((char *) real_mode_mem
+ GRUB_LINUX_CL_END_OFFSET);
i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
/* Create kernel command line. */
grub_memcpy ((char *)real_mode_mem + GRUB_LINUX_CL_OFFSET, LINUX_IMAGE,
sizeof (LINUX_IMAGE));
grub_create_loader_cmdline (argc, argv,
(char *)real_mode_mem + GRUB_LINUX_CL_OFFSET
+ sizeof (LINUX_IMAGE) - 1,
GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
- (sizeof (LINUX_IMAGE) - 1));
len = prot_size;
if (grub_file_read (file, prot_mode_mem, len) != len)

View file

@ -539,6 +539,9 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
mbi->u.elf_sec.shndx = elf_sec_shstrndx;
mbi->flags |= MULTIBOOT_INFO_ELF_SHDR;
ptrorig += elf_sec_entsize * elf_sec_num;
ptrdest += elf_sec_entsize * elf_sec_num;
}
err = retrieve_video_parameters (mbi, ptrorig, ptrdest);
@ -547,6 +550,16 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
}
if ((mbi->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO)
&& mbi->framebuffer_type == MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED)
{
ptrorig += mbi->framebuffer_palette_num_colors
* sizeof (struct multiboot_color);
ptrdest += mbi->framebuffer_palette_num_colors
* sizeof (struct multiboot_color);
}
#if GRUB_MACHINE_HAS_VBE
ptrorig += sizeof (struct grub_vbe_info_block);
ptrdest += sizeof (struct grub_vbe_info_block);

View file

@ -34,6 +34,7 @@
#include <grub/cpu/relocator.h>
#include <grub/video.h>
#include <grub/i386/floppy.h>
#include <grub/lib/cmdline.h>
#define GRUB_LINUX_CL_OFFSET 0x9000
#define GRUB_LINUX_CL_END_OFFSET 0x90FF
@ -86,7 +87,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_size_t real_size;
grub_ssize_t len;
int i;
char *dest;
char *grub_linux_prot_chunk;
int grub_linux_is_bzimage;
grub_addr_t grub_linux_prot_target;
@ -286,21 +286,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
((GRUB_LINUX_MAX_SETUP_SECTS - setup_sects - 1)
<< GRUB_DISK_SECTOR_BITS));
/* Specify the boot file. */
dest = grub_stpcpy (grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET,
"BOOT_IMAGE=");
dest = grub_stpcpy (dest, argv[0]);
/* Copy kernel parameters. */
for (i = 1;
i < argc
&& dest + grub_strlen (argv[i]) + 1 < (grub_linux_real_chunk
+ GRUB_LINUX_CL_END_OFFSET);
i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
/* Create kernel command line. */
grub_memcpy ((char *)grub_linux_real_chunk + GRUB_LINUX_CL_OFFSET,
LINUX_IMAGE, sizeof (LINUX_IMAGE));
grub_create_loader_cmdline (argc, argv,
(char *)grub_linux_real_chunk
+ GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
GRUB_LINUX_CL_END_OFFSET - GRUB_LINUX_CL_OFFSET
- (sizeof (LINUX_IMAGE) - 1));
if (grub_linux_is_bzimage)
grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;

View file

@ -951,10 +951,11 @@ grub_err_t
grub_xnu_boot (void)
{
struct grub_xnu_boot_params *bootparams;
void *bp_in;
grub_addr_t bootparams_target;
grub_err_t err;
grub_efi_uintn_t memory_map_size = 0;
grub_efi_memory_descriptor_t *memory_map;
void *memory_map;
grub_addr_t memory_map_target;
grub_efi_uintn_t map_key = 0;
grub_efi_uintn_t descriptor_size = 0;
@ -1006,9 +1007,10 @@ grub_xnu_boot (void)
/* Relocate the boot parameters to heap. */
err = grub_xnu_heap_malloc (sizeof (*bootparams),
(void **) &bootparams, &bootparams_target);
&bp_in, &bootparams_target);
if (err)
return err;
bootparams = bp_in;
/* Set video. */
err = grub_xnu_set_video (bootparams);
@ -1035,7 +1037,7 @@ grub_xnu_boot (void)
memory map growth. */
memory_map_size += 20 * descriptor_size;
err = grub_xnu_heap_malloc (memory_map_size,
(void **) &memory_map, &memory_map_target);
&memory_map, &memory_map_target);
if (err)
return err;
@ -1109,7 +1111,7 @@ grub_xnu_boot (void)
grub_xnu_arg1 = bootparams_target;
grub_autoefi_set_virtual_address_map (memory_map_size, descriptor_size,
descriptor_version,memory_map);
descriptor_version, memory_map);
state.eip = grub_xnu_entry_point;
state.eax = grub_xnu_arg1;

View file

@ -27,6 +27,7 @@
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/memory.h>
#include <grub/lib/cmdline.h>
#define ELF32_LOADMASK (0xc0000000UL)
#define ELF64_LOADMASK (0xc000000000000000ULL)
@ -151,7 +152,8 @@ grub_linux_load32 (grub_elf_t elf)
Elf32_Addr base_addr;
grub_addr_t seg_addr;
grub_uint32_t align;
int offset;
grub_uint32_t offset;
Elf32_Addr entry;
linux_size = grub_elf32_size (elf, &base_addr, &align);
if (linux_size == 0)
@ -159,9 +161,12 @@ grub_linux_load32 (grub_elf_t elf)
/* Pad it; the kernel scribbles over memory beyond its load address. */
linux_size += 0x100000;
offset = elf->ehdr.ehdr32.e_entry - base_addr;
/* Linux's entry point incorrectly contains a virtual address. */
entry = elf->ehdr.ehdr32.e_entry & ~ELF32_LOADMASK;
/* Linux's incorrectly contains a virtual address. */
base_addr &= ~ELF32_LOADMASK;
offset = entry - base_addr;
/* On some systems, firmware occupies the memory we're trying to use.
* Happily, Linux can be loaded anywhere (it relocates itself). Iterate
@ -195,7 +200,8 @@ grub_linux_load64 (grub_elf_t elf)
Elf64_Addr base_addr;
grub_addr_t seg_addr;
grub_uint64_t align;
int offset;
grub_uint64_t offset;
Elf64_Addr entry;
linux_size = grub_elf64_size (elf, &base_addr, &align);
if (linux_size == 0)
@ -203,9 +209,10 @@ grub_linux_load64 (grub_elf_t elf)
/* Pad it; the kernel scribbles over memory beyond its load address. */
linux_size += 0x100000;
offset = elf->ehdr.ehdr64.e_entry - base_addr;
/* Linux's incorrectly contains a virtual address. */
base_addr &= ~ELF64_LOADMASK;
entry = elf->ehdr.ehdr64.e_entry & ~ELF64_LOADMASK;
offset = entry - base_addr;
/* Linux's incorrectly contains a virtual address. */
/* On some systems, firmware occupies the memory we're trying to use.
* Happily, Linux can be loaded anywhere (it relocates itself). Iterate
@ -238,9 +245,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
int argc, char *argv[])
{
grub_elf_t elf = 0;
int i;
int size;
char *dest;
grub_dl_ref (my_mod);
@ -275,23 +280,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto out;
}
size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]);
for (i = 0; i < argc; i++)
size += grub_strlen (argv[i]) + 1;
linux_args = grub_malloc (size);
size = grub_loader_cmdline_size(argc, argv);
linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
if (! linux_args)
goto out;
/* Specify the boot file. */
dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
dest = grub_stpcpy (dest, argv[0]);
for (i = 1; i < argc; i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
size);
out:

View file

@ -27,6 +27,7 @@
#include <grub/command.h>
#include <grub/i18n.h>
#include <grub/memory.h>
#include <grub/lib/cmdline.h>
static grub_dl_t my_mod;
@ -295,9 +296,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
{
grub_file_t file = 0;
grub_elf_t elf = 0;
int i;
int size;
char *dest;
grub_dl_ref (my_mod);
@ -333,23 +332,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto out;
}
size = sizeof ("BOOT_IMAGE=") + grub_strlen (argv[0]);
for (i = 0; i < argc; i++)
size += grub_strlen (argv[i]) + 1;
size = grub_loader_cmdline_size(argc, argv);
linux_args = grub_malloc (size);
linux_args = grub_malloc (size + sizeof (LINUX_IMAGE));
if (! linux_args)
goto out;
/* Specify the boot file. */
dest = grub_stpcpy (linux_args, "BOOT_IMAGE=");
dest = grub_stpcpy (dest, argv[0]);
for (i = 1; i < argc; i++)
{
*dest++ = ' ';
dest = grub_stpcpy (dest, argv[i]);
}
/* Create kernel command line. */
grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
grub_create_loader_cmdline (argc, argv, linux_args + sizeof (LINUX_IMAGE) - 1,
size);
out:
if (elf)

View file

@ -342,7 +342,8 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
grub_macho_t macho;
grub_uint32_t startcode, endcode;
int i;
char *ptr, *loadaddr;
char *ptr;
void *loadaddr;
grub_addr_t loadaddr_target;
if (argc < 1)
@ -375,7 +376,7 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
if (!grub_xnu_relocator)
return grub_errno;
grub_xnu_heap_target_start = startcode;
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr,
err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr,
&loadaddr_target);
if (err)
@ -386,7 +387,8 @@ grub_cmd_xnu_kernel (grub_command_t cmd __attribute__ ((unused)),
}
/* Load kernel. */
err = grub_macho_load32 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS);
err = grub_macho_load32 (macho, (char *) loadaddr - startcode,
GRUB_MACHO_NOBSS);
if (err)
{
grub_macho_close (macho);
@ -450,7 +452,8 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
grub_macho_t macho;
grub_uint64_t startcode, endcode;
int i;
char *ptr, *loadaddr;
char *ptr;
void *loadaddr;
grub_addr_t loadaddr_target;
if (argc < 1)
@ -486,7 +489,7 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
if (!grub_xnu_relocator)
return grub_errno;
grub_xnu_heap_target_start = startcode;
err = grub_xnu_heap_malloc (endcode - startcode, (void **) &loadaddr,
err = grub_xnu_heap_malloc (endcode - startcode, &loadaddr,
&loadaddr_target);
if (err)
@ -497,7 +500,8 @@ grub_cmd_xnu_kernel64 (grub_command_t cmd __attribute__ ((unused)),
}
/* Load kernel. */
err = grub_macho_load64 (macho, loadaddr - startcode, GRUB_MACHO_NOBSS);
err = grub_macho_load64 (macho, (char *) loadaddr - startcode,
GRUB_MACHO_NOBSS);
if (err)
{
grub_macho_close (macho);
@ -636,7 +640,8 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
grub_file_t infoplist;
struct grub_xnu_extheader *exthead;
int neededspace = sizeof (*exthead);
grub_uint8_t *buf, *buf0;
grub_uint8_t *buf;
void *buf0;
grub_addr_t buf_target;
grub_size_t infoplistsize = 0, machosize = 0;
char *name, *nameend;
@ -692,7 +697,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
err = grub_xnu_align_heap (GRUB_XNU_PAGESIZE);
if (err)
return err;
err = grub_xnu_heap_malloc (neededspace, (void **) &buf0, &buf_target);
err = grub_xnu_heap_malloc (neededspace, &buf0, &buf_target);
if (err)
return err;
buf = buf0;
@ -704,7 +709,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
/* Load the binary. */
if (macho)
{
exthead->binaryaddr = buf_target + (buf - buf0);
exthead->binaryaddr = buf_target + (buf - (grub_uint8_t *) buf0);
exthead->binarysize = machosize;
if (grub_xnu_is_64bit)
err = grub_macho_readfile64 (macho, buf);
@ -723,7 +728,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
/* Load the plist. */
if (infoplist)
{
exthead->infoplistaddr = buf_target + (buf - buf0);
exthead->infoplistaddr = buf_target + (buf - (grub_uint8_t *) buf0);
exthead->infoplistsize = infoplistsize + 1;
if (grub_file_read (infoplist, buf, infoplistsize)
!= (grub_ssize_t) (infoplistsize))
@ -739,7 +744,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile)
}
grub_errno = GRUB_ERR_NONE;
exthead->nameaddr = (buf - buf0) + buf_target;
exthead->nameaddr = (buf - (grub_uint8_t *) buf0) + buf_target;
exthead->namesize = namelen + 1;
grub_memcpy (buf, name, namelen);
buf[namelen] = 0;

View file

@ -148,7 +148,7 @@ grub_env_context_close (void)
grub_err_t
grub_env_extractor_close (int source)
{
grub_menu_t menu, menu2;
grub_menu_t menu = NULL;
grub_menu_entry_t *last;
grub_err_t err;
@ -161,6 +161,7 @@ grub_env_extractor_close (int source)
if (source)
{
grub_menu_t menu2;
menu2 = grub_env_get_menu ();
last = &menu2->entry_list;
@ -175,26 +176,6 @@ grub_env_extractor_close (int source)
return err;
}
grub_err_t
grub_env_export (const char *name)
{
struct grub_env_var *var;
var = grub_env_find (name);
if (! var)
{
grub_err_t err;
err = grub_env_set (name, "");
if (err)
return err;
var = grub_env_find (name);
}
var->global = 1;
return GRUB_ERR_NONE;
}
static grub_command_t export_cmd;
static grub_err_t
@ -216,9 +197,6 @@ grub_cmd_export (struct grub_command *cmd __attribute__ ((unused)),
void
grub_context_init (void)
{
grub_env_export ("root");
grub_env_export ("prefix");
export_cmd = grub_register_command ("export", grub_cmd_export,
N_("ENVVAR [ENVVAR] ..."),
N_("Export variables."));

View file

@ -287,7 +287,7 @@ grub_normal_execute (const char *config, int nested, int batch)
{
if (menu && menu->size)
{
grub_show_menu (menu, nested);
grub_show_menu (menu, nested, 0);
if (nested)
grub_normal_free_menu (menu);
}

View file

@ -154,12 +154,15 @@ get_and_remove_first_entry_number (const char *name)
}
/* Run a menu entry. */
void
grub_menu_execute_entry(grub_menu_entry_t entry)
static void
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{
grub_err_t err = GRUB_ERR_NONE;
int errs_before;
grub_menu_t menu;
grub_menu_t menu = NULL;
char *optr, *buf, *oldchosen = NULL, *olddefault = NULL;
const char *ptr, *chosen, *def;
grub_size_t sz = 0;
if (entry->restricted)
err = grub_auth_check_authentication (entry->users);
@ -173,6 +176,9 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
errs_before = grub_err_printed_errors;
chosen = grub_env_get ("chosen");
def = grub_env_get ("default");
if (entry->submenu)
{
grub_env_context_open ();
@ -180,9 +186,64 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
if (! menu)
return;
grub_env_set_menu (menu);
if (auto_boot)
grub_env_set ("timeout", "0");
}
grub_env_set ("chosen", entry->title);
for (ptr = entry->title; *ptr; ptr++)
sz += (*ptr == '>') ? 2 : 1;
if (chosen)
{
oldchosen = grub_strdup (chosen);
if (!oldchosen)
grub_print_error ();
}
if (def)
{
olddefault = grub_strdup (def);
if (!olddefault)
grub_print_error ();
}
sz++;
if (chosen)
sz += grub_strlen (chosen);
sz++;
buf = grub_malloc (sz);
if (!buf)
grub_print_error ();
else
{
optr = buf;
if (chosen)
{
optr = grub_stpcpy (optr, chosen);
*optr++ = '>';
}
for (ptr = entry->title; *ptr; ptr++)
{
if (*ptr == '>')
*optr++ = '>';
*optr++ = *ptr;
}
*optr = 0;
grub_env_set ("chosen", buf);
grub_env_export ("chosen");
grub_free (buf);
}
for (ptr = def; *ptr; ptr++)
{
if (ptr[0] == '>' && ptr[1] == '>')
{
ptr++;
continue;
}
if (ptr[0] == '>')
break;
}
if (ptr[0] && ptr[1])
grub_env_set ("default", ptr + 1);
else
grub_env_unset ("default");
grub_script_execute_sourcecode (entry->sourcecode, entry->argc, entry->args);
if (errs_before != grub_err_printed_errors)
@ -196,20 +257,30 @@ grub_menu_execute_entry(grub_menu_entry_t entry)
{
if (menu && menu->size)
{
grub_show_menu (menu, 1);
grub_show_menu (menu, 1, auto_boot);
grub_normal_free_menu (menu);
}
grub_env_context_close ();
}
if (oldchosen)
grub_env_set ("chosen", oldchosen);
else
grub_env_unset ("chosen");
if (olddefault)
grub_env_set ("default", olddefault);
else
grub_env_unset ("default");
grub_env_unset ("timeout");
}
/* Execute ENTRY from the menu MENU, falling back to entries specified
in the environment variable "fallback" if it fails. CALLBACK is a
pointer to a struct of function pointers which are used to allow the
caller provide feedback to the user. */
void
static void
grub_menu_execute_with_fallback (grub_menu_t menu,
grub_menu_entry_t entry,
int autobooted,
grub_menu_execute_callback_t callback,
void *callback_data)
{
@ -217,7 +288,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
callback->notify_booting (entry, callback_data);
grub_menu_execute_entry (entry);
grub_menu_execute_entry (entry, 1);
/* Deal with fallback entries. */
while ((fallback_entry = get_and_remove_first_entry_number ("fallback"))
@ -228,14 +299,15 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
entry = grub_menu_get_entry (menu, fallback_entry);
callback->notify_fallback (entry, callback_data);
grub_menu_execute_entry (entry);
grub_menu_execute_entry (entry, 1);
/* If the function call to execute the entry returns at all, then this is
taken to indicate a boot failure. For menu entries that do something
other than actually boot an operating system, this could assume
incorrectly that something failed. */
}
callback->notify_failure (callback_data);
if (!autobooted)
callback->notify_failure (callback_data);
}
static struct grub_menu_viewer *viewers;
@ -309,11 +381,35 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer)
viewers = viewer;
}
static int
menuentry_eq (const char *title, const char *spec)
{
const char *ptr1, *ptr2;
ptr1 = title;
ptr2 = spec;
while (1)
{
if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0)
return 1;
if (*ptr2 == '>' && ptr2[1] != '>')
return 0;
if (*ptr2 == '>')
ptr2++;
if (*ptr1 != *ptr2)
return 0;
if (*ptr1 == 0)
return 1;
ptr1++;
ptr2++;
}
}
/* Get the entry number from the variable NAME. */
static int
get_entry_number (grub_menu_t menu, const char *name)
{
char *val;
const char *val;
int entry;
val = grub_env_get (name);
@ -334,7 +430,7 @@ get_entry_number (grub_menu_t menu, const char *name)
for (i = 0; e; i++)
{
if (grub_strcmp (e->title, val) == 0)
if (menuentry_eq (e->title, val))
{
entry = i;
break;
@ -590,7 +686,7 @@ static struct grub_menu_execute_callback execution_callback =
};
static grub_err_t
show_menu (grub_menu_t menu, int nested)
show_menu (grub_menu_t menu, int nested, int autobooted)
{
while (1)
{
@ -609,22 +705,26 @@ show_menu (grub_menu_t menu, int nested)
grub_cls ();
if (auto_boot)
grub_menu_execute_with_fallback (menu, e, &execution_callback, 0);
grub_menu_execute_with_fallback (menu, e, autobooted,
&execution_callback, 0);
else
grub_menu_execute_entry (e);
grub_menu_execute_entry (e, 0);
if (autobooted)
break;
}
return GRUB_ERR_NONE;
}
grub_err_t
grub_show_menu (grub_menu_t menu, int nested)
grub_show_menu (grub_menu_t menu, int nested, int autoboot)
{
grub_err_t err1, err2;
while (1)
{
err1 = show_menu (menu, nested);
err1 = show_menu (menu, nested, autoboot);
autoboot = 0;
grub_print_error ();
if (grub_normal_exit_level)

View file

@ -1227,7 +1227,7 @@ run (struct screen *screen)
{
if (menu && menu->size)
{
grub_show_menu (menu, 1);
grub_show_menu (menu, 1, 0);
grub_normal_free_menu (menu);
}
grub_env_context_close ();

View file

@ -26,7 +26,7 @@
#include <grub/msdos_partition.h>
#ifdef GRUB_UTIL
#include <grub/util/misc.h>
#include <grub/emu/misc.h>
#endif
static struct grub_partition_map grub_bsdlabel_partition_map;
@ -101,7 +101,8 @@ iterate_real (grub_disk_t disk, grub_disk_addr_t sector, int freebsd,
#ifdef GRUB_UTIL
char *partname;
/* disk->partition != NULL as 0 < delta */
partname = grub_partition_get_name (disk->partition);
partname = disk->partition ? grub_partition_get_name (disk->partition)
: "";
grub_util_warn ("Discarding improperly nested partition (%s,%s,%s%d)",
disk->name, partname, p.partmap->name, p.number + 1);
grub_free (partname);

View file

@ -271,14 +271,14 @@ pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
break;
}
if (end >= *nsectors + 1)
if (end >= *nsectors + 2)
{
int i, j;
unsigned i, j;
char *embed_signature_check;
unsigned int orig_nsectors;
orig_nsectors = *nsectors;
*nsectors = end - 1;
*nsectors = end - 2;
*sectors = grub_malloc (*nsectors * sizeof (**sectors));
if (!*sectors)
return grub_errno;

View file

@ -25,6 +25,8 @@
static unsigned
round_up_exp (unsigned v)
{
COMPILE_TIME_ASSERT (sizeof (v) == 4);
v--;
v |= v >> 1;
v |= v >> 2;
@ -32,9 +34,6 @@ round_up_exp (unsigned v)
v |= v >> 8;
v |= v >> 16;
if (sizeof (v) > 4)
v |= v >> 32;
v++;
v += (v == 0);

View file

@ -494,7 +494,7 @@ static int
grub_keyboard_getkey (void)
{
int key;
int is_break;
int is_break = 0;
key = fetch_key (&is_break);
if (key == -1)