diff options
author | Greg Watson <jarrah@users.sourceforge.net> | 2004-03-13 03:33:34 +0000 |
---|---|---|
committer | Greg Watson <jarrah@users.sourceforge.net> | 2004-03-13 03:33:34 +0000 |
commit | 3cd7fc7640b18b3ccefabee2dc03432217c6ed58 (patch) | |
tree | 76be94a1467d426a6fe55b718ad5aa27df1386ef /src | |
parent | 7d2478e962772c46eccdb9a93359710b0ca01dce (diff) |
filesystem support
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1403 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src')
-rw-r--r-- | src/include/fs/fs.h | 222 | ||||
-rw-r--r-- | src/include/fs/iso9660.h | 310 | ||||
-rw-r--r-- | src/include/fs/vfs.h | 29 |
3 files changed, 561 insertions, 0 deletions
diff --git a/src/include/fs/fs.h b/src/include/fs/fs.h new file mode 100644 index 0000000000..b23a1b5158 --- /dev/null +++ b/src/include/fs/fs.h @@ -0,0 +1,222 @@ +/* GRUB compatibility header */ + +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2003 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 Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <fs/vfs.h> + +/* This disables some portion of code */ +#define STAGE1_5 1 + +static inline int +substring (const char *s1, const char *s2) +{ + while (*s1 == *s2) + { + /* The strings match exactly. */ + if (! *(s1++)) + return 0; + s2 ++; + } + + /* S1 is a substring of S2. */ + if (*s1 == 0) + return -1; + + /* S1 isn't a substring. */ + return 1; +} + +#define MAXINT 0x7fffffff + +/* This is only used by fsys_* to determine if it's hard disk. If it is, + * they try to guess filesystem type by partition type. I guess it is + * not necessory, so hardcoded to 0 (first floppy) --ts1 */ +#define current_drive 0 + +/* Ditto */ +#define current_slice 0 + +extern unsigned long part_start; +extern unsigned long part_length; +extern int filepos; +extern int filemax; +extern int fsmax; + +/* Error codes (descriptions are in common.c) */ +typedef enum +{ + ERR_NONE = 0, + ERR_BAD_FILENAME, + ERR_BAD_FILETYPE, + ERR_BAD_GZIP_DATA, + ERR_BAD_GZIP_HEADER, + ERR_BAD_PART_TABLE, + ERR_BAD_VERSION, + ERR_BELOW_1MB, + ERR_BOOT_COMMAND, + ERR_BOOT_FAILURE, + ERR_BOOT_FEATURES, + ERR_DEV_FORMAT, + ERR_DEV_VALUES, + ERR_EXEC_FORMAT, + ERR_FILELENGTH, + ERR_FILE_NOT_FOUND, + ERR_FSYS_CORRUPT, + ERR_FSYS_MOUNT, + ERR_GEOM, + ERR_NEED_LX_KERNEL, + ERR_NEED_MB_KERNEL, + ERR_NO_DISK, + ERR_NO_PART, + ERR_NUMBER_PARSING, + ERR_OUTSIDE_PART, + ERR_READ, + ERR_SYMLINK_LOOP, + ERR_UNRECOGNIZED, + ERR_WONT_FIT, + ERR_WRITE, + ERR_BAD_ARGUMENT, + ERR_UNALIGNED, + ERR_PRIVILEGED, + ERR_DEV_NEED_INIT, + ERR_NO_DISK_SPACE, + ERR_NUMBER_OVERFLOW, + + MAX_ERR_NUM +} fs_error_t; + +extern fs_error_t errnum; + +/* instrumentation variables */ +/* (Not used in FILO) */ +extern void (*disk_read_hook) (int, int, int); +extern void (*disk_read_func) (int, int, int); + +#define FSYS_BUFLEN 0x8000 +extern char FSYS_BUF[FSYS_BUFLEN]; + +#define print_possibilities 0 + +#define SECTOR_SIZE 512 +#define SECTOR_BITS 9 + +#ifdef CONFIG_FS_FAT +int fat_mount (void); +int fat_read (char *buf, int len); +int fat_dir (char *dirname); +#endif + +#if CONFIG_FS_EXT2 == 1 +int ext2fs_mount (void); +int ext2fs_read (char *buf, int len); +int ext2fs_dir (char *dirname); +#endif + +#ifdef CONFIG_FS_MINIX +int minix_mount (void); +int minix_read (char *buf, int len); +int minix_dir (char *dirname); +#endif + +#ifdef CONFIG_FS_REISERFS +int reiserfs_mount (void); +int reiserfs_read (char *buf, int len); +int reiserfs_dir (char *dirname); +int reiserfs_embed (int *start_sector, int needed_sectors); +#endif + +#ifdef CONFIG_FS_JFS +int jfs_mount (void); +int jfs_read (char *buf, int len); +int jfs_dir (char *dirname); +int jfs_embed (int *start_sector, int needed_sectors); +#endif + +#ifdef CONFIG_FS_XFS +int xfs_mount (void); +int xfs_read (char *buf, int len); +int xfs_dir (char *dirname); +#endif + +#if CONFIG_FS_ISO9660 == 1 +int iso9660_mount (void); +int iso9660_read (char *buf, int len); +int iso9660_dir (char *dirname); +#endif + +/* This is not a flag actually, but used as if it were a flag. */ +#define PC_SLICE_TYPE_HIDDEN_FLAG 0x10 + +#define PC_SLICE_TYPE_NONE 0 +#define PC_SLICE_TYPE_FAT12 1 +#define PC_SLICE_TYPE_FAT16_LT32M 4 +#define PC_SLICE_TYPE_EXTENDED 5 +#define PC_SLICE_TYPE_FAT16_GT32M 6 +#define PC_SLICE_TYPE_FAT32 0xb +#define PC_SLICE_TYPE_FAT32_LBA 0xc +#define PC_SLICE_TYPE_FAT16_LBA 0xe +#define PC_SLICE_TYPE_WIN95_EXTENDED 0xf +#define PC_SLICE_TYPE_EZD 0x55 +#define PC_SLICE_TYPE_MINIX 0x80 +#define PC_SLICE_TYPE_LINUX_MINIX 0x81 +#define PC_SLICE_TYPE_EXT2FS 0x83 +#define PC_SLICE_TYPE_LINUX_EXTENDED 0x85 +#define PC_SLICE_TYPE_VSTAFS 0x9e +#define PC_SLICE_TYPE_DELL_UTIL 0xde +#define PC_SLICE_TYPE_LINUX_RAID 0xfd + +/* For convinience. */ +/* Check if TYPE is a FAT partition type. Clear the hidden flag before + the check, to allow the user to mount a hidden partition in GRUB. */ +#define IS_PC_SLICE_TYPE_FAT(type) \ + ({ int _type = (type) & ~PC_SLICE_TYPE_HIDDEN_FLAG; \ + _type == PC_SLICE_TYPE_FAT12 \ + || _type == PC_SLICE_TYPE_FAT16_LT32M \ + || _type == PC_SLICE_TYPE_FAT16_GT32M \ + || _type == PC_SLICE_TYPE_FAT16_LBA \ + || _type == PC_SLICE_TYPE_FAT32 \ + || _type == PC_SLICE_TYPE_FAT32_LBA \ + || _type == PC_SLICE_TYPE_DELL_UTIL; }) + +#define IS_PC_SLICE_TYPE_MINIX(type) \ + (((type) == PC_SLICE_TYPE_MINIX) \ + || ((type) == PC_SLICE_TYPE_LINUX_MINIX)) + +#define IS_PC_SLICE_TYPE_BSD_WITH_FS(type,fs) 0 + +/* possible values for the *BSD-style partition type */ +#define FS_UNUSED 0 /* unused */ +#define FS_SWAP 1 /* swap */ +#define FS_V6 2 /* Sixth Edition */ +#define FS_V7 3 /* Seventh Edition */ +#define FS_SYSV 4 /* System V */ +#define FS_V71K 5 /* V7 with 1K blocks (4.1, 2.9) */ +#define FS_V8 6 /* Eighth Edition, 4K blocks */ +#define FS_BSDFFS 7 /* 4.2BSD fast file system */ +#define FS_MSDOS 8 /* MSDOS file system */ +#define FS_BSDLFS 9 /* 4.4BSD log-structured file system */ +#define FS_OTHER 10 /* in use, but unknown/unsupported */ +#define FS_HPFS 11 /* OS/2 high-performance file system */ +#define FS_ISO9660 12 /* ISO 9660, normally CD-ROM */ +#define FS_BOOT 13 /* partition contains bootstrap */ +#define FS_ADOS 14 /* AmigaDOS fast file system */ +#define FS_HFS 15 /* Macintosh HFS */ +#define FS_FILECORE 16 /* Acorn Filecore Filing System */ +#define FS_EXT2FS 17 /* Linux Extended 2 file system */ diff --git a/src/include/fs/iso9660.h b/src/include/fs/iso9660.h new file mode 100644 index 0000000000..1c76800eb8 --- /dev/null +++ b/src/include/fs/iso9660.h @@ -0,0 +1,310 @@ +#ifndef _ISO9660_H +#define _ISO9660_H + +/* + * The isofs filesystem constants/structures + */ + +/* This part borrowed from the bsd386 isofs */ +#define ISODCL(from, to) (to - from + 1) + +struct iso_volume_descriptor { + char type[ISODCL(1,1)]; /* 711 */ + char id[ISODCL(2,6)]; + char version[ISODCL(7,7)]; + char data[ISODCL(8,2048)]; +}; + +#define ISO_SECTOR_BITS (11) +#define ISO_SECTOR_SIZE (1<<ISO_SECTOR_BITS) + +#define ISO_REGULAR 1 /* regular file */ +#define ISO_DIRECTORY 2 /* directory */ +#define ISO_OTHER 0 /* other file (with Rock Ridge) */ + +#define RR_FLAG_PX 0x01 /* have POSIX file attributes */ +#define RR_FLAG_NM 0x08 /* have alternate file name */ + +/* POSIX file attributes for Rock Ridge extensions */ +#define POSIX_S_IFMT 0xF000 +#define POSIX_S_IFREG 0x8000 +#define POSIX_S_IFDIR 0x4000 + +/* volume descriptor types */ +#define ISO_VD_PRIMARY 1 +#define ISO_VD_SUPPLEMENTARY 2 +#define ISO_VD_END 255 + +#define ISO_STANDARD_ID "CD001" + +struct iso_primary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char unused1 [ISODCL ( 8, 8)]; + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char unused3 [ISODCL ( 89, 120)]; + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; +}; + +/* Almost the same as the primary descriptor but two fields are specified */ +struct iso_supplementary_descriptor { + char type [ISODCL ( 1, 1)]; /* 711 */ + char id [ISODCL ( 2, 6)]; + char version [ISODCL ( 7, 7)]; /* 711 */ + char flags [ISODCL ( 8, 8)]; /* 853 */ + char system_id [ISODCL ( 9, 40)]; /* achars */ + char volume_id [ISODCL ( 41, 72)]; /* dchars */ + char unused2 [ISODCL ( 73, 80)]; + char volume_space_size [ISODCL ( 81, 88)]; /* 733 */ + char escape [ISODCL ( 89, 120)]; /* 856 */ + char volume_set_size [ISODCL (121, 124)]; /* 723 */ + char volume_sequence_number [ISODCL (125, 128)]; /* 723 */ + char logical_block_size [ISODCL (129, 132)]; /* 723 */ + char path_table_size [ISODCL (133, 140)]; /* 733 */ + char type_l_path_table [ISODCL (141, 144)]; /* 731 */ + char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */ + char type_m_path_table [ISODCL (149, 152)]; /* 732 */ + char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */ + char root_directory_record [ISODCL (157, 190)]; /* 9.1 */ + char volume_set_id [ISODCL (191, 318)]; /* dchars */ + char publisher_id [ISODCL (319, 446)]; /* achars */ + char preparer_id [ISODCL (447, 574)]; /* achars */ + char application_id [ISODCL (575, 702)]; /* achars */ + char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */ + char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */ + char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */ + char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */ + char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */ + char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */ + char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */ + char file_structure_version [ISODCL (882, 882)]; /* 711 */ + char unused4 [ISODCL (883, 883)]; + char application_data [ISODCL (884, 1395)]; + char unused5 [ISODCL (1396, 2048)]; +}; + + +#define HS_STANDARD_ID "CDROM" + +struct hs_volume_descriptor { + char foo [ISODCL ( 1, 8)]; /* 733 */ + char type [ISODCL ( 9, 9)]; /* 711 */ + char id [ISODCL ( 10, 14)]; + char version [ISODCL ( 15, 15)]; /* 711 */ + char data[ISODCL(16,2048)]; +}; + + +struct hs_primary_descriptor { + char foo [ISODCL ( 1, 8)]; /* 733 */ + char type [ISODCL ( 9, 9)]; /* 711 */ + char id [ISODCL ( 10, 14)]; + char version [ISODCL ( 15, 15)]; /* 711 */ + char unused1 [ISODCL ( 16, 16)]; /* 711 */ + char system_id [ISODCL ( 17, 48)]; /* achars */ + char volume_id [ISODCL ( 49, 80)]; /* dchars */ + char unused2 [ISODCL ( 81, 88)]; /* 733 */ + char volume_space_size [ISODCL ( 89, 96)]; /* 733 */ + char unused3 [ISODCL ( 97, 128)]; /* 733 */ + char volume_set_size [ISODCL (129, 132)]; /* 723 */ + char volume_sequence_number [ISODCL (133, 136)]; /* 723 */ + char logical_block_size [ISODCL (137, 140)]; /* 723 */ + char path_table_size [ISODCL (141, 148)]; /* 733 */ + char type_l_path_table [ISODCL (149, 152)]; /* 731 */ + char unused4 [ISODCL (153, 180)]; /* 733 */ + char root_directory_record [ISODCL (181, 214)]; /* 9.1 */ +}; + +/* We use this to help us look up the parent inode numbers. */ + +struct iso_path_table{ + unsigned char name_len[2]; /* 721 */ + char extent[4]; /* 731 */ + char parent[2]; /* 721 */ + char name[0]; +} __attribute__((packed)); + +/* high sierra is identical to iso, except that the date is only 6 bytes, and + there is an extra reserved byte after the flags */ + +struct iso_directory_record { + char length [ISODCL (1, 1)]; /* 711 */ + char ext_attr_length [ISODCL (2, 2)]; /* 711 */ + char extent [ISODCL (3, 10)]; /* 733 */ + char size [ISODCL (11, 18)]; /* 733 */ + char date [ISODCL (19, 25)]; /* 7 by 711 */ + char flags [ISODCL (26, 26)]; + char file_unit_size [ISODCL (27, 27)]; /* 711 */ + char interleave [ISODCL (28, 28)]; /* 711 */ + char volume_sequence_number [ISODCL (29, 32)]; /* 723 */ + unsigned char name_len [ISODCL (33, 33)]; /* 711 */ + char name [0]; +} __attribute__((packed)); + +struct SU_SP{ + unsigned char magic[2]; + unsigned char skip; +} __attribute__((packed)); + +struct SU_CE{ + char extent[8]; + char offset[8]; + char size[8]; +}; + +struct SU_ER{ + unsigned char len_id; + unsigned char len_des; + unsigned char len_src; + unsigned char ext_ver; + char data[0]; +} __attribute__((packed)); + +struct RR_RR{ + char flags[1]; +} __attribute__((packed)); + +struct RR_PX{ + char mode[8]; + char n_links[8]; + char uid[8]; + char gid[8]; +}; + +struct RR_PN{ + char dev_high[8]; + char dev_low[8]; +}; + + +struct SL_component{ + unsigned char flags; + unsigned char len; + char text[0]; +} __attribute__((packed)); + +struct RR_SL{ + unsigned char flags; + struct SL_component link; +} __attribute__((packed)); + +struct RR_NM{ + unsigned char flags; + char name[0]; +} __attribute__((packed)); + +struct RR_CL{ + char location[8]; +}; + +struct RR_PL{ + char location[8]; +}; + +struct stamp{ + char time[7]; +} __attribute__((packed)); + +struct RR_TF{ + char flags; + struct stamp times[0]; /* Variable number of these beasts */ +} __attribute__((packed)); + +/* Linux-specific extension for transparent decompression */ +struct RR_ZF{ + char algorithm[2]; + char parms[2]; + char real_size[8]; +}; + +struct rock_ridge{ + char signature[2]; + unsigned char len; + unsigned char version; + union{ + struct SU_SP SP; + struct SU_CE CE; + struct SU_ER ER; + struct RR_RR RR; + struct RR_PX PX; + struct RR_PN PN; + struct RR_SL SL; + struct RR_NM NM; + struct RR_CL CL; + struct RR_PL PL; + struct RR_TF TF; + struct RR_ZF ZF; + } u; +}; + +typedef union RR_ptr { + struct rock_ridge *rr; + char *ptr; + int i; +} RR_ptr_t; + +#include <arch/byteorder.h> + +static inline int isonum_711(char *p) +{ + unsigned char x = *(unsigned char *)p; + return x; +} +static inline int isonum_712(char *p) +{ + return *(char *)p; +} +static inline int isonum_721(char *p) +{ + return le16_to_cpu(*(unsigned short *)p); +} +static inline int isonum_722(char *p) +{ + return be16_to_cpu(*(unsigned short *)p); +} +static inline int isonum_723(char *p) +{ + /* Ignore bigendian datum due to broken mastering programs */ + return le16_to_cpu(*(unsigned short *)p); +} +static inline int isonum_731(char *p) +{ + return le32_to_cpu(*(unsigned int *)p); +} +static inline int isonum_732(char *p) +{ + return be32_to_cpu(*(unsigned int *)p); +} +static inline int isonum_733(char *p) +{ + /* Ignore bigendian datum due to broken mastering programs */ + return le32_to_cpu(*(unsigned int *)p); +} +#endif /* _ISO9660_H */ diff --git a/src/include/fs/vfs.h b/src/include/fs/vfs.h new file mode 100644 index 0000000000..4040566f65 --- /dev/null +++ b/src/include/fs/vfs.h @@ -0,0 +1,29 @@ +#ifndef _VFS_H +#define _VFS_H + +#include <stdint.h> + +#define DISK_IDE 1 +#define DISK_MEM 2 + +int devopen(const char *name, int *reopen); +int devread(unsigned long sector, unsigned long byte_offset, + unsigned long byte_len, void *buf); + +int file_open(const char *filename); +int file_read(void *buf, unsigned long len); +int file_seek(unsigned long offset); +unsigned long file_pos(void); +unsigned long file_size(void); + +#define PARTITION_UNKNOWN 0xbad6a7 + +#ifdef CONFIG_FS_ELTORITO +int open_eltorito_image(int part, unsigned long *start, unsigned long *length); +#else +# define open_eltorito_image(x,y,z) PARTITION_UNKNOWN +#endif + +extern int using_devsize; + +#endif /* _VFS_H */ |