/* * GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS * Copyright (C) 2007 Bean (bean123@126.com) * * 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. */ /* NTFS boot sector for loading GRLDR , written by bean * * This file can be compiled as standaolne boot sector, or it can be embeded in * GRLDR.MBR at 0xA00 , right after the ext2 boot sector * * To compile the standalone ntfsbs.bin: * gcc -c -o ntfsbs.o ntfsbs.S * gcc -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 -o ntfsbs_exec ntfsbs.o * objcopy -O binary ntfsbs_exec ntfsbs.bin * * To install the standalone ntfsbs.bin: * grubinst --restore=ntfsbs.bin DEVICE_OR_FILE * * Where DEVICE_OR_FILE specify a NTFS partition * * Limitations: * 1. Don't support >1K MFT record size, >4K INDEX record size * 2. Don't support encrypted file * 3. Don't support >4K non-resident attribute list and $BITMAP * */ #ifndef INSIDE_GRLDR .text .code16 #endif #define AT_STANDARD_INFORMATION 0x10 #define AT_ATTRIBUTE_LIST 0x20 #define AT_FILENAME 0x30 #define AT_OBJECT_ID 0x40 #define AT_SECURITY_DESCRIPTOR 0x50 #define AT_VOLUME_NAME 0x60 #define AT_VOLUME_INFORMATION 0x70 #define AT_DATA 0x80 #define AT_INDEX_ROOT 0x90 #define AT_INDEX_ALLOCATION 0xA0 #define AT_BITMAP 0xB0 #define AT_SYMLINK 0xC0 #define AT_EA_INFORMATION 0xD0 #define AT_EA 0xE0 #define MAX_MFT_SIZE 1 // 1<<(1+9) = 1024 #define MAX_IDX_SIZE 3 // 1<<(3+9) = 4096 #define LOADSEG_NT 0x2000 #define MMFT_BASE 0x2000 #define MMFT_EMFT (MMFT_BASE +1024) #define MMFT_EBUF (MMFT_BASE + 2048) #define CMFT_BASE (MMFT_BASE + 6144) #define CMFT_EMFT (CMFT_BASE + 1024) #define CMFT_EBUF (CMFT_BASE + 2048) #define INDX_BASE (CMFT_BASE + 6144) #define SBUF_BASE (INDX_BASE + 4096) #define NTFS_Large_Structure_Error_Code 1 #define NTFS_Corrupt_Error_Code 2 #define NTFS_Run_Overflow_Error_Code 3 #define NTFS_No_Data_Error_Code 4 #define NTFS_Decompress_Error_Code 5 #define NT_FG_COMP 1 #define NT_FG_MMFT 2 #define NT_FG_ALST 4 #define NT_FG_GPOS 8 #define nt_boot_drive -2(%bp) #define nt_blocksize -4(%bp) #define nt_spc -5(%bp) #define nt_mft_size -6(%bp) #define nt_idx_size -7(%bp) #define nt_mft_start -12(%bp) #define nt_remain_len -16(%bp) //#define nt_file_count -18(%bp) #define nt_flag (%di) #define nt_attr_cur 2(%di) #define nt_attr_nxt 4(%di) #define nt_attr_end 6(%di) #define nt_curr_vcn 8(%di) #define nt_curr_lcn 0x10(%di) #define nt_attr_ofs 0x14(%di) #define nt_target_vcn 0x18(%di) #define nt_read_count 0x1C(%di) #define nt_vcn_offset 0x20(%di) #define nt_emft_buf 1024(%di) #define nt_edat_buf 2048(%di) .arch i586 Entry_nt: jmp 1f . = Entry_nt + 0x02 .byte 0x90 /* for CHS. Another possible value is 0x0e for LBA */ .ascii "NTFS " .word 0 /* 0B - Bytes per sector */ .byte 0 /* 0D - Sectors per cluster */ .word 0 /* 0E - reserved sectors, unused */ .byte 0 /* 10 - number of FATs, unused */ .word 0 /* 11 - Max dir entries for FAT12/FAT16, unused */ .word 0 /* 13 - total sectors for FAT12/FAT16, unused */ .byte 0xF8 /* 15 - Media descriptor */ .word 0 /* 16 - sectors per FAT for FAT12/FAT16, unused */ .word 255 /* 18 - Sectors per track */ .word 63 /* 1A - Number of heads */ nt_part_ofs: .long 0 /* 1C - hidden sectors */ .long 0 /* 20 - total sectors for FAT32, unused */ .long 0x800080 /* 24 - Usually 80 00 80 00, A value of 80 00 00 00 has * been seen on a USB thumb drive which is formatted * with NTFS under Windows XP. Note this is removable * media and is not partitioned, the drive as a whole * is NTFS formatted. */ .long 0,0 /* 28 - Number of sectors in the volume */ .long 0,0 /* 30 - LCN of VCN 0 of the $MFT */ .long 0,0 /* 38 - LCN of VCN 0 of the $MFTMirr */ .long 0 /* 40 - Clusters per MFT Record */ .long 4 /* 44 - Clusters per Index Record */ .long 0,0 /* 48 - Volume serial number */ .long 0 /* 50 - Checksum, usually 0 */ 1: . = Entry_nt + 0x54 cli cld . = Entry_nt + 0x56 /* the byte at offset 0x57 stores the real partition number for read. * the format program or the caller should set it to a correct value. * For floppies, it should be 0xff, which stands for whole drive. */ movb $0xff, %dh /* boot partition number */ xorw %ax, %ax movw %ax, %ds movw $0x7c00, %bp movw %ax, %es movw %ax, %ss /* stack and BP-relative moves up, too */ leaw -0x20(%bp), %sp sti movw %dx, nt_boot_drive /* Test if your BIOS support LBA mode */ movb $0x41, %ah movw $0x55AA, %bx int $0x13 jc 1f /* No EBIOS */ cmpw $0xAA55, %bx jne 1f /* No EBIOS */ testb $1, %cl jz 1f /* No EBIOS */ /* EBIOS supported */ movb $0x42, (ebios_nt - 1 - Entry_nt)(%bp) 1: cmpl $0x42555247, (nt_sector_mark - Entry_nt)(%bp) jz 1f // Must be called from GRLDR.MBR movw $0x7E00, %bx movl (nt_part_ofs - Entry_nt)(%bp), %eax incl %eax call readDisk_nt // Load the second sector from disk call readDisk_nt // Load the third sector from disk call readDisk_nt 1: xorl %eax, %eax movw 0xb(%bp), %ax // Bytes per sector (blocksize) movw %ax, nt_blocksize call convert_to_power_2 movb %cl, %bl movb 0xd(%bp), %al // Sectors per cluster call convert_to_power_2 movb %cl, %ch addb %bl, %ch subb $9, %ch // 1<