+2006-06-04 Yoshinori K. Okuji <okuji@enbug.org>
+
+ Clean up the code to support 64-bit addressing in disks and
+ files. This change is not enough for filesystems yet.
+
+ * util/i386/pc/grub-setup.c (struct boot_blocklist): Change the
+ type of "start" to grub_uint64_t.
+ (setup): Change the types of KERNEL_SECTOR and FIRST_SECTOR to
+ grub_disk_addr_t * and grub_disk_addr_t. Fix the format string in
+ save_first_sector and save_blocklists. Use grub_le_to_cpu64 to
+ convert addresses.
+
+ * util/i386/pc/biosdisk.c (open_device): Change the type of SECTOR
+ to grub_disk_addr_t.
+
+ * partmap/gpt.c (gpt_partition_map_iterate): Fix the format
+ string.
+
+ * partmap/pc.c (pc_partition_map_iterate): Likewise.
+
+ * partmap/amiga.c (amiga_partition_map_iterate): Cast RDSK.MAGIC
+ to char *.
+
+ * normal/script.c (grub_script_parse): Remove unused MEMFREE.
+
+ * normal/parser.y (YYLTYPE_IS_TRIVIAL): New macro.
+
+ * normal/lexer.c (grub_script_yyerror): Specify unused to LEX.
+
+ * loader/i386/pc/multiboot.c (grub_multiboot_load_elf64): Cast -1
+ to grub_off_t, to detect an error from grub_file_seek.
+ (grub_multiboot_load_elf32): Likewise.
+
+ * kern/misc.c (grub_strtoul): Use grub_strtoull. Return the
+ maximum unsigned long value when an overflow is detected.
+ (grub_strtoull): New function.
+ (grub_divmod64): Likewise.
+ (grub_lltoa): use grub_divmod64.
+
+ * kern/fs.c (struct grub_fs_block): Change the type of "offset" to
+ grub_disk_addr_t.
+ (grub_fs_blocklist_open): Increase P if P is not NULL to advance
+ the pointer to next character. Use grub_strtoull instead of
+ grub_strtoul.
+ (grub_fs_blocklist_read): Change the types of SECTOR, OFFSET and
+ SIZE to grub_disk_addr_t, grub_off_t and grub_size_t,
+ respectively.
+
+ * kern/file.c (grub_file_read): Prevent an oveflow of LEN, as the
+ return value is signed.
+ (grub_file_seek): Change the type of OLD to grub_off_t. Do not
+ test if OFFSET is less than zero, as OFFSET is unsigned now.
+
+ * kern/disk.c (struct grub_disk_cache): Change the type of
+ "sector" to grub_disk_addr_t.
+ (grub_disk_cache_get_index): Change the type of SECTOR to
+ grub_disk_addr_t. Calculate the hash with SECTOR casted to
+ unsigned after shifting.
+ (grub_disk_cache_invalidate): Change the type of SECTOR to
+ grub_disk_addr_t.
+ (grub_disk_cache_unlock): Likewise.
+ (grub_disk_cache_store): Likewise.
+ (grub_disk_check_range): Change the types of SECTOR, OFFSET, SIZE,
+ START and LEN to grub_disk_addr_t *, grub_off_t *, grub_size_t,
+ grub_disk_addr_t and grub_uint64_t, respectively.
+ (grub_disk_read): Use an unsigned variable REAL_OFFSET for the
+ body, as the value of OFFSET is tweaked by
+ grub_disk_check_range. Change the types of START_SECTOR, LEN and
+ POS to grub_disk_addr_t, grub_size_t and grub_size_t,
+ respectively.
+ (grub_disk_write): Use an unsigned variable REAL_OFFSET for the
+ body, as the value of OFFSET is tweaked by
+ grub_disk_check_range. Change the types of LEN and N to
+ grub_size_t.
+
+ * io/gzio.c (struct grub_gzio): Change the types of "data_offset"
+ and "saved_offset" to grub_off_t.
+ (test_header): Cast BUF to char *.
+ (get_byte): Cast GZIO->DATA_OFFSET to grub_off_t. Cast GZIO->INBUF
+ to char *.
+ (grub_gzio_read): Change the types of OFFSET and SIZE to
+ grub_off_t and grub_size_t, respectively.
+
+ * include/grub/i386/pc/boot.h (GRUB_BOOT_MACHINE_FORCE_LBA):
+ Removed.
+ (GRUB_BOOT_MACHINE_BOOT_DRIVE): Changed to 0x4c.
+ (GRUB_BOOT_MACHINE_KERNEL_ADDRESS): Changed to 0x40.
+ (GRUB_BOOT_MACHINE_KERNEL_SEGMENT): Changed to 0x42.
+ (GRUB_BOOT_MACHINE_DRIVE_CHECK): Changed to 0x4e.
+ (GRUB_BOOT_MACHINE_LIST_SIZE): Increased to 12.
+
+ * include/grub/types.h (grub_off_t): Unconditionally set to
+ grub_uint64_t.
+ (grub_disk_addr_t): Changed to grub_uint64_t.
+
+ * include/grub/partition.h (struct grub_partition): Change the
+ types of "start", "len" and "offset" to grub_disk_addr_t,
+ grub_uint64_t and grub_disk_addr_t, respectively.
+ (grub_partition_get_start): Return grub_disk_addr_t.
+ (grub_partition_get_len): Return grub_uint64_t.
+
+ * include/grub/misc.h (grub_strtoull): New prototype.
+ (grub_divmod64): Likewise.
+
+ * include/grub/fshelp.h (grub_fshelp_read_file): Change the types
+ of SECTOR, LEN and FILESIZE to grub_disk_addr_t, grub_size_t and
+ grub_off_t, respectively.
+ All callers and references changed.
+
+ * include/grub/fs.h (struct grub_fs): Change the type of LEN to
+ grub_size_t in "read".
+ All callers and references changed.
+
+ * include/grub/file.h (struct grub_file): Change the types of
+ "offset" and "size" to grub_off_t and grub_off_t,
+ respectively. Change the type of SECTOR to grub_disk_addr_t in
+ "read_hook".
+ (grub_file_read): Change the type of LEN to grub_size_t.
+ (grub_file_seek): Return grub_off_t. Change the type of OFFSET to
+ grub_off_t.
+ (grub_file_size): Return grub_off_t.
+ (grub_file_tell): Likewise.
+ All callers and references changed.
+
+ * include/grub/disk.h (struct grub_disk_dev): Change the types of
+ SECTOR and SIZE to grub_disk_addr_t and grub_size_t in "read" and
+ "write".
+ (struct grub_disk): Change the type of "total_sectors" to
+ grub_uint64_t. Change the type of SECTOR to grub_disk_addr_t in
+ "read_hook".
+ (grub_disk_read): Change the types of SECTOR, OFFSET and SIZE to
+ grub_disk_addr_t, grub_off_t and grub_size_t, respectively.
+ (grub_disk_write): Likewise.
+ All callers and references changed.
+
+ * fs/iso9660.c (grub_iso9660_susp_iterate): Cast parameters to
+ char * for grub_strncmp to silence gcc.
+ (grub_iso9660_mount): Likewise.
+ (grub_iso9660_mount): Likewise.
+ (grub_iso9660_read_symlink): Likewise. Also, remove the nonsense
+ return statement.
+ (grub_iso9660_iterate_dir): Likewise.
+ (grub_iso9660_label): Cast DATA->VOLDESC.VOLNAME to char *.
+
+ * fs/hfs.c (grub_hfs_read_file): Change the types of SECTOR and
+ LEN to grub_disk_addr_t and grub_size_t, respectively.
+
+ * fs/hfsplus.c (grub_hfsplus_read_file): Likewise.
+
+ * fs/jfs.c (grub_jfs_read_file): Likewise.
+
+ * fs/minix.c (grub_jfs_read_file): Likewise.
+
+ * fs/sfs.c (grub_jfs_read_file): Likewise.
+
+ * fs/ufs.c (grub_jfs_read_file): Likewise.
+
+ * fs/xfs.c (grub_jfs_read_file): Likewise.
+
+ * fs/fat.c (grub_fat_read_data): Change the types of SECTOR, LEN
+ and SIZE to grub_disk_addr_t, grub_size_t and grub_size_t,
+ respectively.
+
+ * fs/ext2.c (grub_ext2_read_block): When an error happens, set
+ BLKNR to -1 instead of returning GRUB_ERRNO.
+ (grub_ext2_read_file): Change the types of SECTOR and
+ LEN to grub_disk_addr_t and grub_size_t, respectively.
+
+ * fs/affs.c (grub_affs_read_file): Change the types of SECTOR and
+ LEN to grub_disk_addr_t and grub_size_t, respectively.
+
+ * font/manager.c (grub_font_get_glyph): Cast BITMAP to char * for
+ grub_file_read.
+
+ * disk/ieee1275/ofdisk.c (grub_ofdisk_read): Fix the format
+ string. Do not cast SECTOR explicitly.
+
+ * disk/i386/pc/biosdisk.c (grub_biosdisk_open): Change the type of
+ TOTAL_SECTORS to grub_uint64_t. Do not mask DRP->TOTAL_SECTORS.
+ (grub_biosdisk_rw): Change the types of SECTOR and SIZE to
+ grub_disk_addr_t and grub_size_t, respectively. If the sector is
+ over 2TB and LBA mode is not supported, raise an error.
+ (get_safe_sectors): New function.
+ (grub_biosdisk_read): Use get_safe_sectors.
+ (grub_biosdisk_write): Likewise.
+
+ * disk/efi/efidisk.c (grub_efidisk_read): Fix the format string.
+ (grub_efidisk_write): Likewise.
+
+ * disk/loopback.c (delete_loopback): Cosmetic changes.
+ (grub_cmd_loopback): Likewise. Also, test NEWDEV->FILENAME
+ correctly.
+ (grub_loopback_open): Likewise.
+ (grub_loopback_read): Likewise. Also, change the type of POS to
+ grub_off_t, and fix the usage of grub_memset.
+
+ * commands/i386/pc/play.c: Include grub/machine/time.h.
+
+ * commands/ls.c (grub_ls_list_files): Use "llu" instead of "d" to
+ print FILE->SIZE.
+
+ * commands/configfile.c: Include grub/env.h.
+
+ * commands/cmp.c (grub_cmd_cmp): Do not use ERR, but use
+ GRUB_ERRNO directly instead. Change the type of POS to
+ grub_off_t. Follow the coding standard.
+
+ * commands/blocklist.c: Include grub/partition.h.
+ (grub_cmd_blocklist): Return an error if the underlying device is
+ not a disk. Take the starting sector of a partition into account,
+ if a partition is used.
+
+ * boot/i386/pc/diskboot.S (bootloop): Adapted to the new offset of
+ a length field.
+ (lba_mode): Support 64-bit addresses.
+ (chs_mode): Likewise.
+ (copy_buffer): Adapted to the new offsets of a length field and a
+ segment field.
+ (blocklist_default_start): Allocate 64-bit space.
+
+ * boot/i386/pc/boot.S (force_lba): Removed.
+ (boot_drive): Moved to under KERNEL_SECTOR.
+ (kernel_sector): Moved to under KENREL_SEGMENT. Allocate 64-bit
+ space.
+ (real_start): Set %si earlier. Remove code for FORCE_LBA, since it
+ is useless.
+ (lba_mode): Refactored to support a 64-bit address. More size
+ optimization.
+ (setup_sectors): Likewise.
+
2006-06-04 Yoshinori K. Okuji <okuji@enbug.org>
* DISTLIST: Added include/grub/i386/linux.h. Removed
/* -*-Asm-*- */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2005 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
boot_version:
.byte GRUB_BOOT_VERSION_MAJOR, GRUB_BOOT_VERSION_MINOR
-boot_drive:
- .byte 0xff /* the disk to load kernel from */
- /* 0xff means use the boot drive */
-force_lba:
- .byte 0
kernel_address:
.word GRUB_BOOT_MACHINE_KERNEL_ADDR
-kernel_sector:
- .long 1
kernel_segment:
.word GRUB_BOOT_MACHINE_KERNEL_SEG
+kernel_sector:
+ .long 1, 0
+boot_drive:
+ .byte 0xff /* the disk to load kernel from */
+ /* 0xff means use the boot drive */
after_BPB:
/* print a notification message on the screen */
MSG(notification_string)
+ /* set %si to the disk address packet */
+ movw $ABS(disk_address_packet), %si
+
/* do not probe LBA if the drive is a floppy */
testb $GRUB_BOOT_MACHINE_BIOS_HD_FLAG, %dl
jz chs_mode
cmpw $0xaa55, %bx
jne chs_mode
- /* set %si to the disk address packet */
- movw $ABS(disk_address_packet), %si
-
- /* check if AH=0x42 is supported if FORCE_LBA is zero */
- MOV_MEM_TO_AL(ABS(force_lba)) /* movb ABS(force_lba), %al */
- testb %al, %al
- jnz lba_mode
andw $1, %cx
jz chs_mode
lba_mode:
- xorl %eax, %eax
+ xorw %ax, %ax
movw %ax, 4(%si)
- movl %eax, 12(%si)
incw %ax
/* set the mode to non-zero */
movb %al, -1(%si)
- movl ABS(kernel_sector), %ebx
+ /* the blocks */
+ movw %ax, 2(%si)
/* the size and the reserved byte */
movw $0x0010, (%si)
- /* the blocks */
- movw %ax, 2(%si)
-
- /* the absolute address (low 32 bits) */
+ /* the absolute address */
+ movl ABS(kernel_sector), %ebx
movl %ebx, 8(%si)
+ movl ABS(kernel_sector + 4), %ebx
+ movl %ebx, 12(%si)
/* the segment of buffer address */
movw $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
final_init:
/* set the mode to zero */
- movb $0, -1(%si)
+ movzbl %dh, %eax
+ movb %ah, -1(%si)
/* save number of heads */
- xorl %eax, %eax
- movb %dh, %al
incw %ax
movl %eax, 4(%si)
- xorw %dx, %dx
- movb %cl, %dl
+ movzbw %cl, %dx
shlw $2, %dx
movb %ch, %al
movb %dh, %ah
incw %ax
movw %ax, 8(%si)
- xorw %ax, %ax
- movb %dl, %al
+ movzbw %dl, %ax
shrb $2, %al
/* save number of sectors */
movl %eax, (%si)
setup_sectors:
+ /* load logical sector start (top half) */
+ movl ABS(kernel_sector + 4), %eax
+ orl %eax, %eax
+ jnz geometry_error
+
/* load logical sector start (bottom half) */
movl ABS(kernel_sector), %eax
divl (%si)
/* save sector start */
- movb %dl, 10(%si)
+ movb %dl, %cl
- xorl %edx, %edx /* zero %edx */
+ xorw %dx, %dx /* zero %edx */
divl 4(%si) /* divide by number of heads */
- /* save head start */
- movb %dl, 11(%si)
-
- /* save cylinder start */
- movw %ax, 12(%si)
-
/* do we need too many cylinders? */
cmpw 8(%si), %ax
jge geometry_error
-/*
- * This is the loop for taking care of BIOS geometry translation (ugh!)
- */
+ /* normalize sector start (1-based) */
+ incb %cl
- /* get high bits of cylinder */
- movb 13(%si), %dl
+ /* low bits of cylinder start */
+ movb %al, %ch
- shlb $6, %dl /* shift left by 6 bits */
- movb 10(%si), %cl /* get sector */
+ /* high bits of cylinder start */
+ xorb %al, %al
+ shrw $2, %ax
+ orb %al, %cl
- incb %cl /* normalize sector (sectors go
- from 1-N, not 0-(N-1) ) */
- orb %dl, %cl /* composite together */
- movb 12(%si), %ch /* sector+hcyl in cl, cylinder in ch */
+ /* save head start */
+ movb %dl, %al
- /* restore %dx */
+ /* restore %dl */
popw %dx
-
- /* head number */
- movb 11(%si), %dh
+
+ /* head start */
+ movb %al, %dh
/*
* BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
bootloop:
/* check the number of sectors to read */
- cmpw $0, 4(%di)
+ cmpw $0, 8(%di)
/* if zero, go to the start function */
je bootit
lba_mode:
/* load logical sector start */
movl (%di), %ebx
+ movl 4(%di), %ecx
/* the maximum is limited to 0x7f because of Phoenix EDD */
xorl %eax, %eax
movb $0x7f, %al
/* how many do we really want to read? */
- cmpw %ax, 4(%di) /* compare against total number of sectors */
+ cmpw %ax, 8(%di) /* compare against total number of sectors */
/* which is greater? */
jg 1f
/* if less than, set to total */
- movw 4(%di), %ax
+ movw 8(%di), %ax
1:
/* subtract from total */
- subw %ax, 4(%di)
+ subw %ax, 8(%di)
/* add into logical sector start */
addl %eax, (%di)
+ adcl $0, 4(%di)
/* set up disk address packet */
/* the number of sectors */
movw %ax, 2(%si)
- /* the absolute address (low 32 bits) */
+ /* the absolute address */
movl %ebx, 8(%si)
+ movl %ecx, 12(%si)
/* the segment of buffer address */
movw $GRUB_BOOT_MACHINE_BUFFER_SEG, 6(%si)
/* save %ax from destruction! */
pushw %ax
- /* zero %eax */
- xorl %eax, %eax
-
/* the offset of buffer address */
- movw %ax, 4(%si)
-
- /* the absolute address (high 32 bits) */
- movl %eax, 12(%si)
-
+ movw $0, 4(%si)
/*
* BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
jmp copy_buffer
chs_mode:
+ /* load logical sector start (top half) */
+ movl 4(%di), %eax
+ orl %eax, %eax
+ jnz geometry_error
+
/* load logical sector start (bottom half) */
movl (%di), %eax
subb 10(%si), %al
/* how many do we really want to read? */
- cmpw %ax, 4(%di) /* compare against total number of sectors */
+ cmpw %ax, 8(%di) /* compare against total number of sectors */
/* which is greater? */
jg 2f
/* if less than, set to total */
- movw 4(%di), %ax
+ movw 8(%di), %ax
2:
/* subtract from total */
- subw %ax, 4(%di)
+ subw %ax, 8(%di)
/* add into logical sector start */
addl %eax, (%di)
+ adcl $0, 4(%di)
/*
* This is the loop for taking care of BIOS geometry translation (ugh!)
copy_buffer:
/* load addresses for copy from disk buffer to destination */
- movw 6(%di), %es /* load destination segment */
+ movw 10(%di), %es /* load destination segment */
/* restore %ax */
popw %ax
/* determine the next possible destination address (presuming
512 byte sectors!) */
shlw $5, %ax /* shift %ax five bits to the left */
- addw %ax, 6(%di) /* add the corrected value to the destination
+ addw %ax, 10(%di) /* add the corrected value to the destination
address for next time */
/* save addressing regs */
popa
/* check if finished with this dataset */
- cmpw $0, 4(%di)
+ cmpw $0, 8(%di)
jne setup_sectors
/* update position to load from */
blocklist_default_start:
/* this is the sector start parameter, in logical sectors from
the start of the disk, sector 0 */
- .long 2
+ .long 2, 0
blocklist_default_len:
/* this is the number of sectors to read the command "install"
will fill this up */
#include <grub/file.h>
#include <grub/mm.h>
#include <grub/disk.h>
+#include <grub/partition.h>
static grub_err_t
grub_cmd_blocklist (struct grub_arg_list *state __attribute__ ((unused)),
unsigned long start_sector = 0;
unsigned num_sectors = 0;
int num_entries = 0;
- auto void read_blocklist (unsigned long sector, unsigned offset,
+ grub_disk_addr_t part_start = 0;
+ auto void read_blocklist (grub_disk_addr_t sector, unsigned offset,
unsigned length);
- auto void print_blocklist (unsigned long sector, unsigned num,
+ auto void print_blocklist (grub_disk_addr_t sector, unsigned num,
unsigned offset, unsigned length);
- void read_blocklist (unsigned long sector, unsigned offset,
+ void read_blocklist (grub_disk_addr_t sector, unsigned offset,
unsigned length)
{
if (num_sectors > 0)
print_blocklist (sector, 0, offset, length);
}
- void print_blocklist (unsigned long sector, unsigned num,
+ void print_blocklist (grub_disk_addr_t sector, unsigned num,
unsigned offset, unsigned length)
{
if (num_entries++)
grub_printf (",");
- grub_printf ("%lu", sector);
+ grub_printf ("%llu", sector - part_start);
if (num > 0)
grub_printf ("+%u", num);
if (offset != 0 || length != 0)
if (! file)
return grub_errno;
+ if (! file->device->disk)
+ return grub_error (GRUB_ERR_BAD_DEVICE,
+ "this command is available only for disk devices.");
+
+ 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)
/* cmd.c - command to cmp an operating system */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003,2005 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2005,2006 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
grub_cmd_cmp (struct grub_arg_list *state __attribute__ ((unused)),
int argc, char **args)
{
- grub_err_t err;
grub_ssize_t rd1, rd2;
- grub_uint32_t pos;
+ grub_off_t pos;
grub_file_t file1 = 0;
grub_file_t file2 = 0;
char *buf1 = 0;
grub_printf ("Compare `%s' and `%s':\n", args[0],
args[1]);
- if (! (file1 = grub_gzfile_open (args[0], 1) ) ||
- ! (file2 = grub_gzfile_open (args[1], 1) ) )
+ file1 = grub_gzfile_open (args[0], 1);
+ file2 = grub_gzfile_open (args[1], 1);
+ if (! file1 || ! file2)
goto cleanup;
if (grub_file_size (file1) != grub_file_size (file2))
- grub_printf ("Differ in size: %d [%s], %d [%s]\n",
+ grub_printf ("Differ in size: %llu [%s], %llu [%s]\n",
grub_file_size (file1), args[0],
grub_file_size (file2), args[1]);
-
else
{
pos = 0;
- if (! (buf1 = (char *) grub_malloc (BUFFER_SIZE) ) ||
- ! (buf2 = (char *) grub_malloc (BUFFER_SIZE) ) )
+ 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);
{
if (buf1[i] != buf2[i])
{
- grub_printf ("Differ at the offset %d: 0x%x [%s], 0x%x [%s]\n",
+ grub_printf ("Differ at the offset %llu: 0x%x [%s], 0x%x [%s]\n",
i + pos, buf1[i], args[0],
buf2[i], args[1]);
goto cleanup;
}
pos += BUFFER_SIZE;
- } while (rd2);
+ }
+ while (rd2);
+
grub_printf ("The files are identical.\n");
}
cleanup:
- err=grub_errno;
+
if (buf1)
grub_free (buf1);
if (buf2)
if (file2)
grub_file_close (file2);
- return err;
+ return grub_errno;
}
\f
#include <grub/arg.h>
#include <grub/term.h>
#include <grub/misc.h>
+#include <grub/env.h>
static grub_err_t
grub_cmd_configfile (struct grub_arg_list *state __attribute__ ((unused)),
#include <grub/disk.h>
#include <grub/term.h>
#include <grub/misc.h>
+#include <grub/machine/time.h>
#define BASE_TEMPO 120
}
if (! human)
- grub_printf ("%-12d", file->size);
+ grub_printf ("%-12llu", file->size);
else
{
float fsize = file->size;
grub_printf ("%-12s", buf);
}
else
- grub_printf ("%-12d", file->size);
+ grub_printf ("%-12llu", file->size);
}
grub_file_close (file);
}
static grub_err_t
-grub_efidisk_read (struct grub_disk *disk, unsigned long sector,
- unsigned long size, char *buf)
+grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
+ grub_size_t size, char *buf)
{
/* For now, use the disk io interface rather than the block io's. */
struct grub_efidisk_data *d;
dio = d->disk_io;
bio = d->block_io;
- grub_dprintf ("efidisk", "reading 0x%lx sectors at the sector 0x%lx from %s\n",
+ grub_dprintf ("efidisk",
+ "reading 0x%x sectors at the sector 0x%llx from %s\n",
size, sector, disk->name);
status = dio->read (dio, bio->media->media_id,
}
static grub_err_t
-grub_efidisk_write (struct grub_disk *disk, unsigned long sector,
- unsigned long size, const char *buf)
+grub_efidisk_write (struct grub_disk *disk, grub_disk_addr_t sector,
+ grub_size_t size, const char *buf)
{
/* For now, use the disk io interface rather than the block io's. */
struct grub_efidisk_data *d;
dio = d->disk_io;
bio = d->block_io;
- grub_dprintf ("efidisk", "writing 0x%lx sectors at the sector 0x%lx to %s\n",
+ grub_dprintf ("efidisk",
+ "writing 0x%x sectors at the sector 0x%llx to %s\n",
size, sector, disk->name);
status = dio->write (dio, bio->media->media_id,
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006 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
static grub_err_t
grub_biosdisk_open (const char *name, grub_disk_t disk)
{
- unsigned long total_sectors = 0;
+ grub_uint64_t total_sectors = 0;
int drive;
struct grub_biosdisk_data *data;
/* Clear out the DRP. */
grub_memset (drp, 0, sizeof (*drp));
drp->size = sizeof (*drp);
- if (!grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))
+ if (! grub_biosdisk_get_diskinfo_int13_extensions (drive, drp))
{
data->flags = GRUB_BIOSDISK_FLAG_LBA;
- /* FIXME: 2TB limit. */
if (drp->total_sectors)
- total_sectors = drp->total_sectors & ~0L;
+ total_sectors = drp->total_sectors;
else
/* Some buggy BIOSes doesn't return the total sectors
correctly but returns zero. So if it is zero, compute
static grub_err_t
grub_biosdisk_rw (int cmd, grub_disk_t disk,
- unsigned long sector, unsigned long size,
+ grub_disk_addr_t sector, grub_size_t size,
unsigned segment)
{
struct grub_biosdisk_data *data = disk->data;
{
unsigned coff, hoff, soff;
unsigned head;
+ unsigned real_sector = (unsigned) sector;
- soff = sector % data->sectors + 1;
- head = sector / data->sectors;
+ /* It is impossible to reach over 2TB with the traditional
+ CHS access. */
+ if (sector > ~0UL)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "out of disk");
+
+ soff = real_sector % data->sectors + 1;
+ head = real_sector / data->sectors;
hoff = head % data->heads;
coff = head / data->heads;
return GRUB_ERR_NONE;
}
+/* Return the number of sectors which can be read safely at a time. */
+static grub_size_t
+get_safe_sectors (grub_disk_addr_t sector, grub_uint32_t sectors)
+{
+ grub_size_t size;
+ grub_uint32_t offset;
+
+ /* OFFSET = SECTOR % SECTORS */
+ grub_divmod64 (sector, sectors, &offset);
+
+ size = sectors - offset;
+
+ /* Limit the max to 0x7f because of Phoenix EDD. */
+ if (size > 0x7f)
+ size = 0x7f;
+
+ return size;
+}
+
static grub_err_t
-grub_biosdisk_read (grub_disk_t disk, unsigned long sector,
- unsigned long size, char *buf)
+grub_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, char *buf)
{
struct grub_biosdisk_data *data = disk->data;
while (size)
{
- unsigned long len;
+ grub_size_t len;
- len = data->sectors - (sector % data->sectors);
+ len = get_safe_sectors (sector, data->sectors);
if (len > size)
len = size;
}
static grub_err_t
-grub_biosdisk_write (grub_disk_t disk, unsigned long sector,
- unsigned long size, const char *buf)
+grub_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, const char *buf)
{
struct grub_biosdisk_data *data = disk->data;
while (size)
{
- unsigned long len;
+ grub_size_t len;
- len = data->sectors - (sector % data->sectors);
+ len = get_safe_sectors (sector, data->sectors);
if (len > size)
len = size;
/* ofdisk.c - Open Firmware disk access. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2004,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
}
static grub_err_t
-grub_ofdisk_read (grub_disk_t disk, unsigned long sector,
- unsigned long size, char *buf)
+grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, char *buf)
{
grub_ssize_t status, actual;
unsigned long long pos;
grub_dprintf ("disk",
- "Reading handle %p: sector 0x%lx, size 0x%lx, buf %p.\n",
+ "Reading handle %p: sector 0x%llx, size 0x%lx, buf %p.\n",
(void *) disk->data, sector, size, buf);
- pos = (unsigned long long) sector * 512UL;
+ pos = sector * 512UL;
grub_ieee1275_seek ((grub_ieee1275_ihandle_t) disk->data, (int) (pos >> 32),
(int) pos & 0xFFFFFFFFUL, &status);
if (status != 0)
return grub_error (GRUB_ERR_READ_ERROR,
- "Seek error, can't seek block %d", sector);
+ "Seek error, can't seek block %llu",
+ sector);
grub_ieee1275_read ((grub_ieee1275_ihandle_t) disk->data, buf,
size * 512UL, &actual);
if (actual != actual)
- return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %d", sector);
+ return grub_error (GRUB_ERR_READ_ERROR, "Read error on block: %llu",
+ sector);
return 0;
}
static grub_err_t
grub_ofdisk_write (grub_disk_t disk __attribute ((unused)),
- unsigned long sector __attribute ((unused)),
- unsigned long size __attribute ((unused)),
+ grub_disk_addr_t sector __attribute ((unused)),
+ grub_size_t size __attribute ((unused)),
const char *buf __attribute ((unused)))
{
return GRUB_ERR_NOT_IMPLEMENTED_YET;
/* loopback.c - command to add loopback devices. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006 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
/* Search for the device. */
for (dev = loopback_list, prev = &loopback_list;
- dev; prev = &dev->next, dev = dev->next)
- if (!grub_strcmp (dev->devname, name))
+ dev;
+ prev = &dev->next, dev = dev->next)
+ if (grub_strcmp (dev->devname, name) == 0)
break;
- if (!dev)
+
+ if (! dev)
return grub_error (GRUB_ERR_BAD_DEVICE, "Device not found");
/* Remove the device from the list. */
/* First try to replace the old device. */
for (newdev = loopback_list; newdev; newdev = newdev->next)
- if (!grub_strcmp (newdev->devname, args[0]))
+ if (grub_strcmp (newdev->devname, args[0]) == 0)
break;
+
if (newdev)
{
char *newname = grub_strdup (args[1]);
- if (!newname)
+ if (! newname)
return grub_errno;
grub_free (newdev->filename);
/* Unable to replace it, make a new entry. */
newdev = grub_malloc (sizeof (struct grub_loopback));
- if (!newdev)
+ if (! newdev)
return grub_errno;
newdev->devname = grub_strdup (args[0]);
- if (!newdev->devname)
+ if (! newdev->devname)
{
grub_free (newdev);
return grub_errno;
}
newdev->filename = grub_strdup (args[1]);
- if (!newdev->devname)
+ if (! newdev->filename)
{
grub_free (newdev->devname);
grub_free (newdev);
struct grub_loopback *dev;
for (dev = loopback_list; dev; dev = dev->next)
- if (!grub_strcmp (dev->devname, name))
+ if (grub_strcmp (dev->devname, name) == 0)
break;
if (! dev)
}
static grub_err_t
-grub_loopback_read (grub_disk_t disk, unsigned long sector,
- unsigned long size, char *buf)
+grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, char *buf)
{
grub_file_t file = (grub_file_t) disk->data;
- long pos;
+ grub_off_t pos;
- grub_file_seek (file, sector * GRUB_DISK_SECTOR_SIZE);
+ grub_file_seek (file, sector << GRUB_DISK_SECTOR_BITS);
- grub_file_read (file, buf, size * GRUB_DISK_SECTOR_SIZE);
+ 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. */
- pos = sector * GRUB_DISK_SECTOR_SIZE + size * GRUB_DISK_SECTOR_SIZE;
+ pos = (sector + size) << GRUB_DISK_SECTOR_BITS;
if (pos > file->size)
{
- unsigned long amount = pos - file->size;
- grub_memset (buf + pos - amount, amount, 0);
+ grub_size_t amount = pos - file->size;
+ grub_memset (buf + size - amount, 0, amount);
}
return 0;
static grub_err_t
grub_loopback_write (grub_disk_t disk __attribute ((unused)),
- unsigned long sector __attribute ((unused)),
- unsigned long size __attribute ((unused)),
- const char *buf __attribute ((unused)))
+ grub_disk_addr_t sector __attribute ((unused)),
+ grub_size_t size __attribute ((unused)),
+ const char *buf __attribute ((unused)))
{
return GRUB_ERR_NOT_IMPLEMENTED_YET;
}
GRUB_MOD_INIT(loop)
{
- (void)mod; /* To stop warning. */
+ (void) mod; /* To stop warning. */
grub_register_command ("loopback", grub_cmd_loopback, GRUB_COMMAND_FLAG_BOTH,
"loopback [-d|-p] DEVICENAME FILE",
"Make a device of a file.", options);
grub_unregister_command ("loopback");
grub_disk_dev_unregister (&grub_loopback_dev);
}
-
}
if (bitmap
- && (grub_file_read (font->file, bitmap, w * 16)
+ && (grub_file_read (font->file, (char *) bitmap, w * 16)
!= (grub_ssize_t) w * 16))
{
remove_font (font);
/* affs.c - Amiga Fast FileSystem. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_affs_read_file (grub_fshelp_node_t node,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_affs_read_block,
/* Read LEN bytes data from FILE into BUF. */
static grub_ssize_t
-grub_affs_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_affs_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_affs_data *data =
(struct grub_affs_data *) file->data;
{
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
"ext2fs doesn't support tripple indirect blocks");
- return grub_errno;
+ blknr = -1;
}
return blknr;
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_ext2_read_file (grub_fshelp_node_t node,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_ext2_read_block,
/* Read LEN bytes data from FILE into BUF. */
static grub_ssize_t
-grub_ext2_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_ext2_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_ext2_data *data =
(struct grub_ext2_data *) file->data;
static grub_ssize_t
grub_fat_read_data (grub_disk_t disk, struct grub_fat_data *data,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- grub_ssize_t offset, grub_ssize_t len, char *buf)
+ grub_off_t offset, grub_size_t len, char *buf)
{
- grub_ssize_t size;
+ grub_size_t size;
grub_uint32_t logical_cluster;
unsigned logical_cluster_bits;
grub_ssize_t ret = 0;
}
static grub_ssize_t
-grub_fat_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_fat_read (grub_file_t file, char *buf, grub_size_t len)
{
return grub_fat_read_data (file->device->disk, file->data, file->read_hook,
file->offset, len, buf);
/* fshelp.c -- Filesystem helper functions */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2004,2005,2006 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
blocks have a size of LOG2BLOCKSIZE (in log2). */
grub_ssize_t
grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf,
+ int pos, grub_size_t len, char *buf,
int (*get_block) (grub_fshelp_node_t node, int block),
- unsigned int filesize, int log2blocksize)
+ grub_off_t filesize, int log2blocksize)
{
int i;
int blockcnt;
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_hfs_read_file (struct grub_hfs_data *data,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
int i;
int blockcnt;
blockend = (len + pos) % data->blksz;
/* The last portion is exactly EXT2_BLOCK_SIZE (data). */
- if (!blockend)
+ if (! blockend)
blockend = data->blksz;
}
}
static grub_ssize_t
-grub_hfs_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_hfs_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_hfs_data *data =
(struct grub_hfs_data *) file->data;
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_hfsplus_read_file (grub_fshelp_node_t node,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_hfsplus_read_block,
/* Read LEN bytes data from FILE into BUF. */
static grub_ssize_t
-grub_hfsplus_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_hfsplus_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_hfsplus_data *data =
(struct grub_hfsplus_data *) file->data;
SUSP, Rock Ridge. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2004,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
((char *) entry + entry->len))
{
/* The last entry. */
- if (!grub_strncmp (entry->sig, "ST", 2))
+ if (grub_strncmp ((char *) entry->sig, "ST", 2) == 0)
break;
/* Additional entries are stored elsewhere. */
- if (!grub_strncmp (entry->sig, "CE", 2))
+ if (grub_strncmp ((char *) entry->sig, "CE", 2) == 0)
{
struct grub_iso9660_susp_ce *ce;
{
/* The "ER" entry is used to detect extensions. The
`IEEE_P1285' extension means Rock ridge. */
- if (!grub_strncmp (susp_entry->sig, "ER", 2))
+ if (grub_strncmp ((char *) susp_entry->sig, "ER", 2) == 0)
{
data->rockridge = 1;
return 1;
}
data = grub_malloc (sizeof (struct grub_iso9660_data));
- if (!data)
+ if (! data)
return 0;
/* Read the superblock. */
goto fail;
}
- if (grub_strncmp (data->voldesc.voldesc.magic, "CD001", 5))
+ if (grub_strncmp ((char *) data->voldesc.voldesc.magic, "CD001", 5) == 0)
{
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 (entry->sig, "SP", 2))
+ if (grub_strncmp ((char *) entry->sig, "SP", 2) == 0)
{
/* The 2nd data byte stored how many bytes are skipped everytime
to get to the SUA (System Usage Area). */
int size = grub_strlen (symlink);
symlink = grub_realloc (symlink, size + len + 1);
- if (!symlink)
+ if (! symlink)
return;
+
grub_strncat (symlink, part, len);
-
- return;
}
/* Read in a symlink. */
grub_err_t susp_iterate_sl (struct grub_iso9660_susp_entry *entry)
{
- if (!grub_strncmp ("SL", entry->sig, 2))
+ if (grub_strncmp ("SL", (char *) entry->sig, 2) == 0)
{
unsigned int pos = 1;
/* The data on pos + 2 is the actual data, pos + 1
is the length. Both are part of the `Component
Record'. */
- add_part (&entry->data[pos + 2],
+ add_part ((char *) &entry->data[pos + 2],
entry->data[pos + 1]);
if ((entry->data[pos] & 1))
addslash = 1;
grub_err_t susp_iterate_dir (struct grub_iso9660_susp_entry *entry)
{
/* The filename in the rock ridge entry. */
- if (!grub_strncmp ("NM", entry->sig, 2))
+ if (grub_strncmp ("NM", (char *) entry->sig, 2) == 0)
{
/* The flags are stored at the data position 0, here the
filename type is stored. */
filename[0] = '\0';
}
filename_alloc = 1;
- grub_strncpy (filename, &entry->data[1], size);
- filename [size] = '\0';
+ grub_strncpy (filename, (char *) &entry->data[1], size);
+ filename[size] = '\0';
}
}
/* The mode information (st_mode). */
- else if (!grub_strncmp (entry->sig, "PX", 2))
+ else if (grub_strncmp ((char *) entry->sig, "PX", 2) == 0)
{
/* At position 0 of the PX record the st_mode information is
stored. */
static grub_ssize_t
-grub_iso9660_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_iso9660_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_iso9660_data *data =
(struct grub_iso9660_data *) file->data;
if (data)
{
- *label = grub_strndup (data->voldesc.volname, 32);
+ *label = grub_strndup ((char *) data->voldesc.volname, 32);
grub_free (data);
}
else
/* jfs.c - JFS. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2004,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_jfs_read_file (struct grub_jfs_data *data,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
int i;
int blockcnt;
static grub_ssize_t
-grub_jfs_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_jfs_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_jfs_data *data =
(struct grub_jfs_data *) file->data;
/* minix.c - The minix filesystem, version 1 and 2. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2004,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_minix_read_file (struct grub_minix_data *data,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_disk_addr_t len, char *buf)
{
struct grub_minix_sblock *sblock = &data->sblock;
int i;
static grub_ssize_t
-grub_minix_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_minix_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_minix_data *data =
(struct grub_minix_data *) file->data;
/* sfs.c - Amiga Smart FileSystem. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_sfs_read_file (grub_fshelp_node_t node,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_sfs_read_block,
/* Read LEN bytes data from FILE into BUF. */
static grub_ssize_t
-grub_sfs_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_sfs_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_sfs_data *data = (struct grub_sfs_data *) file->data;
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_ufs_read_file (struct grub_ufs_data *data,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
struct grub_ufs_sblock *sblock = &data->sblock;
int i;
static grub_ssize_t
-grub_ufs_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_ufs_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_ufs_data *data =
(struct grub_ufs_data *) file->data;
/* xfs.c - XFS. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
POS. Return the amount of read bytes in READ. */
static grub_ssize_t
grub_xfs_read_file (grub_fshelp_node_t node,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset, unsigned length),
- int pos, unsigned int len, char *buf)
+ int pos, grub_size_t len, char *buf)
{
return grub_fshelp_read_file (node->data->disk, node, read_hook,
pos, len, buf, grub_xfs_read_block,
static grub_ssize_t
-grub_xfs_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_xfs_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_xfs_data *data =
(struct grub_xfs_data *) file->data;
void (*close) (struct grub_disk *disk);
/* Read SIZE sectors from the sector SECTOR of the disk DISK into BUF. */
- grub_err_t (*read) (struct grub_disk *disk, unsigned long sector,
- unsigned long size, char *buf);
+ grub_err_t (*read) (struct grub_disk *disk, grub_disk_addr_t sector,
+ grub_size_t size, char *buf);
/* Write SIZE sectors from BUF into the sector SECTOR of the disk DISK. */
- grub_err_t (*write) (struct grub_disk *disk, unsigned long sector,
- unsigned long size, const char *buf);
+ grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector,
+ grub_size_t size, const char *buf);
/* The next disk device. */
struct grub_disk_dev *next;
grub_disk_dev_t dev;
/* The total number of sectors. */
- unsigned long total_sectors;
+ grub_uint64_t total_sectors;
/* If partitions can be stored. */
int has_partitions;
/* The partition information. This is machine-specific. */
struct grub_partition *partition;
- /* Called when a sector was read. */
- void (*read_hook) (unsigned long sector, unsigned offset, unsigned length);
+ /* Called when a sector was read. OFFSET is between 0 and
+ the sector size minus 1, and LENGTH is between 0 and the sector size. */
+ void (*read_hook) (grub_disk_addr_t sector,
+ unsigned offset, unsigned length);
/* Device-specific data. */
void *data;
grub_disk_t EXPORT_FUNC(grub_disk_open) (const char *name);
void EXPORT_FUNC(grub_disk_close) (grub_disk_t disk);
grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk,
- unsigned long sector,
- unsigned long offset,
- unsigned long size,
+ grub_disk_addr_t sector,
+ grub_off_t offset,
+ grub_size_t size,
char *buf);
grub_err_t EXPORT_FUNC(grub_disk_write) (grub_disk_t disk,
- unsigned long sector,
- unsigned long offset,
- unsigned long size,
+ grub_disk_addr_t sector,
+ grub_off_t offset,
+ grub_size_t size,
const char *buf);
grub_fs_t fs;
/* The current offset. */
- grub_ssize_t offset;
+ grub_off_t offset;
/* The file size. */
- grub_ssize_t size;
+ grub_off_t size;
/* Filesystem-specific data. */
void *data;
/* This is called when a sector is read. Used only for a disk device. */
- void (*read_hook) (unsigned long sector, unsigned offset, unsigned length);
+ void (*read_hook) (grub_disk_addr_t sector,
+ unsigned offset, unsigned length);
};
typedef struct grub_file *grub_file_t;
grub_file_t EXPORT_FUNC(grub_file_open) (const char *name);
grub_ssize_t EXPORT_FUNC(grub_file_read) (grub_file_t file, char *buf,
- grub_ssize_t len);
-grub_ssize_t EXPORT_FUNC(grub_file_seek) (grub_file_t file,
- grub_ssize_t offset);
+ grub_size_t len);
+grub_off_t EXPORT_FUNC(grub_file_seek) (grub_file_t file, grub_off_t offset);
grub_err_t EXPORT_FUNC(grub_file_close) (grub_file_t file);
-static inline grub_ssize_t
+static inline grub_off_t
grub_file_size (const grub_file_t file)
{
return file->size;
}
-static inline grub_ssize_t
+static inline grub_off_t
grub_file_tell (const grub_file_t file)
{
return file->offset;
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_ssize_t len);
+ 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);
/* fshelp.h -- Filesystem helper functions */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2004,2005,2006 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
blocks have a size of LOG2BLOCKSIZE (in log2). */
grub_ssize_t
EXPORT_FUNC(grub_fshelp_read_file) (grub_disk_t disk, grub_fshelp_node_t node,
- void (*read_hook) (unsigned long sector,
+ void (*read_hook) (grub_disk_addr_t sector,
unsigned offset,
unsigned length),
- int pos, unsigned int len, char *buf,
+ int pos, grub_size_t len, char *buf,
int (*get_block) (grub_fshelp_node_t node,
int block),
- unsigned int filesize, int log2blocksize);
+ grub_off_t filesize, int log2blocksize);
unsigned int
EXPORT_FUNC(grub_fshelp_log2blksize) (unsigned int blksize,
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2002,2005 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2002,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#define GRUB_BOOT_MACHINE_VER_MAJ 0x3e
/* The offset of BOOT_DRIVE. */
-#define GRUB_BOOT_MACHINE_BOOT_DRIVE 0x40
-
-/* The offset of FORCE_LBA. */
-#define GRUB_BOOT_MACHINE_FORCE_LBA 0x41
+#define GRUB_BOOT_MACHINE_BOOT_DRIVE 0x4c
/* The offset of KERNEL_ADDRESS. */
-#define GRUB_BOOT_MACHINE_KERNEL_ADDRESS 0x42
+#define GRUB_BOOT_MACHINE_KERNEL_ADDRESS 0x40
/* The offset of KERNEL_SECTOR. */
#define GRUB_BOOT_MACHINE_KERNEL_SECTOR 0x44
/* The offset of KERNEL_SEGMENT. */
-#define GRUB_BOOT_MACHINE_KERNEL_SEGMENT 0x48
+#define GRUB_BOOT_MACHINE_KERNEL_SEGMENT 0x42
/* The offset of BOOT_DRIVE_CHECK. */
-#define GRUB_BOOT_MACHINE_DRIVE_CHECK 0x4b
+#define GRUB_BOOT_MACHINE_DRIVE_CHECK 0x4e
/* The offset of a magic number used by Windows NT. */
#define GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC 0x1b8
#define GRUB_BOOT_MACHINE_KERNEL_ADDR (GRUB_BOOT_MACHINE_KERNEL_SEG << 4)
/* The size of a block list used in the kernel startup code. */
-#define GRUB_BOOT_MACHINE_LIST_SIZE 8
+#define GRUB_BOOT_MACHINE_LIST_SIZE 12
#endif /* ! BOOT_MACHINE_HEADER */
int EXPORT_FUNC(grub_isdigit) (int c);
int EXPORT_FUNC(grub_tolower) (int c);
unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base);
+unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base);
char *EXPORT_FUNC(grub_strdup) (const char *s);
char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n);
void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
const grub_uint8_t *src,
grub_size_t size);
+grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
+ grub_uint32_t d, grub_uint32_t *r);
/* Inline functions. */
static inline unsigned int
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2004,2006 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
/* 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));
+ 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,
struct grub_partition
{
/* The start sector. */
- unsigned long start;
+ grub_disk_addr_t start;
/* The length in sector units. */
- unsigned long len;
+ grub_uint64_t len;
/* The offset of the partition table. */
- unsigned long offset;
+ grub_disk_addr_t offset;
/* The index of this partition in the partition table. */
int index;
void grub_sun_partition_map_fini (void);
#endif
\f
-static inline unsigned long
+static inline grub_disk_addr_t
grub_partition_get_start (const grub_partition_t p)
{
return p->start;
}
-static inline unsigned long
+static inline grub_uint64_t
grub_partition_get_len (const grub_partition_t p)
{
return p->len;
#if GRUB_CPU_SIZEOF_VOID_P == 8
typedef grub_uint64_t grub_addr_t;
-typedef grub_uint64_t grub_off_t;
typedef grub_uint64_t grub_size_t;
typedef grub_int64_t grub_ssize_t;
#else
typedef grub_uint32_t grub_addr_t;
-typedef grub_uint32_t grub_off_t;
typedef grub_uint32_t grub_size_t;
typedef grub_int32_t grub_ssize_t;
#endif
-/* FIXME: Will be grub_uint64_t */
-typedef unsigned long grub_disk_addr_t;
+/* The type for representing a file offset. */
+typedef grub_uint64_t grub_off_t;
+
+/* The type for representing a disk block address. */
+typedef grub_uint64_t grub_disk_addr_t;
/* Byte-orders. */
#define grub_swap_bytes16(x) \
/* gzio.c - decompression support for gzip */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2005 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
/* The underlyding file object. */
grub_file_t file;
/* The offset at which the data starts in the underlyding file. */
- grub_ssize_t data_offset;
+ grub_off_t data_offset;
/* The type of current block. */
int block_type;
/* The length of current block. */
/* The lookup bits for the distance code table. */
int bd;
/* The original offset value. */
- grub_ssize_t saved_offset;
+ grub_off_t saved_offset;
};
typedef struct grub_gzio *grub_gzio_t;
* (other than a real error with the disk) then we don't think it
* is a compressed file, and simply mark it as such.
*/
- if (grub_file_read (gzio->file, buf, 10) != 10
+ if (grub_file_read (gzio->file, (char *) buf, 10) != 10
|| ((*((grub_uint16_t *) buf) != GZIP_MAGIC)
&& (*((grub_uint16_t *) buf) != OLD_GZIP_MAGIC)))
{
if (buf[2] != DEFLATED
|| (buf[3] & UNSUPPORTED_FLAGS)
|| ((buf[3] & EXTRA_FIELD)
- && (grub_file_read (gzio->file, buf, 2) != 2
+ && (grub_file_read (gzio->file, (char *) buf, 2) != 2
|| eat_field (gzio->file,
grub_le_to_cpu16 (*((grub_uint16_t *) buf)))))
|| ((buf[3] & ORIG_NAME) && eat_field (gzio->file, -1))
grub_file_seek (gzio->file, grub_file_size (gzio->file) - 8);
- if (grub_file_read (gzio->file, buf, 8) != 8)
+ if (grub_file_read (gzio->file, (char *) buf, 8) != 8)
{
grub_error (GRUB_ERR_BAD_FILE_TYPE, "unsupported gzip format");
return 0;
}
+ /* FIXME: this does not handle files whose original size is over 4GB.
+ But how can we know the real original size? */
file->size = grub_le_to_cpu32 (*((grub_uint32_t *) (buf + 4)));
initialize_tables (file);
{
grub_gzio_t gzio = file->data;
- if (grub_file_tell (gzio->file) == gzio->data_offset
+ if (grub_file_tell (gzio->file) == (grub_off_t) gzio->data_offset
|| gzio->inbuf_d == INBUFSIZ)
{
gzio->inbuf_d = 0;
- grub_file_read (gzio->file, gzio->inbuf, INBUFSIZ);
+ grub_file_read (gzio->file, (char *) gzio->inbuf, INBUFSIZ);
}
return gzio->inbuf[gzio->inbuf_d++];
}
static grub_ssize_t
-grub_gzio_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_gzio_read (grub_file_t file, char *buf, grub_size_t len)
{
grub_ssize_t ret = 0;
grub_gzio_t gzio = file->data;
- grub_ssize_t offset;
+ grub_off_t offset;
/* Do we reset decompression to the beginning of the file? */
if (gzio->saved_offset > file->offset + WSIZE)
while (len > 0 && grub_errno == GRUB_ERR_NONE)
{
- register grub_ssize_t size;
+ register grub_size_t size;
register char *srcaddr;
while (offset >= gzio->saved_offset)
{
unsigned long dev_id;
unsigned long disk_id;
- unsigned long sector;
+ grub_disk_addr_t sector;
char *data;
int lock;
};
static unsigned
grub_disk_cache_get_index (unsigned long dev_id, unsigned long disk_id,
- unsigned long sector)
+ grub_disk_addr_t sector)
{
return ((dev_id * 524287UL + disk_id * 2606459UL
- + (sector >> GRUB_DISK_CACHE_BITS))
+ + ((unsigned) (sector >> GRUB_DISK_CACHE_BITS)))
% GRUB_DISK_CACHE_NUM);
}
static void
grub_disk_cache_invalidate (unsigned long dev_id, unsigned long disk_id,
- unsigned long sector)
+ grub_disk_addr_t sector)
{
unsigned index;
struct grub_disk_cache *cache;
static char *
grub_disk_cache_fetch (unsigned long dev_id, unsigned long disk_id,
- unsigned long sector)
+ grub_disk_addr_t sector)
{
struct grub_disk_cache *cache;
unsigned index;
static void
grub_disk_cache_unlock (unsigned long dev_id, unsigned long disk_id,
- unsigned long sector)
+ grub_disk_addr_t sector)
{
struct grub_disk_cache *cache;
unsigned index;
static grub_err_t
grub_disk_cache_store (unsigned long dev_id, unsigned long disk_id,
- unsigned long sector, const char *data)
+ grub_disk_addr_t sector, const char *data)
{
unsigned index;
struct grub_disk_cache *cache;
}
static grub_err_t
-grub_disk_check_range (grub_disk_t disk, unsigned long *sector,
- unsigned long *offset, grub_ssize_t size)
+grub_disk_check_range (grub_disk_t disk, grub_disk_addr_t *sector,
+ grub_off_t *offset, grub_size_t size)
{
*sector += *offset >> GRUB_DISK_SECTOR_BITS;
*offset &= GRUB_DISK_SECTOR_SIZE - 1;
if (disk->partition)
{
- unsigned long start, len;
+ grub_disk_addr_t start;
+ grub_uint64_t len;
start = grub_partition_get_start (disk->partition);
len = grub_partition_get_len (disk->partition);
/* Read data from the disk. */
grub_err_t
-grub_disk_read (grub_disk_t disk, unsigned long sector,
- unsigned long offset, unsigned long size, char *buf)
+grub_disk_read (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_off_t offset, grub_size_t size, char *buf)
{
char *tmp_buf;
-
+ unsigned real_offset;
+
/* First of all, check if the region is within the disk. */
if (grub_disk_check_range (disk, §or, &offset, size) != GRUB_ERR_NONE)
return grub_errno;
+ real_offset = offset;
+
/* Allocate a temporary buffer. */
tmp_buf = grub_malloc (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS);
if (! tmp_buf)
while (size)
{
char *data;
- unsigned long start_sector;
- unsigned long len;
- unsigned long pos;
+ grub_disk_addr_t start_sector;
+ grub_size_t len;
+ grub_size_t pos;
/* For reading bulk data. */
start_sector = sector & ~(GRUB_DISK_CACHE_SIZE - 1);
pos = (sector - start_sector) << GRUB_DISK_SECTOR_BITS;
- len = (GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS) - pos - offset;
+ len = ((GRUB_DISK_SECTOR_SIZE << GRUB_DISK_CACHE_BITS)
+ - pos - real_offset);
if (len > size)
len = size;
if (data)
{
/* Just copy it! */
- grub_memcpy (buf, data + pos + offset, len);
+ grub_memcpy (buf, data + pos + real_offset, len);
grub_disk_cache_unlock (disk->dev->id, disk->id, start_sector);
}
else
if ((disk->dev->read) (disk, sector, num, tmp_buf))
goto finish;
- grub_memcpy (buf, tmp_buf + offset, size);
+ grub_memcpy (buf, tmp_buf + real_offset, size);
/* Call the read hook, if any. */
if (disk->read_hook)
while (size)
{
- (disk->read_hook) (sector, offset,
+ (disk->read_hook) (sector, real_offset,
((size > GRUB_DISK_SECTOR_SIZE)
? GRUB_DISK_SECTOR_SIZE
: size));
sector++;
- size -= GRUB_DISK_SECTOR_SIZE - offset;
- offset = 0;
+ size -= GRUB_DISK_SECTOR_SIZE - real_offset;
+ real_offset = 0;
}
/* This must be the end. */
}
/* Copy it and store it in the disk cache. */
- grub_memcpy (buf, tmp_buf + pos + offset, len);
+ grub_memcpy (buf, tmp_buf + pos + real_offset, len);
grub_disk_cache_store (disk->dev->id, disk->id,
start_sector, tmp_buf);
}
/* Call the read hook, if any. */
if (disk->read_hook)
{
- unsigned long s = sector;
- unsigned long l = len;
+ grub_disk_addr_t s = sector;
+ grub_size_t l = len;
while (l)
{
- (disk->read_hook) (s, offset,
+ (disk->read_hook) (s, real_offset,
((l > GRUB_DISK_SECTOR_SIZE)
? GRUB_DISK_SECTOR_SIZE
: l));
- if (l < GRUB_DISK_SECTOR_SIZE - offset)
+ if (l < GRUB_DISK_SECTOR_SIZE - real_offset)
break;
s++;
- l -= GRUB_DISK_SECTOR_SIZE - offset;
- offset = 0;
+ l -= GRUB_DISK_SECTOR_SIZE - real_offset;
+ real_offset = 0;
}
}
sector = start_sector + GRUB_DISK_CACHE_SIZE;
buf += len;
size -= len;
- offset = 0;
+ real_offset = 0;
}
finish:
}
grub_err_t
-grub_disk_write (grub_disk_t disk, unsigned long sector,
- unsigned long offset, unsigned long size, const char *buf)
+grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_off_t offset, grub_size_t size, const char *buf)
{
+ unsigned real_offset;
+
if (grub_disk_check_range (disk, §or, &offset, size) != GRUB_ERR_NONE)
return -1;
+ real_offset = offset;
+
while (size)
{
- if (offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0))
+ if (real_offset != 0 || (size < GRUB_DISK_SECTOR_SIZE && size != 0))
{
char tmp_buf[GRUB_DISK_SECTOR_SIZE];
- unsigned long len;
+ 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 - offset;
+ len = GRUB_DISK_SECTOR_SIZE - real_offset;
if (len > size)
len = size;
- grub_memcpy (tmp_buf + offset, buf, len);
+ grub_memcpy (tmp_buf + real_offset, buf, len);
grub_disk_cache_invalidate (disk->dev->id, disk->id, sector);
sector++;
buf += len;
size -= len;
- offset = 0;
+ real_offset = 0;
}
else
{
- unsigned long len;
- unsigned long n;
+ grub_size_t len;
+ grub_size_t n;
len = size & ~(GRUB_DISK_SECTOR_SIZE - 1);
n = size >> GRUB_DISK_SECTOR_BITS;
/* file.c - file I/O functions */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2006 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
}
grub_ssize_t
-grub_file_read (grub_file_t file, char *buf, grub_ssize_t len)
+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;
return grub_errno;
}
-grub_ssize_t
-grub_file_seek (grub_file_t file, grub_ssize_t offset)
+grub_off_t
+grub_file_seek (grub_file_t file, grub_off_t offset)
{
- grub_ssize_t old;
+ grub_off_t old;
- if (offset < 0 || offset > file->size)
+ if (offset > file->size)
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
"attempt to seek outside of the file");
struct grub_fs_block
{
- unsigned long offset;
+ grub_disk_addr_t offset;
unsigned long length;
};
{
num++;
p = grub_strchr (p, ',');
+ if (p)
+ p++;
}
while (p);
{
if (*p != '+')
{
- blocks[i].offset = grub_strtoul (p, &p, 0);
+ blocks[i].offset = grub_strtoull (p, &p, 0);
if (grub_errno != GRUB_ERR_NONE || *p != '+')
{
grub_error (GRUB_ERR_BAD_FILENAME,
}
static grub_ssize_t
-grub_fs_blocklist_read (grub_file_t file, char *buf, grub_ssize_t len)
+grub_fs_blocklist_read (grub_file_t file, char *buf, grub_size_t len)
{
struct grub_fs_block *p;
- unsigned long sector;
- unsigned long offset;
+ grub_disk_addr_t sector;
+ grub_off_t offset;
grub_ssize_t ret = 0;
if (len > file->size - file->offset)
{
if (sector < p->length)
{
- grub_ssize_t size;
+ grub_size_t size;
size = len;
if (((size + offset + GRUB_DISK_SECTOR_SIZE - 1)
return c;
}
+
unsigned long
grub_strtoul (const char *str, char **end, int base)
{
- unsigned long num = 0;
+ unsigned long long num;
+
+ num = grub_strtoull (str, end, base);
+ if (num > ~0UL)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
+ return ~0UL;
+ }
+
+ return (unsigned long) num;
+}
+
+unsigned long long
+grub_strtoull (const char *str, char **end, int base)
+{
+ unsigned long long num = 0;
int found = 0;
/* Skip white spaces. */
}
found = 1;
-
- if (num > (~0UL - digit) / base)
+
+ /* NUM * BASE + DIGIT > ~0ULL */
+ if (num > grub_divmod64 (~0ULL - digit, base, 0))
{
grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow is detected");
- return 0;
+ return ~0ULL;
}
num = num * base + digit;
return p;
}
+/* Divide N by D, return the quotient, and store the remainder in *R. */
+grub_uint64_t
+grub_divmod64 (grub_uint64_t n, grub_uint32_t d, grub_uint32_t *r)
+{
+ /* This algorithm is typically implemented by hardware. The idea
+ is to get the highest bit in N, 64 times, by keeping
+ upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
+ represents the high 64 bits in 128-bits space. */
+ unsigned bits = 64;
+ unsigned long long q = 0;
+ unsigned m = 0;
+
+ /* Skip the slow computation, if 32-bit arithmetics are possible. */
+ if (n < 0xffffffff)
+ {
+ if (r)
+ *r = ((grub_uint32_t) n) % d;
+
+ 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;
+ m -= d;
+ }
+ }
+
+ if (r)
+ *r = m;
+
+ return q;
+}
+
/* Convert a long long value to a string. This function avoids 64-bit
modular arithmetic or divisions. */
static char *
/* BASE == 10 */
do
{
- /* This algorithm is typically implemented by hardware. The idea
- is to get the highest bit in N, 64 times, by keeping
- upper(N * 2^i) = upper((Q * 10 + M) * 2^i), where upper
- represents the high 64 bits in 128-bits space. */
- unsigned bits = sizeof (unsigned long long) * 8;
- unsigned long long q = 0;
- unsigned m = 0;
-
- while (bits--)
- {
- m <<= 1;
-
- if ((long long ) n < 0)
- m |= 1;
-
- q <<= 1;
- n <<= 1;
-
- if (m >= 10)
- {
- q |= 1;
- m -= 10;
- }
- }
-
+ unsigned m;
+
+ n = grub_divmod64 (n, 10, &m);
*p++ = m + '0';
- n = q;
}
while (n);
return grub_error (GRUB_ERR_BAD_OS,
"segment doesn't fit in memory reserved for the OS");
- if (grub_file_seek (file, phdr->p_offset) == -1)
+ if (grub_file_seek (file, (grub_off_t) phdr->p_offset)
+ == (grub_off_t) -1)
return grub_error (GRUB_ERR_BAD_OS,
"invalid offset in program header");
return grub_error (GRUB_ERR_BAD_OS,
"segment doesn't fit in memory reserved for the OS");
- if (grub_file_seek (file, phdr->p_offset) == -1)
+ if (grub_file_seek (file, (grub_off_t) phdr->p_offset)
+ == (grub_off_t) -1)
return grub_error (GRUB_ERR_BAD_OS,
"invalid offset in program header");
}
void
-grub_script_yyerror (struct grub_parser_param *lex, char const *err)
+grub_script_yyerror (struct grub_parser_param *lex __attribute__ ((unused)),
+ char const *err)
{
grub_printf ("%s\n", err);
}
#define YYFREE grub_free
#define YYMALLOC grub_malloc
-
+#define YYLTYPE_IS_TRIVIAL 0
%}
grub_script_parse (char *script, grub_err_t (*getline) (char **))
{
struct grub_script *parsed;
- struct grub_script_mem *memfree;
struct grub_script_mem *membackup;
struct grub_lexer_param *lexstate;
struct grub_parser_param *parsestate;
/* amiga.c - Read amiga partition tables (RDB). */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2004,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
sizeof (rdsk), (char *) &rdsk))
return grub_errno;
- if (!grub_strcmp (rdsk.magic, "RDSK"))
+ if (grub_strcmp ((char *) rdsk.magic, "RDSK") == 0)
{
/* Found the first PART block. */
next = grub_be_to_cpu32 (rdsk.partitionlst);
/* gpt.c - Read GUID Partition Tables (GPT). */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2005,2006 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
part.index = partno;
part.partmap = &grub_gpt_partition_map;
- grub_dprintf ("gpt", "GPT entry %d: start=%ld, length=%ld\n",
+ grub_dprintf ("gpt", "GPT entry %d: start=%lld, length=%lld\n",
partno, part.start, part.len);
if (hook (disk, &part))
/* pc.c - Read PC style partition tables. */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2004,2005 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2004,2005,2006 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
pcdata.bsd_type = -1;
grub_dprintf ("partition",
- "partition %d: flag 0x%x, type 0x%x, start 0x%lx, len 0x%lx\n",
+ "partition %d: flag 0x%x, type 0x%x, start 0x%llx, len 0x%llx\n",
p.index, e->flag, pcdata.dos_type, p.start, p.len);
/* If this is a GPT partition, this MBR is just a dummy. */
/* biosdisk.c - emulate biosdisk */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2006 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
#endif /* __linux__ */
static int
-open_device (const grub_disk_t disk, unsigned long sector, int flags)
+open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags)
{
int fd;
}
static grub_err_t
-grub_util_biosdisk_read (grub_disk_t disk, unsigned long sector,
- unsigned long size, char *buf)
+grub_util_biosdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, char *buf)
{
int fd;
}
static grub_err_t
-grub_util_biosdisk_write (grub_disk_t disk, unsigned long sector,
- unsigned long size, const char *buf)
+grub_util_biosdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
+ grub_size_t size, const char *buf)
{
int fd;
/* This is the blocklist used in the diskboot image. */
struct boot_blocklist
{
- grub_uint32_t start;
+ grub_uint64_t start;
grub_uint16_t len;
grub_uint16_t segment;
} __attribute__ ((packed));
grub_uint16_t core_sectors;
grub_device_t root_dev, dest_dev;
grub_uint8_t *boot_drive;
- grub_uint32_t *kernel_sector;
+ grub_disk_addr_t *kernel_sector;
grub_uint16_t *boot_drive_check;
struct boot_blocklist *first_block, *block;
grub_int32_t *install_dos_part, *install_bsd_part;
char *install_prefix;
char *tmp_img;
int i;
- unsigned long first_sector;
+ grub_disk_addr_t first_sector;
grub_uint16_t current_segment
= GRUB_BOOT_MACHINE_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4);
grub_uint16_t last_length = GRUB_DISK_SECTOR_SIZE;
FILE *fp;
unsigned long first_start = ~0UL;
- auto void save_first_sector (unsigned long sector, unsigned offset,
+ auto void save_first_sector (grub_disk_addr_t sector, unsigned offset,
unsigned length);
- auto void save_blocklists (unsigned long sector, unsigned offset,
+ auto void save_blocklists (grub_disk_addr_t sector, unsigned offset,
unsigned length);
auto int find_first_partition_start (grub_disk_t disk,
return 0;
}
- void save_first_sector (unsigned long sector, unsigned offset,
+ void save_first_sector (grub_disk_addr_t sector, unsigned offset,
unsigned length)
{
- grub_util_info ("the fist sector is <%lu,%u,%u>",
+ grub_util_info ("the first sector is <%llu,%u,%u>",
sector, offset, length);
if (offset != 0 || length != GRUB_DISK_SECTOR_SIZE)
first_sector = sector;
}
- void save_blocklists (unsigned long sector, unsigned offset, unsigned length)
+ void save_blocklists (grub_disk_addr_t sector, unsigned offset,
+ unsigned length)
{
struct boot_blocklist *prev = block + 1;
- grub_util_info ("saving <%lu,%u,%u> with the segment 0x%x",
+ 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 != first_block
- && (grub_le_to_cpu32 (prev->start)
+ && (grub_le_to_cpu64 (prev->start)
+ grub_le_to_cpu16 (prev->len)) == sector)
prev->len = grub_cpu_to_le16 (grub_le_to_cpu16 (prev->len) + 1);
else
{
- block->start = grub_cpu_to_le32 (sector);
+ block->start = grub_cpu_to_le64 (sector);
block->len = grub_cpu_to_le16 (1);
block->segment = grub_cpu_to_le16 (current_segment);
/* Set the addresses of BOOT_DRIVE, KERNEL_SECTOR and BOOT_DRIVE_CHECK. */
boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE);
- kernel_sector = (grub_uint32_t *) (boot_img
+ kernel_sector = (grub_disk_addr_t *) (boot_img
+ GRUB_BOOT_MACHINE_KERNEL_SECTOR);
boot_drive_check = (grub_uint16_t *) (boot_img
+ GRUB_BOOT_MACHINE_DRIVE_CHECK);
grub_util_info ("will embed the core image into after the MBR");
/* The first blocklist contains the whole sectors. */
- first_block->start = grub_cpu_to_le32 (2);
+ first_block->start = grub_cpu_to_le64 (2);
first_block->len = grub_cpu_to_le16 (core_sectors - 1);
first_block->segment
= grub_cpu_to_le16 (GRUB_BOOT_MACHINE_KERNEL_SEG
/* The boot image and the core image are on the same drive,
so there is no need to specify the boot drive explicitly. */
*boot_drive = 0xff;
- *kernel_sector = grub_cpu_to_le32 (1);
+ *kernel_sector = grub_cpu_to_le64 (1);
/* Write the boot image onto the disk. */
if (grub_disk_write (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE,
file = grub_file_open (core_path);
if (file)
{
- if (grub_file_size (file) != (grub_ssize_t) core_size)
+ if (grub_file_size (file) != core_size)
grub_util_info ("succeeded in opening the core image but the size is different (%d != %d)",
(int) grub_file_size (file), (int) core_size);
else if (grub_file_read (file, tmp_img, core_size)
free (core_path);
free (tmp_img);
- *kernel_sector = grub_cpu_to_le32 (first_sector);
+ *kernel_sector = grub_cpu_to_le64 (first_sector);
/* If the destination device is different from the root device,
it is necessary to embed the boot drive explicitly. */