diff --git a/ChangeLog b/ChangeLog index 7fb3fc336..7f4b20c6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +1999-08-25 OKUJI Yoshinori + + From Jochen Hoenicke : + * stage2/fat.h (FAT_BPB_FAT_SECTORS_16): New macro. + (FAT_BPB_FAT_SECTORS_32): Likewise. + (FAT_BPB_IS_FAT32): Likewise. + (FAT_BPB_ROOT_DIR_CLUSTER): Likewise. + (FAT_BPB_FAT_SECTORS): If FAT_BPB_FAT_SECTORS_16 returns + a non-zero value, return it. Otherwise return + FAT_BPB_FAT_SECTORS_32. + (FAT_DIRENTRY_FIRST_CLUSTER): Corrected. + * stage2/fsys_fat.c (root_dir): New variable. + (fat_mount): Use the macro IS_PC_SLICE_TYPE_FAT instead of + checking for each fs types directly. + Omit the >64 sectors check. + If the current fs type is FAT32, then set FAT_SIZE to 8 and + get the root from BPB. + (fat_create_blocklist): Use the macro SECTOR_SIZE instead of a + magic number. + (fat_dir): Set MAP to ROOT_DIR instead of -1. + * stage2/pc_slice.h (PC_SLICE_TYPE_FAT32): New macro. + (PC_SLICE_TYPE_FAT32_LBA): Likewise. + (PC_SLICE_TYPE_FAT16_LBA): Likewise. + (IS_PC_SLICE_TYPE_FAT): Likewise. + +1999-08-25 OKUJI Yoshinori + + * stage2/fsys_ffs.c (ffs_mount): Do not shift the fs type + FS_BSDFFS. Reported by Takehiro Suzuki + . + * stage2/fsys_fat.c (fat_mount): Do not shift the fs type + FS_MSDOS. + 1999-08-13 OKUJI Yoshinori Pavel Roskin's patch that adds new options to disable arbitrary diff --git a/NEWS b/NEWS index bc77a136b..2362922ec 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ New in 0.5.93: * Exit from the grub emulator just by pushing the key `q' in the menu. * The options --disable-ext2fs, --disable-fat and --disable-ffs disable ext2fs, FAT and FFS support in Stage 2 respectively. +* FAT32 support is added. New in 0.5.92 - 1999-07-26: * Bug fixes (i.e. Stage 1.5 can work fine again). diff --git a/THANKS b/THANKS index 870ef6607..b5126baa1 100644 --- a/THANKS +++ b/THANKS @@ -13,6 +13,7 @@ Bryan Ford Dan J. Walters Eric Hanchrow Heiko Schroeder +Jochen Hoenicke Klaus Reichl Kunihiro Ishiguro Mark Lundeberg @@ -20,4 +21,5 @@ Miles Bader OKUJI Yoshinori Pavel Roskin Peter Astrand +Takehiro Suzuki VaX#n8 diff --git a/TODO b/TODO index eb98c5d15..8be6956bd 100644 --- a/TODO +++ b/TODO @@ -33,7 +33,7 @@ Add keyboard layout configuration support. Clean up and enhance the manuals, especially concept indexes. -Add more filesystems support (minix, FAT32, etc.) +Add more filesystems support (minix, NTFS, etc.) ??? Add hide and unhide facilities. diff --git a/stage2/fat.h b/stage2/fat.h index c1bce8471..d9665ec06 100644 --- a/stage2/fat.h +++ b/stage2/fat.h @@ -43,10 +43,20 @@ #define FAT_BPB_RESERVED_SECTORS(bpb) \ (*((unsigned short *) (((int)bpb) + 14))) -#define FAT_BPB_FAT_SECTORS(bpb) \ +#define FAT_BPB_FAT_SECTORS_16(bpb) \ (*((unsigned short *) (((int)bpb) + 22))) +#define FAT_BPB_FAT_SECTORS_32(bpb) \ + (*((unsigned long *) (((int)bpb) + 36))) +#define FAT_BPB_IS_FAT32(bpb) \ + (FAT_BPB_FAT_SECTORS_16(bpb) == 0) +#define FAT_BPB_FAT_SECTORS(bpb) \ + (FAT_BPB_FAT_SECTORS_16(bpb) \ + ? FAT_BPB_FAT_SECTORS_16(bpb) : FAT_BPB_FAT_SECTORS_32(bpb)) #define FAT_BPB_FAT_START(bpb) FAT_BPB_RESERVED_SECTORS(bpb) +#define FAT_BPB_ROOT_DIR_CLUSTER(bpb) \ + (*((unsigned long *) (((int)bpb) + 44))) + /* * This appears to be a MAJOR kludge!! Don't use it if possible... */ @@ -108,6 +118,6 @@ & ((*((unsigned char *) entry)) != 0xE5) \ & !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) ) #define FAT_DIRENTRY_FIRST_CLUSTER(entry) \ - (*((unsigned short *) (entry+26))) + ((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16)) #define FAT_DIRENTRY_FILELENGTH(entry) \ (*((unsigned long *) (entry+28))) diff --git a/stage2/fsys_fat.c b/stage2/fsys_fat.c index 94d18a4a0..5b24c0067 100644 --- a/stage2/fsys_fat.c +++ b/stage2/fsys_fat.c @@ -29,6 +29,7 @@ static int num_clust; static int mapblock; static int data_offset; static int fat_size; +static int root_dir; /* pointer(s) into filesystem info buffer for DOS stuff */ #define BPB ( FSYS_BUF + 32256 ) /* 512 bytes long */ @@ -40,13 +41,11 @@ fat_mount (void) int retval = 1; if ((((current_drive & 0x80) || (current_slice != 0)) - && (current_slice != PC_SLICE_TYPE_FAT12) - && (current_slice != PC_SLICE_TYPE_FAT16_LT32M) - && (current_slice != PC_SLICE_TYPE_FAT16_GT32M) - && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_MSDOS << 8))) + && ! IS_PC_SLICE_TYPE_FAT (current_slice) + && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_MSDOS))) || !devread (0, 0, SECTOR_SIZE, (char *) BPB) || FAT_BPB_BYTES_PER_SECTOR (BPB) != SECTOR_SIZE - || FAT_BPB_SECT_PER_CLUST (BPB) < 1 || FAT_BPB_SECT_PER_CLUST (BPB) > 64 + || FAT_BPB_SECT_PER_CLUST (BPB) < 1 || (FAT_BPB_SECT_PER_CLUST (BPB) & (FAT_BPB_SECT_PER_CLUST (BPB) - 1)) || !((current_drive & 0x80) || FAT_BPB_FLOPPY_NUM_SECTORS (BPB))) @@ -56,7 +55,13 @@ fat_mount (void) mapblock = -4096; data_offset = FAT_BPB_DATA_OFFSET (BPB); num_clust = FAT_BPB_NUM_CLUST (BPB) + 2; - if (num_clust > FAT_MAX_12BIT_CLUST) + root_dir = -1; + if (FAT_BPB_IS_FAT32 (BPB)) + { + fat_size = 8; + root_dir = FAT_BPB_ROOT_DIR_CLUSTER (BPB); + } + else if (num_clust > FAT_MAX_12BIT_CLUST) fat_size = 4; else fat_size = 3; @@ -107,7 +112,7 @@ fat_create_blocklist (int first_fat_entry) */ new_mapblock = (last_fat_entry * fat_size) >> 1; - if (new_mapblock > (mapblock + 2045) + if (new_mapblock > (mapblock + SECTOR_SIZE * 4 - 3) || new_mapblock < (mapblock + 3)) { mapblock = ((new_mapblock < 6) ? 0 : @@ -118,15 +123,17 @@ fat_create_blocklist (int first_fat_entry) } first_fat_entry - = *((unsigned short *) (FAT_BUF + (new_mapblock - mapblock))); + = *((unsigned long *) (FAT_BUF + (new_mapblock - mapblock))); - if (num_clust <= FAT_MAX_12BIT_CLUST) + if (fat_size == 3) { if (last_fat_entry & 1) first_fat_entry >>= 4; else first_fat_entry &= 0xFFF; } + else if (fat_size == 4) + first_fat_entry &= 0xFFFF; if (first_fat_entry < 2) { @@ -144,7 +151,7 @@ fat_create_blocklist (int first_fat_entry) while (first_fat_entry < num_clust && blk_cur_blklist < (FAT_BUF - 7)); } - return 1; + return first_fat_entry >= num_clust; } @@ -156,7 +163,7 @@ int fat_dir (char *dirname) { char *rest, ch, filename[13], dir_buf[FAT_DIRENTRY_LENGTH]; - int attrib = FAT_ATTRIB_DIR, map = -1; + int attrib = FAT_ATTRIB_DIR, map = root_dir; /* main loop to find desired directory entry */ loop: diff --git a/stage2/fsys_ffs.c b/stage2/fsys_ffs.c index 611c8e721..f56217b9d 100644 --- a/stage2/fsys_ffs.c +++ b/stage2/fsys_ffs.c @@ -80,7 +80,7 @@ ffs_mount (void) int retval = 1; if ((((current_drive & 0x80) || (current_slice != 0)) - && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS << 8)) + && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS)) || part_length < (SBLOCK + (SBSIZE / DEV_BSIZE)) || !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK) || SUPERBLOCK->fs_magic != FS_MAGIC) diff --git a/stage2/pc_slice.h b/stage2/pc_slice.h index 08195e199..6d6ad90ce 100644 --- a/stage2/pc_slice.h +++ b/stage2/pc_slice.h @@ -102,9 +102,22 @@ #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_EXT2FS 0x83 +/* For convinience. */ +#define IS_PC_SLICE_TYPE_FAT(type) \ + (((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)) + + /* these ones are special, as they use thier own partitioning scheme to subdivide the PC partitions from there. */ #define PC_SLICE_TYPE_FREEBSD 0xa5