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.
This commit is contained in:
okuji 2006-06-04 15:56:55 +00:00
parent 53af98ad17
commit 524a1e6a40
47 changed files with 708 additions and 380 deletions

View file

@ -56,12 +56,12 @@ struct grub_disk_dev
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;
@ -80,7 +80,7 @@ struct grub_disk
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;
@ -91,8 +91,10 @@ struct grub_disk
/* 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;
@ -120,14 +122,14 @@ int EXPORT_FUNC(grub_disk_dev_iterate) (int (*hook) (const char *name));
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);

View file

@ -35,16 +35,17 @@ struct grub_file
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;
@ -53,18 +54,17 @@ char *EXPORT_FUNC(grub_file_get_device_name) (const char *name);
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;

View file

@ -42,7 +42,7 @@ struct grub_fs
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);

View file

@ -1,7 +1,7 @@
/* 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
@ -64,13 +64,13 @@ EXPORT_FUNC(grub_fshelp_find_file) (const char *path,
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,

View file

@ -1,6 +1,6 @@
/*
* 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
@ -33,22 +33,19 @@
#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
@ -77,6 +74,6 @@
#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 */

View file

@ -56,6 +56,7 @@ int EXPORT_FUNC(grub_isgraph) (int c);
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);
@ -76,6 +77,8 @@ grub_uint8_t *EXPORT_FUNC(grub_utf16_to_utf8) (grub_uint8_t *dest,
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

View file

@ -1,6 +1,6 @@
/*
* 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
@ -34,7 +34,8 @@ struct grub_partition_map
/* 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,
@ -52,13 +53,13 @@ typedef struct grub_partition_map *grub_partition_map_t;
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;
@ -94,13 +95,13 @@ void grub_sun_partition_map_init (void);
void grub_sun_partition_map_fini (void);
#endif
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;

View file

@ -83,18 +83,19 @@ typedef grub_int32_t grub_host_ssize_t;
#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) \